package httpserver import ( "net/http" "strings" "github.com/go-chi/chi/v5/middleware" "nexavpn/backend/internal/apiutil" "nexavpn/backend/internal/auth" "nexavpn/backend/internal/requestctx" ) func BaseMiddleware(next http.Handler) http.Handler { return middleware.RealIP(middleware.RequestID(middleware.Logger(next))) } func AuthMiddleware(jwtSecret string) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { header := r.Header.Get("Authorization") if !strings.HasPrefix(header, "Bearer ") { apiutil.Error(w, http.StatusUnauthorized, "unauthorized", "missing bearer token") return } claims, err := auth.ParseAccessToken(jwtSecret, strings.TrimPrefix(header, "Bearer ")) if err != nil { apiutil.Error(w, http.StatusUnauthorized, "unauthorized", "invalid access token") return } ctx := requestctx.WithClaims(r.Context(), claims) next.ServeHTTP(w, r.WithContext(ctx)) }) } } func AdminOnly(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { claims, ok := requestctx.ClaimsFromContext(r.Context()) if !ok || claims.Role != "admin" { apiutil.Error(w, http.StatusForbidden, "forbidden", "admin role required") return } next.ServeHTTP(w, r) }) }