package auth import ( "context" "net/http" "logjensticks/internal/db" ) const CookieName = "session_token" type contextKey string const sessionContextKey contextKey = "session" // Middleware validates the session cookie on every request. Attach this to // any route that requires authentication. func Middleware(dbc *db.Client) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { cookie, err := r.Cookie(CookieName) if err != nil { writeUnauthorized(w) return } session, err := ValidateSession(r.Context(), dbc, cookie.Value) if err != nil { writeUnauthorized(w) return } ctx := context.WithValue(r.Context(), sessionContextKey, session) next.ServeHTTP(w, r.WithContext(ctx)) }) } } // SessionFromContext retrieves the validated session attached by Middleware. // Returns nil if called outside an authenticated route. func SessionFromContext(ctx context.Context) *Session { s, _ := ctx.Value(sessionContextKey).(*Session) return s } func writeUnauthorized(w http.ResponseWriter) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(`{"success":false,"data":null,"error":{"code":"UNAUTHORIZED","message":"authentication required"}}`)) }