From 1d463352a74e35535b7a986fede32f0677717b97 Mon Sep 17 00:00:00 2001 From: gilesb Date: Thu, 8 Jan 2026 17:26:42 +0000 Subject: [PATCH] Add configurable cookie domain for cross-subdomain auth sharing - Add COOKIE_DOMAIN env var (e.g., ".rose-ash.com") - Auto-derive from ARTDAG_DOMAIN if not set (strips first subdomain) - Set domain on auth cookies for sharing across L1/L2 subdomains - Add secure=True for cross-subdomain cookies Co-Authored-By: Claude Opus 4.5 --- server.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/server.py b/server.py index 5ba9bf1..0d4090f 100644 --- a/server.py +++ b/server.py @@ -39,6 +39,20 @@ DATA_DIR = Path(os.environ.get("ARTDAG_DATA", str(Path.home() / ".artdag" / "l2" L1_PUBLIC_URL = os.environ.get("L1_PUBLIC_URL", "https://celery-artdag.rose-ash.com") EFFECTS_REPO_URL = os.environ.get("EFFECTS_REPO_URL", "https://git.rose-ash.com/art-dag/effects") +# Cookie domain for sharing auth across subdomains (e.g., ".rose-ash.com") +# If not set, derives from DOMAIN (strips first subdomain, adds leading dot) +def _get_cookie_domain(): + env_val = os.environ.get("COOKIE_DOMAIN") + if env_val: + return env_val + # Derive from DOMAIN: artdag.rose-ash.com -> .rose-ash.com + parts = DOMAIN.split(".") + if len(parts) >= 2: + return "." + ".".join(parts[-2:]) + return None + +COOKIE_DOMAIN = _get_cookie_domain() + # Ensure data directory exists DATA_DIR.mkdir(parents=True, exist_ok=True) (DATA_DIR / "assets").mkdir(exist_ok=True) @@ -340,7 +354,9 @@ async def ui_login_submit(request: Request): value=token.access_token, httponly=True, max_age=60 * 60 * 24 * 30, # 30 days - samesite="lax" + samesite="lax", + domain=COOKIE_DOMAIN, # Share across subdomains + secure=True # Required for cross-subdomain cookies ) return response @@ -424,7 +440,9 @@ async def ui_register_submit(request: Request): value=token.access_token, httponly=True, max_age=60 * 60 * 24 * 30, # 30 days - samesite="lax" + samesite="lax", + domain=COOKIE_DOMAIN, # Share across subdomains + secure=True # Required for cross-subdomain cookies ) return response @@ -433,7 +451,7 @@ async def ui_register_submit(request: Request): async def logout(): """Handle logout - clear cookie and redirect to home.""" response = RedirectResponse(url="/", status_code=302) - response.delete_cookie("auth_token") + response.delete_cookie("auth_token", domain=COOKIE_DOMAIN) return response