package auth import ( "encoding/json" "net/http" "os" "strings" "time" authn "ds2api/internal/auth" ) func (h *Handler) requireAdmin(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if err := authn.VerifyAdminRequestWithStore(r, h.Store); err != nil { writeJSON(w, http.StatusUnauthorized, map[string]any{"detail": err.Error()}) return } next.ServeHTTP(w, r) }) } func (h *Handler) login(w http.ResponseWriter, r *http.Request) { var req map[string]any _ = json.NewDecoder(r.Body).Decode(&req) adminKey, _ := req["admin_key"].(string) expireHours := intFrom(req["expire_hours"]) if !authn.VerifyAdminCredential(adminKey, h.Store) { writeJSON(w, http.StatusUnauthorized, map[string]any{"detail": "Invalid admin key"}) return } token, err := authn.CreateJWTWithStore(expireHours, h.Store) if err != nil { writeJSON(w, http.StatusInternalServerError, map[string]any{"detail": err.Error()}) return } if expireHours <= 0 { expireHours = h.Store.AdminJWTExpireHours() } writeJSON(w, http.StatusOK, map[string]any{"success": true, "token": token, "expires_in": expireHours * 3600}) } func (h *Handler) verify(w http.ResponseWriter, r *http.Request) { header := strings.TrimSpace(r.Header.Get("Authorization")) if !strings.HasPrefix(strings.ToLower(header), "bearer ") { writeJSON(w, http.StatusUnauthorized, map[string]any{"detail": "No credentials provided"}) return } token := strings.TrimSpace(header[7:]) payload, err := authn.VerifyJWTWithStore(token, h.Store) if err != nil { writeJSON(w, http.StatusUnauthorized, map[string]any{"detail": err.Error()}) return } exp, _ := payload["exp"].(float64) remaining := int64(exp) - time.Now().Unix() if remaining < 0 { remaining = 0 } writeJSON(w, http.StatusOK, map[string]any{"valid": true, "expires_at": int64(exp), "remaining_seconds": remaining}) } func (h *Handler) getVercelConfig(w http.ResponseWriter, _ *http.Request) { saved := h.Store.Snapshot().Vercel token, tokenSource := firstConfiguredValue( [2]string{"env", os.Getenv("VERCEL_TOKEN")}, [2]string{"config", saved.Token}, ) projectID, _ := firstConfiguredValue( [2]string{"env", os.Getenv("VERCEL_PROJECT_ID")}, [2]string{"config", saved.ProjectID}, ) teamID, _ := firstConfiguredValue( [2]string{"env", os.Getenv("VERCEL_TEAM_ID")}, [2]string{"config", saved.TeamID}, ) writeJSON(w, http.StatusOK, map[string]any{ "has_token": token != "", "token_preview": maskSecretPreview(token), "token_source": nilIfEmpty(tokenSource), "project_id": projectID, "team_id": nilIfEmpty(teamID), }) } func firstConfiguredValue(values ...[2]string) (string, string) { for _, pair := range values { value := strings.TrimSpace(pair[1]) if value != "" { return value, strings.TrimSpace(pair[0]) } } return "", "" }