From e303c07f8d66a54370c4d0c1b5cdc15f6a8afe55 Mon Sep 17 00:00:00 2001 From: Stephen Adamson Date: Mon, 6 Jul 2026 19:22:00 +0100 Subject: [PATCH] refactor(backend): replace inline Bearer parsing with OptionalAuth middleware in services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes the inline Bearer token fallback in ServicesHandler — the OptionalAuth middleware (added to the public services route group in main.go) now handles auth context population. This eliminates duplicated token parsing logic and ensures consistent auth behavior across all routes. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- backend/handlers/services/services.go | 20 +------------------- backend/main.go | 1 + 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/backend/handlers/services/services.go b/backend/handlers/services/services.go index 010cda9..f46dc31 100644 --- a/backend/handlers/services/services.go +++ b/backend/handlers/services/services.go @@ -2,7 +2,6 @@ package services import ( "context" - "crussell/auth" "crussell/clock" "crussell/db" "github.com/jackc/pgx/v5" @@ -12,7 +11,6 @@ import ( "encoding/json" "errors" "net/http" - "strings" "time" "github.com/go-chi/chi/v5" @@ -258,26 +256,10 @@ func DeleteServiceHandler(w http.ResponseWriter, r *http.Request) { // ServicesHandler returns all services from the database // For non-admin logged-in users, filters based on age and patch test eligibility func ServicesHandler(w http.ResponseWriter, r *http.Request) { - // Check if user is authenticated - try context first, then optional token + // Check if user is authenticated — context is set by OptionalAuth middleware userID, hasUser := r.Context().Value(mw.UserIDKey).(string) role, _ := r.Context().Value(mw.UserRoleKey).(string) - // If no user in context, try to parse token from header - if !hasUser || userID == "" { - authHeader := r.Header.Get("Authorization") - if strings.HasPrefix(authHeader, "Bearer ") { - tokenString := strings.TrimPrefix(authHeader, "Bearer ") - var err error - userID, role, _, err = auth.VerifyToken(tokenString, r.Context()) - if err != nil { - // Invalid token - treat as unauthenticated - userID = "" - role = "" - } - hasUser = userID != "" - } - } - // If not logged in or admin, return all services (current behavior) if !hasUser || userID == "" || role == "admin" { query := ` diff --git a/backend/main.go b/backend/main.go index b5d1c2d..6cb6c7c 100644 --- a/backend/main.go +++ b/backend/main.go @@ -186,6 +186,7 @@ func main() { // Public read-only (but check auth context if present for eligibility) r.Group(func(r chi.Router) { r.Use(mw.RateLimit(120, time.Minute)) + r.Use(mw.OptionalAuth) r.Get("/services", services.ServicesHandler) r.Get("/services/eligible-for/{user_id}", services.ServicesEligibleForUserHandler) })