Skip to content

Commit 3cbffc6

Browse files
ZukaiSagansmagen10
andauthored
Fix/p1 cors backend allowed origins MERGE AFTER PR #109 (#110)
* fix(fullstack): consent gating, Beanie 2 Mongo init, Framingham module, auth routes - Backend: user consent fields; POST/GET /api/v1/consent; health consent guard on risk assessment; init_beanie via PyMongo connection_string (Beanie 2); drop Motor dependency; CORS origins include Vite fallback port 5174 - Frontend: ConsentPage, consent service, RequireAuth + RequireHealthConsent, auth context consent sync, guarded dashboard/questionnaire/modules, Login/Signup post-auth routing, Framingham UI without demo fallback - i18n: framingham namespace and nav strings across locales - Tests: test-utils consent defaults; Dashboard tests aligned Made-with: Cursor * fix(frontend): Framingham risk must use backend API with validated responses Route assessment through healthRiskService (POST /health/risk-assessment only). Parse and validate HealthRiskOutput before rendering; invalid payloads show a clear error plus toast. Surface server/network failures via toasts without fabricating results. Add unit and integration tests; extend i18n for invalid response copy. Made-with: Cursor * fix(backend): align CORS allowed origins with Vite and local dev Default ALLOWED_ORIGINS to include localhost/127.0.0.1 on ports 5173, 5174 (Vite) and 3000 (common Docker UI mapping). Update backend/.env.example and README so local .env stays consistent and browsers stop blocking cross-origin API calls from the standard frontend URLs. Made-with: Cursor --------- Co-authored-by: smagen10 <maayizsameer@gmail.com>
1 parent e448bc0 commit 3cbffc6

3 files changed

Lines changed: 25 additions & 7 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ npm run dev
177177
| `JWT_REFRESH_SECRET` | Refresh token secret | `dev-refresh-secret-...` |
178178
| `ACCESS_TOKEN_EXPIRE_MINUTES` | Access token TTL | `15` |
179179
| `REFRESH_TOKEN_EXPIRE_DAYS` | Refresh token TTL | `7` |
180-
| `ALLOWED_ORIGINS` | CORS allowed origins | `http://localhost:5173` |
180+
| `ALLOWED_ORIGINS` | CORS allowed origins (comma-separated); see `backend/.env.example` | Vite `:5173`/`:5174`, `127.0.0.1`, Docker UI `:3000` |
181181

182182
#### Frontend (`frontend/.env`)
183183

backend/.env.example

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ REFRESH_TOKEN_EXPIRE_DAYS=7
2424
# ─────────────────────────────────────────────────────────────────────────────
2525
# CORS Configuration
2626
# ─────────────────────────────────────────────────────────────────────────────
27-
# Comma-separated origins allowed to call the API (e.g., frontend dev server)
28-
# Include 5174 if Vite picks a fallback port when 5173 is busy
29-
ALLOWED_ORIGINS=http://localhost:5173,http://127.0.0.1:5173,http://localhost:5174,http://127.0.0.1:5174
27+
# Comma-separated origins allowed to call the API. Include both hostname styles:
28+
# - Vite dev server: :5173 (and :5174 if 5173 is busy)
29+
# - Docker/nginx static UI often mapped to :3000
30+
# If unset, the API uses the same defaults as in backend/src/main.py (Settings.ALLOWED_ORIGINS).
31+
ALLOWED_ORIGINS=http://localhost:5173,http://127.0.0.1:5173,http://localhost:5174,http://127.0.0.1:5174,http://localhost:3000,http://127.0.0.1:3000
3032
ALLOWED_ORIGIN_REGEX=

backend/src/main.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from fastapi.middleware.cors import CORSMiddleware
1111
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
1212
from jose import jwt, JWTError
13+
from pydantic import Field
1314
from pydantic_settings import BaseSettings
1415
from dotenv import load_dotenv
1516
from slowapi import Limiter, _rate_limit_exceeded_handler
@@ -23,15 +24,28 @@
2324

2425
# --- 1. CONFIGURATION ---
2526
load_dotenv(os.path.join(os.path.dirname(__file__), '..', '.env'))
27+
_DEFAULT_ALLOWED_ORIGINS = (
28+
"http://localhost:5173,"
29+
"http://127.0.0.1:5173,"
30+
"http://localhost:5174,"
31+
"http://127.0.0.1:5174,"
32+
"http://localhost:3000,"
33+
"http://127.0.0.1:3000"
34+
)
35+
36+
2637
class Settings(BaseSettings):
2738
MONGO_URL: str
2839
MONGO_DB_NAME: str
2940
JWT_ACCESS_SECRET: str
3041
JWT_REFRESH_SECRET: str
3142
ACCESS_TOKEN_EXPIRE_MINUTES: int
3243
REFRESH_TOKEN_EXPIRE_DAYS: int
33-
ALLOWED_ORIGINS: str
34-
ALLOWED_ORIGIN_REGEX: str | None = None
44+
ALLOWED_ORIGINS: str = Field(
45+
default=_DEFAULT_ALLOWED_ORIGINS,
46+
description="Comma-separated browser origins permitted for CORS (Vite :5173/5174, Dockerized UI :3000).",
47+
)
48+
ALLOWED_ORIGIN_REGEX: str | None = Field(default=None)
3549

3650
settings = Settings()
3751

@@ -162,7 +176,9 @@ async def lifespan(app: FastAPI):
162176
app = FastAPI(title="Simple Health App API (MongoDB)", lifespan=lifespan)
163177
app.state.limiter = limiter
164178
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
165-
allowed_origins = [origin.strip() for origin in settings.ALLOWED_ORIGINS.split(',') if origin.strip()]
179+
allowed_origins = [
180+
origin.strip() for origin in settings.ALLOWED_ORIGINS.split(",") if origin.strip()
181+
]
166182

167183
app.add_middleware(
168184
CORSMiddleware,

0 commit comments

Comments
 (0)