package api import ( "encoding/json" "net/http" "geniusrun/backend/internal/garmin" ) type authResponse struct { Status string `json:"status"` // "authenticated" | "mfa_required" | "failed" Message string `json:"message"` } func authStatusString(s garmin.AuthStatus) string { switch s { case garmin.AuthSuccess: return "authenticated" case garmin.AuthMFARequired: return "mfa_required" case garmin.AuthFailed: return "failed" default: return "unknown" } } func (s *Server) recordAuthResult(userID int64, res garmin.AuthResult) { s.mu.Lock() s.userAuthStatus[userID] = res.Status s.userAuthMessage[userID] = res.Message s.mu.Unlock() } func (s *Server) handleAuthLogin(w http.ResponseWriter, r *http.Request) { userID := userIDFromContext(r.Context()) client, err := s.garminFor(r.Context(), userID) if err != nil { writeError(w, http.StatusInternalServerError, err.Error()) return } res, err := client.Authenticate(r.Context()) if err != nil { writeError(w, http.StatusBadGateway, err.Error()) return } s.recordAuthResult(userID, res) writeJSON(w, http.StatusOK, authResponse{Status: authStatusString(res.Status), Message: res.Message}) } func (s *Server) handleAuthMFA(w http.ResponseWriter, r *http.Request) { userID := userIDFromContext(r.Context()) var body struct { Code string `json:"code"` } if err := json.NewDecoder(r.Body).Decode(&body); err != nil { writeError(w, http.StatusBadRequest, "invalid request body") return } if body.Code == "" { writeError(w, http.StatusBadRequest, "code is required") return } client, err := s.garminFor(r.Context(), userID) if err != nil { writeError(w, http.StatusInternalServerError, err.Error()) return } res, err := client.CompleteMFA(r.Context(), body.Code) if err != nil { writeError(w, http.StatusBadGateway, err.Error()) return } s.recordAuthResult(userID, res) writeJSON(w, http.StatusOK, authResponse{Status: authStatusString(res.Status), Message: res.Message}) } func (s *Server) handleAuthStatus(w http.ResponseWriter, r *http.Request) { userID := userIDFromContext(r.Context()) s.mu.Lock() status, msg := s.userAuthStatus[userID], s.userAuthMessage[userID] s.mu.Unlock() writeJSON(w, http.StatusOK, authResponse{Status: authStatusString(status), Message: msg}) }