fix: make CORS origins environment-aware based on FRONTEND_URL (#240)

- production (FRONTEND_URL=https://plyr.fm) allows plyr.fm + www.plyr.fm
- staging (FRONTEND_URL=https://stg.plyr.fm) allows stg.plyr.fm
- both environments allow localhost and cloudflare preview deployments

this ensures staging frontend (stg.plyr.fm) talks to staging API,
and production frontend (plyr.fm) talks to production API.

authored by zzstoatzz.io and committed by GitHub 3c495da2 563ffecc

Changed files
+19 -2
src
backend
+19 -2
src/backend/config.py
··· 130 if self.cors_origin_regex is not None: 131 return self.cors_origin_regex 132 133 - # default: allow localhost for dev + plyr.fm + cloudflare pages (including preview deployments) 134 - return r"^(https://(www\.)?plyr\.fm|https://([a-z0-9]+\.)?relay-4i6\.pages\.dev|http://localhost:5173)$" 135 136 137 class DatabaseSettings(RelaySettingsSection):
··· 130 if self.cors_origin_regex is not None: 131 return self.cors_origin_regex 132 133 + # derive allowed origins based on FRONTEND_URL 134 + # production: FRONTEND_URL=https://plyr.fm → allow plyr.fm + www.plyr.fm 135 + # staging: FRONTEND_URL=https://stg.plyr.fm → allow stg.plyr.fm 136 + # always allow localhost for local dev and cloudflare preview deployments 137 + 138 + from urllib.parse import urlparse 139 + 140 + parsed = urlparse(self.url) 141 + hostname = parsed.hostname or "localhost" 142 + 143 + if hostname == "stg.plyr.fm": 144 + # staging: allow stg.plyr.fm 145 + return r"^(https://stg\.plyr\.fm|https://([a-z0-9]+\.)?relay-4i6\.pages\.dev|http://localhost:5173)$" 146 + elif hostname in ("plyr.fm", "www.plyr.fm"): 147 + # production: allow plyr.fm and www.plyr.fm 148 + return r"^(https://(www\.)?plyr\.fm|https://([a-z0-9]+\.)?relay-4i6\.pages\.dev|http://localhost:5173)$" 149 + else: 150 + # local dev: allow localhost 151 + return r"^(http://localhost:5173)$" 152 153 154 class DatabaseSettings(RelaySettingsSection):