package auth import ( "github.com/gofiber/fiber/v2" ) // JWTMiddleware provides JWT authentication middleware type JWTMiddleware struct { authService *MockAuthService } // NewJWTMiddleware creates a new JWT middleware func NewJWTMiddleware(authService *MockAuthService) *JWTMiddleware { return &JWTMiddleware{ authService: authService, } } // Authenticate middleware validates JWT tokens func (m *JWTMiddleware) Authenticate() fiber.Handler { return func(c *fiber.Ctx) error { // Extract token from Authorization header tokenString, err := extractToken(c) if err != nil { return unauthorizedError(c, err.Error()) } // Validate token and set user context if err := validateAndSetContext(c, m.authService, tokenString); err != nil { return unauthorizedError(c, ErrInvalidToken, err.Error()) } return c.Next() } } // RequireRole middleware requires specific roles func (m *JWTMiddleware) RequireRole(requiredRole string) fiber.Handler { return func(c *fiber.Ctx) error { userRoles, ok := c.Locals(RolesKey).([]string) if !ok { return forbiddenError(c, ErrNoRolesFound) } // Check if user has required role using helper function if !hasRole(c, requiredRole) { return forbiddenError(c, ErrInsufficientPermissions, fiber.Map{ "required_role": requiredRole, "user_roles": userRoles, }) } return c.Next() } } // RequireAnyRole middleware requires any of the specified roles func (m *JWTMiddleware) RequireAnyRole(requiredRoles ...string) fiber.Handler { return func(c *fiber.Ctx) error { userRoles, ok := c.Locals(RolesKey).([]string) if !ok { return forbiddenError(c, ErrNoRolesFound) } // Check if user has any of the required roles using helper function if !HasAnyRole(c, requiredRoles...) { return forbiddenError(c, ErrInsufficientPermissions, fiber.Map{ "required_roles": requiredRoles, "user_roles": userRoles, }) } return c.Next() } } // Optional middleware validates token if present, but allows requests without tokens func (m *JWTMiddleware) Optional() fiber.Handler { return func(c *fiber.Ctx) error { // Extract token from Authorization header tokenString, err := extractToken(c) if err != nil { // No token or invalid format, continue without setting user context return c.Next() } // Try to validate token and set user context // If validation fails, continue without blocking the request validateAndSetContext(c, m.authService, tokenString) return c.Next() } }