Strip trailing slashes from PUBLIC_URL, CORS_ORIGINS, FRONTEND_BASE_URL
A trailing slash on CORS_ORIGINS never matches a browser's Origin header (which never includes a path), silently breaking CORS with no error message beyond the browser's generic "No Access-Control-Allow-Origin header" — exactly what happened in production after switching domains. A trailing slash on PUBLIC_URL/FRONTEND_BASE_URL similarly produced double-slash URLs in API responses and reset-password links. All three are now normalized at config-load time so a .env typo can't cause this again. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
23a14a9710
commit
7384a6c05a
@ -1,4 +1,5 @@
|
||||
from __future__ import annotations
|
||||
from pydantic import field_validator
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
@ -45,9 +46,20 @@ class Settings(BaseSettings):
|
||||
admin_password: str = "change-me"
|
||||
admin_session_ttl_hours: int = 12
|
||||
|
||||
@field_validator("public_url", "frontend_base_url", mode="after")
|
||||
@classmethod
|
||||
def _strip_trailing_slash(cls, v: str) -> str:
|
||||
# Every call site concatenates a leading-slash path directly onto
|
||||
# these (e.g. f"{public_url}/mcp/sse") — a trailing slash in .env
|
||||
# would silently produce a double-slash URL.
|
||||
return v.rstrip("/")
|
||||
|
||||
@property
|
||||
def cors_origins_list(self) -> list[str]:
|
||||
return [o.strip() for o in self.cors_origins.split(",") if o.strip()]
|
||||
# A trailing slash here would never match a browser's Origin header
|
||||
# (which never includes a path/slash), silently breaking CORS —
|
||||
# strip it defensively so a .env typo can't cause that again.
|
||||
return [o.strip().rstrip("/") for o in self.cors_origins.split(",") if o.strip()]
|
||||
|
||||
|
||||
settings = Settings()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user