diff --git a/internal/router/device.go b/internal/router/device.go new file mode 100644 index 0000000..46e5ad8 --- /dev/null +++ b/internal/router/device.go @@ -0,0 +1,42 @@ +package router + +import ( + "github.com/golang-jwt/jwt/v5" + "github.com/labstack/echo-jwt/v4" + "github.com/labstack/echo/v4" +) + +func registerDeviceRoutes(cfg *Config) { + e := cfg.Echo + + // JWT middleware + jwtMiddleware := echojwt.WithConfig(echojwt.Config{ + SigningKey: []byte(cfg.Cfg.JWTSecret), + ContextKey: "user", + SuccessHandler: func(c echo.Context) { + token := c.Get("user").(*jwt.Token) + claims := token.Claims.(jwt.MapClaims) + c.Set("user_id", claims["user_id"]) + c.Set("user_role", claims["user_role"]) + c.Set("user_email", claims["user_email"]) + c.Set("user_username", claims["user_username"]) + }, + }) + + // Protected routes + protected := e.Group("/api", jwtMiddleware) + + // Public device registration routes (no auth required) + e.POST("/api/devices/register", cfg.DeviceHandler.InitiateRegistration) + e.POST("/api/devices/register/status", cfg.DeviceHandler.CheckRegistrationStatus) + e.GET("/api/devices/approve/:token", cfg.DeviceHandler.ApproveDevice) + e.POST("/api/devices/reject/:token", cfg.DeviceHandler.RejectDevice) + + // Device management routes (protected) + devices := protected.Group("/devices") + devices.GET("", cfg.DeviceHandler.ListDevices) + devices.GET("/:id", cfg.DeviceHandler.GetDevice) + devices.PUT("/:id", cfg.DeviceHandler.UpdateDevice) + devices.DELETE("/:id", cfg.DeviceHandler.DeleteDevice) + devices.GET("/pending", cfg.DeviceHandler.ListPendingRegistrations) +} diff --git a/internal/router/library.go b/internal/router/library.go new file mode 100644 index 0000000..b0fe1cd --- /dev/null +++ b/internal/router/library.go @@ -0,0 +1,70 @@ +package router + +import ( + "bookhoard/internal/handlers" + + "github.com/golang-jwt/jwt/v5" + "github.com/labstack/echo-jwt/v4" + "github.com/labstack/echo/v4" +) + +func registerLibraryRoutes(cfg *Config) { + e := cfg.Echo + + // JWT middleware for protected routes + jwtMiddleware := echojwt.WithConfig(echojwt.Config{ + SigningKey: []byte(cfg.Cfg.JWTSecret), + ContextKey: "user", + SuccessHandler: func(c echo.Context) { + token := c.Get("user").(*jwt.Token) + claims := token.Claims.(jwt.MapClaims) + c.Set("user_id", claims["user_id"]) + c.Set("user_role", claims["user_role"]) + c.Set("user_email", claims["user_email"]) + c.Set("user_username", claims["user_username"]) + }, + }) + + // Protected routes group + protected := e.Group("/api", jwtMiddleware) + + // Setup ebook handler routes + h := handlers.SetupRoutes(protected, cfg.Queries, cfg.ConnManager) + + // Public library types endpoint + e.GET("/api/libraries/types", cfg.LibraryHandler.GetLibraryTypes) + + // Library management routes + library := protected.Group("/libraries") + + // Admin-only library routes + adminLibrary := library.Group("", handlers.AdminMiddleware) + adminLibrary.POST("", cfg.LibraryHandler.CreateLibrary) + adminLibrary.GET("", cfg.LibraryHandler.ListLibraries) + adminLibrary.GET("/:id", cfg.LibraryHandler.GetLibrary) + adminLibrary.PUT("/:id", cfg.LibraryHandler.UpdateLibrary) + adminLibrary.DELETE("/:id", cfg.LibraryHandler.DeleteLibrary) + adminLibrary.POST("/:id/folders", cfg.LibraryHandler.AddLibraryFolder) + adminLibrary.GET("/:id/folders", cfg.LibraryHandler.GetLibraryFolders) + adminLibrary.DELETE("/:id/folders", cfg.LibraryHandler.DeleteLibraryFolder) + adminLibrary.GET("/:id/stats", cfg.LibraryHandler.GetLibraryStats) + adminLibrary.POST("/:id/scan", func(c echo.Context) error { + libraryID := c.Param("id") + scanReq := map[string]interface{}{ + "library_id": libraryID, + } + c.Set("scan_request", scanReq) + return h.ScanEbooks(c) + }) + adminLibrary.GET("/:id/media-items", func(c echo.Context) error { + libraryID := c.Param("id") + c.QueryParams().Set("library_id", libraryID) + return h.ListMediaItems(c) + }) + + // User library visibility control + userLibrary := library.Group("/visibility") + userLibrary.GET("", cfg.LibraryHandler.GetUserVisibleLibraries) + userLibrary.POST("", cfg.LibraryHandler.SetLibraryVisibility) + // Note: Remove endpoint may not exist - check handlers +} diff --git a/internal/router/router.go b/internal/router/router.go index 5534d52..a48eb68 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -88,13 +88,6 @@ func RegisterRoutes(cfg *Config) { } // Stub functions - will be implemented incrementally -func registerLibraryRoutes(cfg *Config) { - // TODO: Implement in library.go -} - -func registerDeviceRoutes(cfg *Config) { - // TODO: Implement in device.go -} func registerSyncRoutes(cfg *Config) { // TODO: Implement in sync.go