//go:build ignore // +build ignore // TODO: Réactiver two_factor_handlers après stabilisation du noyau et alignement des services (AuthService.GetUserByID) package handlers import ( "net/http" "github.com/gin-gonic/gin" "go.uber.org/zap" "veza-backend-api/internal/services" ) // TwoFactorHandlers handles 2FA-related API endpoints type TwoFactorHandlers struct { twoFactorService *services.TwoFactorService authService *services.AuthService logger *zap.Logger } // NewTwoFactorHandlers creates new 2FA handlers func NewTwoFactorHandlers(twoFactorService *services.TwoFactorService, authService *services.AuthService, logger *zap.Logger) *TwoFactorHandlers { return &TwoFactorHandlers{ twoFactorService: twoFactorService, authService: authService, logger: logger, } } // InitTwoFactorHandlers initializes 2FA handlers func InitTwoFactorHandlers(twoFactorService *services.TwoFactorService, authService *services.AuthService, logger *zap.Logger) { handlers := NewTwoFactorHandlers(twoFactorService, authService, logger) // Store handlers globally for route registration TwoFactorHandlersInstance = handlers } // TwoFactorHandlersInstance holds the global 2FA handlers instance var TwoFactorHandlersInstance *TwoFactorHandlers // SetupTwoFactor initiates 2FA setup for a user func (h *TwoFactorHandlers) SetupTwoFactor(c *gin.Context) { userID := c.GetInt64("user_id") // Get user information user, err := h.authService.GetUserByID(c.Request.Context(), userID) if err != nil { h.logger.Error("Failed to get user", zap.Error(err)) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get user information"}) return } // Check if 2FA is already enabled enabled, err := h.twoFactorService.GetTwoFactorStatus(c.Request.Context(), userID) if err != nil { h.logger.Error("Failed to get 2FA status", zap.Error(err)) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get 2FA status"}) return } if enabled { c.JSON(http.StatusBadRequest, gin.H{"error": "2FA is already enabled"}) return } // Generate 2FA setup setup, err := h.twoFactorService.GenerateSecret(user) if err != nil { h.logger.Error("Failed to generate 2FA setup", zap.Error(err)) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate 2FA setup"}) return } c.JSON(http.StatusOK, gin.H{ "success": true, "setup": setup, }) } // EnableTwoFactor enables 2FA for a user func (h *TwoFactorHandlers) EnableTwoFactor(c *gin.Context) { userID := c.GetInt64("user_id") var req struct { Secret string `json:"secret" binding:"required"` Code string `json:"code" binding:"required"` RecoveryCodes []string `json:"recovery_codes" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // Verify the code first valid, err := h.twoFactorService.VerifyTwoFactor(c.Request.Context(), userID, req.Code) if err != nil { h.logger.Error("Failed to verify 2FA code", zap.Error(err)) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to verify 2FA code"}) return } if !valid { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 2FA code"}) return } // Enable 2FA err = h.twoFactorService.EnableTwoFactor(c.Request.Context(), userID, req.Secret, req.RecoveryCodes) if err != nil { h.logger.Error("Failed to enable 2FA", zap.Error(err)) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to enable 2FA"}) return } c.JSON(http.StatusOK, gin.H{ "success": true, "message": "2FA enabled successfully", }) } // DisableTwoFactor disables 2FA for a user func (h *TwoFactorHandlers) DisableTwoFactor(c *gin.Context) { userID := c.GetInt64("user_id") var req struct { Code string `json:"code" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // Verify the code first valid, err := h.twoFactorService.VerifyTwoFactor(c.Request.Context(), userID, req.Code) if err != nil { h.logger.Error("Failed to verify 2FA code", zap.Error(err)) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to verify 2FA code"}) return } if !valid { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 2FA code"}) return } // Disable 2FA err = h.twoFactorService.DisableTwoFactor(c.Request.Context(), userID) if err != nil { h.logger.Error("Failed to disable 2FA", zap.Error(err)) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to disable 2FA"}) return } c.JSON(http.StatusOK, gin.H{ "success": true, "message": "2FA disabled successfully", }) } // VerifyTwoFactor verifies a 2FA code func (h *TwoFactorHandlers) VerifyTwoFactor(c *gin.Context) { userID := c.GetInt64("user_id") var req services.TwoFactorVerification if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // Verify the code valid, err := h.twoFactorService.VerifyTwoFactor(c.Request.Context(), userID, req.Code) if err != nil { h.logger.Error("Failed to verify 2FA code", zap.Error(err)) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to verify 2FA code"}) return } if !valid { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 2FA code"}) return } c.JSON(http.StatusOK, gin.H{ "success": true, "message": "2FA code verified successfully", }) } // GetTwoFactorStatus gets the 2FA status for a user func (h *TwoFactorHandlers) GetTwoFactorStatus(c *gin.Context) { userID := c.GetInt64("user_id") enabled, err := h.twoFactorService.GetTwoFactorStatus(c.Request.Context(), userID) if err != nil { h.logger.Error("Failed to get 2FA status", zap.Error(err)) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get 2FA status"}) return } c.JSON(http.StatusOK, gin.H{ "success": true, "enabled": enabled, }) }