package interfaces import ( "mengstack/internal/app/middleware" "mengstack/internal/config" "mengstack/internal/kernel/tenant" "mengstack/internal/modules/auth/application" "mengstack/internal/modules/auth/infrastructure" "github.com/gin-gonic/gin" "go.uber.org/fx" ) type AuthMiddleware struct { fx.In Service *application.Service } func NewAuthMiddleware(in AuthMiddleware) gin.HandlerFunc { return func(c *gin.Context) { authHeader := c.GetHeader("Authorization") if authHeader == "" { c.AbortWithStatusJSON(401, gin.H{"code": -1, "message": "missing authorization"}) return } token := authHeader if len(authHeader) > 7 && authHeader[:7] == "Bearer " { token = authHeader[7:] } claims, err := application.ParseToken(token, in.Service.JWTSecret()) if err != nil { c.AbortWithStatusJSON(401, gin.H{"code": -1, "message": "invalid token"}) return } c.Set("user_id", claims.UserID) c.Set("tenant_id", claims.TenantID) c.Next() } } func SetupRoutes(r *gin.Engine, h *Handler, authMW gin.HandlerFunc, tenantResolver tenant.Resolver) { auth := r.Group("/api/v1/auth") auth.Use(middleware.OptionalTenant(tenantResolver)) { auth.POST("/register", h.Register) auth.POST("/login", h.Login) auth.POST("/refresh", h.RefreshToken) } protected := r.Group("/api/v1") protected.Use(authMW, middleware.MultiTenant(tenantResolver)) { protected.GET("/ping", h.Ping) protected.GET("/profile", h.GetProfile) protected.POST("/password", h.ChangePassword) protected.GET("/users", h.ListUsers) protected.POST("/users", h.CreateUser) protected.GET("/users/:id", h.GetUser) protected.PUT("/users/:id", h.UpdateUser) protected.DELETE("/users/:id", h.DeleteUser) } } func NewJWTConfig(cfg *config.Config) application.JWTConfig { return application.JWTConfig{ Secret: cfg.JWT.Secret, AccessExpiryMinutes: cfg.JWT.AccessExpiryMinutes, RefreshExpiryDays: cfg.JWT.RefreshExpiryDays, Issuer: cfg.JWT.Issuer, } } var Module = fx.Module("auth", fx.Provide( NewJWTConfig, infrastructure.NewUserRepository, application.NewService, NewHandler, NewAuthMiddleware, ), )