package app import ( "fmt" "net/http" "strings" "git.linuxforward.com/byom/byom-core/handlers" "git.linuxforward.com/byom/byom-core/jwtutils" "github.com/gin-gonic/gin" ) func addRoutes( rtr *gin.Engine, jwtSvc *jwtutils.Service, userHandler *handlers.UserHandler, workspaceHandler *handlers.WorkspaceHandler, profileHandler *handlers.ProfileHandler, ) { //group routes behind /api/v1/core coreRtr := rtr.Group("/api/v1/core") // Health check coreRtr.GET("/health", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"status": "ok"}) }) // Auth routes authRoutes := coreRtr.Group("/auth") authRoutes.POST("/login", userHandler.Login) // Workspace onboarding routes workspaceOnboarding := coreRtr.Group("/workspaces") workspaceOnboarding.POST("/owners/init", userHandler.InitOwner) workspaceOnboarding.PUT("/owners", userHandler.CreateOwner) // Invitation management (public) invitationRoutes := coreRtr.Group("/invitations") invitationRoutes.POST("/accept", userHandler.AcceptInvitation) invitationRoutes.GET("/validate", userHandler.ValidateInvitation) // Authenticated routes auth := coreRtr.Group("/") auth.Use(authMiddleware(jwtSvc)) // Workspace management workspaces := auth.Group("/workspaces") workspaces.POST("", workspaceHandler.Create) workspaces.POST("/:id/members", userHandler.AddMember) workspaces.GET("/:id/profiles", profileHandler.ListByWorkspace) // Profile management profiles := auth.Group("/profiles") profiles.GET("", profileHandler.List) profiles.POST("", profileHandler.Create) profiles.GET("/:id", profileHandler.Get) profiles.PUT("/:id", profileHandler.Update) profiles.DELETE("/:id", profileHandler.Delete) // User management users := auth.Group("/users") users.GET("/current", userHandler.GetCurrent) users.PUT("/current", userHandler.UpdateCurrent) // Invitation management (authenticated) authInvitations := auth.Group("/invitations") authInvitations.POST("", userHandler.CreateInvitation) } func authMiddleware(jwtSvc *jwtutils.Service) gin.HandlerFunc { return func(c *gin.Context) { authHeader := c.GetHeader("Authorization") if authHeader == "" { fmt.Println("No auth header") c.AbortWithStatus(http.StatusUnauthorized) return } // Get token part, using SplitAfter to preserve the delimiter token := strings.TrimPrefix(authHeader, "Bearer ") token = strings.TrimSpace(token) // Validate token without any cleaning since we now know it's clean claims, err := jwtSvc.ValidateToken(token) if err != nil { fmt.Println(err) c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) return } // Store claims in the context using the exported key from jwtutils c.Set("claims", claims) c.Next() } }