From 3cf64376178c66eb9625fb1b338c4f7165d97919 Mon Sep 17 00:00:00 2001 From: Erik Date: Fri, 15 May 2026 20:17:22 +0200 Subject: [PATCH] fix(auth): populate request.state.user inside loopback-bypass branch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- main.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/main.py b/main.py index 782ca955..ab896428 100644 --- a/main.py +++ b/main.py @@ -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