Files
Erupe/server/api/middleware.go
Houmgaor 7ff26f4980 feat(api): add v2 routes, auth middleware, structured errors, and server status endpoint
Introduces incremental API improvements for custom launcher support
(mhf-iel, stratic-dev's Rust launcher):

- Standardize all error responses to JSON envelopes with error/message
- Add Bearer token auth middleware for v2 routes (legacy body-token preserved)
- Add `returning` (>90d inactive) and `courses` fields to auth response
- Add /v2/ route prefix with HTTP method enforcement
- Add GET /v2/server/status for MezFes, featured weapon, and event status
- Add APIEventRepo for read-only event data access

Closes #44
2026-02-27 12:46:23 +01:00

39 lines
1.2 KiB
Go

package api
import (
"context"
"net/http"
"strings"
)
type contextKey string
const userIDKey contextKey = "userID"
// UserIDFromContext extracts the authenticated user ID from the request context.
// Returns the user ID and true if present, or 0 and false otherwise.
func UserIDFromContext(ctx context.Context) (uint32, bool) {
uid, ok := ctx.Value(userIDKey).(uint32)
return uid, ok
}
// AuthMiddleware extracts a Bearer token from the Authorization header,
// validates it, and injects the user ID into the request context.
func (s *APIServer) AuthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
auth := r.Header.Get("Authorization")
if auth == "" || !strings.HasPrefix(auth, "Bearer ") {
writeError(w, http.StatusUnauthorized, "unauthorized", "Invalid or expired token")
return
}
token := strings.TrimPrefix(auth, "Bearer ")
userID, err := s.userIDFromToken(r.Context(), token)
if err != nil {
writeError(w, http.StatusUnauthorized, "unauthorized", "Invalid or expired token")
return
}
ctx := context.WithValue(r.Context(), userIDKey, userID)
next.ServeHTTP(w, r.WithContext(ctx))
})
}