diff --git a/backend/main.py b/backend/main.py index 5c356b1e..dfc1817e 100644 --- a/backend/main.py +++ b/backend/main.py @@ -132,9 +132,15 @@ async def p_auth_middleware(request: Request, call_next): f"auth: rejecting {request.method} {request.url.path} " f"(origin={headers.get('origin', '-')}, no valid token)" ) + # This middleware sits OUTSIDE CORSMiddleware, so an early 401 skips its headers and a cross-origin caller (e.g. the vite dev server) sees an opaque "CORS blocked" instead of an honest 401. Echo the origin ONLY when it matches the CORS allow-list (same regex), so the 401 is legible without re-opening CORS to arbitrary origins. + import re as p_re + p_origin = headers.get("origin") + p_allowed = bool(p_origin) and bool(p_re.match(r"^(file://.*|http://localhost:\d+|http://127\.0\.0\.1:\d+|https://(api\.)?openswarm\.com)$", p_origin)) + p_cors = {"Access-Control-Allow-Origin": p_origin, "Access-Control-Allow-Credentials": "true"} if p_allowed else {} return JSONResponse( {"error": "unauthorized", "detail": "missing or invalid token"}, status_code=401, + headers=p_cors, ) response = await call_next(request)