package api import ( "net/http" "github.com/alchemistkay/guestguard/internal/domain" "github.com/alchemistkay/guestguard/internal/storage" ) type meHandler struct { users *storage.UserRepo } // GET /me — returns the authenticated user. Used by the frontend to bootstrap // after a page reload (with a fresh access token from /auth/refresh). func (h *meHandler) get(w http.ResponseWriter, r *http.Request) { uid, ok := UserIDFromContext(r.Context()) if !ok { writeError(w, http.StatusUnauthorized, "unauthenticated") return } u, err := h.users.GetByID(r.Context(), uid) if err != nil { if err == domain.ErrUserNotFound { writeError(w, http.StatusUnauthorized, "user not found") return } writeError(w, http.StatusInternalServerError, "failed to load user") return } writeJSON(w, http.StatusOK, u) } // GET /me/public-ip — returns the IP the API sees the caller from. // Powers the Gate tab's "Use my current network" button so a host can // allowlist their own home / office Wi-Fi with one click rather than // learning what a CIDR is. Tier 2 Block G UX rebrand. // // In production behind an ingress proxy the real public IP arrives via // X-Forwarded-For (handled by clientIP); in dev with Docker Desktop the // caller's apparent IP is the bridge gateway (~192.168.65.1), which is // still the right value to allowlist for local hosts. func (h *meHandler) publicIP(w http.ResponseWriter, r *http.Request) { if _, ok := UserIDFromContext(r.Context()); !ok { writeError(w, http.StatusUnauthorized, "unauthenticated") return } writeJSON(w, http.StatusOK, map[string]string{"ip": clientIP(r)}) }