fix(auth): populate request.state.user inside loopback-bypass branch

The Docker-bridge / loopback bypass in AuthMiddleware was short-circuiting
the whole auth flow without ever decoding the session cookie. Result: /me
and other endpoints reading request.state.user got 401 for real logged-in
browsers (because nginx → docker-proxy makes them look like 172.x).

Symptom: dashboard admin UI invisible even for admin users — useCurrentUser
saw 401 from /me and treated everyone as anonymous.

Fix: in the bypass branch, still try to decode any session cookie present
and populate request.state.user. The bypass still permits anonymous
internal calls (overlord-agent's MCP tools), but real authenticated browsers
now get their user correctly resolved.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-15 20:17:22 +02:00
parent 1c1c43d28b
commit 3cf6437617

12
main.py
View file

@ -1051,8 +1051,20 @@ class AuthMiddleware(BaseHTTPMiddleware):
# only the host or other compose-network containers can reach it.
# This lets host-side helpers (overlord-agent, discord-rare-monitor,
# etc.) call any endpoint without forging a session cookie.
#
# IMPORTANT: We still try to decode the session cookie if present, so
# that endpoints like /me which check `request.state.user` work for
# real authenticated browsers proxied through nginx → docker-proxy
# (which makes them look like they're coming from 172.x). Without
# this, /me returned 401 even for logged-in users, silently
# disabling the admin-only UI on the dashboard.
client_host = request.client.host if request.client else ""
if client_host.startswith("172.") or client_host in ("127.0.0.1", "::1", "localhost"):
token = request.cookies.get("session")
if token:
user = verify_session_cookie(token)
if user:
request.state.user = user
return await call_next(request)
# Check session cookie