package middleware import ( "net/http" "strings" "clintonambulance.com/calculate_negative_points/internal/config" ) type contextKey string const userContextKey = contextKey("user") func audMatch(aud interface{}, expected string) bool { switch v := aud.(type) { case string: return v == expected case []interface{}: for _, val := range v { if s, ok := val.(string); ok && s == expected { return true } } } return false } func JWTMiddleware(config *config.ApplicationConfig) (func(http.Handler) http.Handler, error) { middleware := func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost && r.Method != http.MethodPut && r.Method != http.MethodDelete { // Skip auth for safe methods like GET/HEAD next.ServeHTTP(w, r) return } authHeader := r.Header.Get("Authorization") // Check if the header exists and starts with "Bearer " if authHeader == "" || !strings.HasPrefix(authHeader, "Bearer ") { http.Error(w, "Unauthorized: Bearer token missing or invalid", http.StatusUnauthorized) return } // Extract the token by removing the "Bearer " prefix //tokenStr := strings.TrimPrefix(authHeader, "Bearer ") //token, err := jwt.Parse(tokenStr, config.Jwt.KeySet.Keyfunc) //if err != nil || !token.Valid { // http.Error(w, "Invalid or expired token", http.StatusUnauthorized) // return //} //claims, ok := token.Claims.(jwt.MapClaims) //if !ok { // http.Error(w, "Invalid token claims", http.StatusUnauthorized) // return //} // Check `iss` and `aud` // if claims["iss"] != config.Jwt.Issuer { // http.Error(w, "Invalid issuer", http.StatusUnauthorized) // return // } // audClaim := claims["aud"] // if !audMatch(audClaim, config.Jwt.Audience) { // http.Error(w, "Invalid audience", http.StatusUnauthorized) // return // } //ctx := context.WithValue(r.Context(), userContextKey, claims) next.ServeHTTP(w, r.WithContext(r.Context())) }) } return middleware, nil }