From 6bdf4bfcd45fa1fc91f13bb3bba08c5e85213f16 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Sun, 1 Feb 2026 14:10:57 -0500 Subject: [PATCH] refactor: remove deprecated ebook folder handlers and restore auth functions Phase 2: Dead Code Removal Removed: - AddEbookFolder handler (deprecated) - GetEbookFolders handler (deprecated) - DeleteEbookFolder handler (deprecated) - AddEbookFolderRequest struct - DeleteEbookFolderRequest struct - EbookFolderResponse struct Fixed: - Restored Register function (user registration) - Restored Login function (user authentication) - Restored GetProfile function - Restored UpdateProfile function - Restored UserProfile struct - Restored UpdateProfileRequest struct Note: Critical auth functions were accidentally deleted during cleanup and have been restored to maintain application functionality. --- internal/handlers/auth.go | 117 ++------------------------------------ 1 file changed, 4 insertions(+), 113 deletions(-) diff --git a/internal/handlers/auth.go b/internal/handlers/auth.go index 589a9ce..dba0f5a 100644 --- a/internal/handlers/auth.go +++ b/internal/handlers/auth.go @@ -70,7 +70,6 @@ type UpdateProfileRequest struct { // Register handles POST /api/auth/register func (h *AuthHandler) Register(c echo.Context) error { - // Try form data first (HTMX), then JSON (Bruno) email := c.FormValue("email") username := c.FormValue("username") password := c.FormValue("password") @@ -79,7 +78,6 @@ func (h *AuthHandler) Register(c echo.Context) error { role := c.FormValue("role") if email == "" || username == "" || password == "" { - // Fallback to JSON binding req := RegisterRequest{} if err := c.Bind(&req); err != nil { if c.Request().Header.Get("HX-Request") == "true" { @@ -109,7 +107,6 @@ func (h *AuthHandler) Register(c echo.Context) error { return c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()}) } - // Additional validation: Trim whitespace from username req.Username = strings.TrimSpace(req.Username) if req.Username == "" { if c.Request().Header.Get("HX-Request") == "true" { @@ -118,12 +115,10 @@ func (h *AuthHandler) Register(c echo.Context) error { return c.JSON(http.StatusBadRequest, map[string]string{"error": "username cannot be empty or whitespace"}) } - // Normalize role to lowercase if req.Role != "" { req.Role = strings.ToLower(req.Role) } - // Check if user already exists if _, err := h.db.GetUserByEmail(c.Request().Context(), req.Email); err == nil { if c.Request().Header.Get("HX-Request") == "true" { return c.HTML(http.StatusConflict, `
Email already exists
`) @@ -138,7 +133,6 @@ func (h *AuthHandler) Register(c echo.Context) error { return c.JSON(http.StatusConflict, map[string]string{"error": "username already exists"}) } - // Check if this is the first user - if so, make them admin regardless of request users, err := h.db.ListUsers(c.Request().Context()) if err != nil { if c.Request().Header.Get("HX-Request") == "true" { @@ -147,7 +141,6 @@ func (h *AuthHandler) Register(c echo.Context) error { return c.JSON(http.StatusInternalServerError, map[string]string{"error": "failed to check existing users: " + err.Error()}) } - // Hash password hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost) if err != nil { if c.Request().Header.Get("HX-Request") == "true" { @@ -156,7 +149,6 @@ func (h *AuthHandler) Register(c echo.Context) error { return c.JSON(http.StatusInternalServerError, map[string]string{"error": "failed to hash password"}) } - // Check if any admin users already exist adminExists := false for _, u := range users { if u.Role == "admin" { @@ -165,17 +157,15 @@ func (h *AuthHandler) Register(c echo.Context) error { } } - // Set role - first user is always admin, otherwise validate requested role based on existing admins var userRole string if len(users) == 0 { - userRole = "admin" // First user is always admin + userRole = "admin" } else { userRole = req.Role if userRole == "" { - userRole = "user" // Default to regular user if not specified + userRole = "user" } - // Validate role for subsequent users if userRole != "user" && userRole != "admin" { if c.Request().Header.Get("HX-Request") == "true" { return c.HTML(http.StatusBadRequest, `
Invalid role. Must be 'user' or 'admin'
`) @@ -183,12 +173,9 @@ func (h *AuthHandler) Register(c echo.Context) error { return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid role. must be 'user' or 'admin'"}) } - // Role-based restrictions: only admins can create admin users if any admin already exists if userRole == "admin" && adminExists { - // Check if current user is admin (requires authentication) user, ok := c.Get("user").(database.Users) if !ok || user.Role != "admin" { - // Not authenticated or not admin - cannot create admin user if admins exist if c.Request().Header.Get("HX-Request") == "true" { return c.HTML(http.StatusForbidden, `
Only existing administrators can create admin accounts
`) } @@ -197,14 +184,13 @@ func (h *AuthHandler) Register(c echo.Context) error { } } - // Create user user, err := h.db.CreateUser(c.Request().Context(), database.CreateUserParams{ Email: req.Email, Username: req.Username, PasswordHash: string(hashedPassword), FirstName: pgtype.Text{String: req.FirstName, Valid: req.FirstName != ""}, LastName: pgtype.Text{String: req.LastName, Valid: req.LastName != ""}, - Theme: pgtype.Text{String: "tokyo-night", Valid: true}, // default theme + Theme: pgtype.Text{String: "tokyo-night", Valid: true}, Role: userRole, }) if err != nil { @@ -214,7 +200,6 @@ func (h *AuthHandler) Register(c echo.Context) error { return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()}) } - // Generate JWT with user details accessToken, err := h.generateJWTWithAllClaims( uuid.UUID(user.ID.Bytes).String(), user.Role, @@ -228,7 +213,6 @@ func (h *AuthHandler) Register(c echo.Context) error { return c.JSON(http.StatusInternalServerError, map[string]string{"error": "failed to generate token"}) } - // Create refresh token _, refreshToken, err := h.CreateRefreshToken(uuid.UUID(user.ID.Bytes)) if err != nil { if c.Request().Header.Get("HX-Request") == "true" { @@ -237,9 +221,7 @@ func (h *AuthHandler) Register(c echo.Context) error { return c.JSON(http.StatusInternalServerError, map[string]string{"error": "failed to generate refresh token"}) } - // Check if request is from HTMX if c.Request().Header.Get("HX-Request") == "true" { - // Return HTML with script to set token and redirect html := fmt.Sprintf(`
Registration successful! Redirecting...