Skip to content

Add Dockerfile and fix CORS errors#33

Merged
rosasbehoundja merged 3 commits into
IFRI-AI-Classes:mainfrom
Pinite37:main
Mar 26, 2026
Merged

Add Dockerfile and fix CORS errors#33
rosasbehoundja merged 3 commits into
IFRI-AI-Classes:mainfrom
Pinite37:main

Conversation

@rosasbehoundja
Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI review requested due to automatic review settings March 26, 2026 21:43
@rosasbehoundja rosasbehoundja merged commit c54042c into IFRI-AI-Classes:main Mar 26, 2026
4 checks passed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds containerization support and tightens CORS configuration to address frontend cross-origin request failures, while also centralizing the frontend API base URL configuration.

Changes:

  • Added a Dockerfile and updated start.sh defaults/env exports for running the FastAPI app.
  • Implemented stricter, normalized CORS origin allow-list building in backup/app/main.py.
  • Introduced pages/static/js/config.js and updated pages/scripts to read API_URL from window.APP_CONFIG.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
start.sh Sets runtime env vars (DB URL, CORS origins, SECRET_KEY) before launching Uvicorn.
backup/app/main.py Normalizes and de-duplicates CORS origins; removes permissive "*" fallback.
Dockerfile Adds a basic container build/run configuration for the API.
pages/static/js/config.js Provides a single place to configure frontend API_URL.
pages/static/js/auth.js Uses window.APP_CONFIG.API_URL (with fallback) instead of localhost constant.
pages/static/js/scoreboard.js Uses window.APP_CONFIG.API_URL (with fallback) instead of localhost constant.
pages/submission.html Updates nav label and loads config.js before auth.js.
pages/scoreboard.html Loads config.js before scoreboard.js.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread start.sh

# Export DATABASE_URL (uses existing value if already set).
export DATABASE_URL="${DATABASE_URL:-sqlite:///./mpvrp_scoring.db}"
export FRONTEND_ALLOWED_ORIGINS="${FRONTEND_ALLOWED_ORIGINS:-https://ifri-ai-classes.github.io,https://ifri-ai-classes.github.io/MPVRP-CC,https://ifri-ai-classes.github.io/MPVRP-CC/pages}"
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FRONTEND_ALLOWED_ORIGINS default includes path components (e.g. "/MPVRP-CC"), but CORS Origin values are scheme+host(+port) only. With the new normalization this collapses to a single origin and will emit warnings; it also omits localhost origins which can break local frontend dev when using start.sh defaults. Consider defaulting to origins only (no paths) and include localhost entries if local dev via start.sh is expected.

Suggested change
export FRONTEND_ALLOWED_ORIGINS="${FRONTEND_ALLOWED_ORIGINS:-https://ifri-ai-classes.github.io,https://ifri-ai-classes.github.io/MPVRP-CC,https://ifri-ai-classes.github.io/MPVRP-CC/pages}"
export FRONTEND_ALLOWED_ORIGINS="${FRONTEND_ALLOWED_ORIGINS:-https://ifri-ai-classes.github.io,http://localhost:3000,http://127.0.0.1:3000,http://localhost:5173,http://127.0.0.1:5173}"

Copilot uses AI. Check for mistakes.
Comment thread start.sh
Comment on lines 17 to 22
# Require stable secret key in environments with external users.
# Generate and export a fresh SECRET_KEY at launch time.
SECRET_KEY="$(python -c "import secrets; print('SECRET_KEY=' + secrets.token_urlsafe(32))")"
export "$SECRET_KEY"
export SECRET_KEY="$(python -c "import secrets; print(secrets.token_urlsafe(32))")"
if [[ -z "${SECRET_KEY:-}" ]]; then
echo "ERROR: SECRET_KEY is required. Set it in your environment before starting the server." >&2
exit 1
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

export SECRET_KEY="$(...)" overwrites any pre-set SECRET_KEY on every start, which breaks token validity across restarts and contradicts the "Require stable secret key" comment. It also makes the subsequent -z check effectively dead code. Prefer only generating a key when SECRET_KEY is unset (or fail fast in production) and keep the stability requirement enforceable.

Copilot uses AI. Check for mistakes.
Comment thread Dockerfile
@@ -0,0 +1,12 @@
FROM python:3.11-slim
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Base image is Python 3.11, but the project declares requires-python ">=3.12" (pyproject.toml). This mismatch can cause runtime failures or dependency resolution issues in the container. Update the image to a 3.12 variant (or adjust the project requirement if 3.11 is actually supported).

Suggested change
FROM python:3.11-slim
FROM python:3.12-slim

Copilot uses AI. Check for mistakes.
Comment thread backup/app/main.py
Comment on lines +26 to +66
def _normalize_origin(origin: str) -> str | None:
"""Normalize CORS entries to scheme://host[:port] and drop invalid values."""
raw = origin.strip()
if not raw:
return None

parsed = urlsplit(raw)
if not parsed.scheme or not parsed.netloc:
logger.warning("Ignoring invalid CORS origin '%s'", origin)
return None

normalized = f"{parsed.scheme}://{parsed.netloc}"
if normalized != raw.rstrip("/"):
logger.warning("Normalized CORS origin '%s' to '%s'", origin, normalized)
return normalized


def _normalized_unique(origins: list[str]) -> list[str]:
result: list[str] = []
for origin in origins:
normalized = _normalize_origin(origin)
if normalized and normalized not in result:
result.append(normalized)
return result


def _build_allowed_origins() -> list[str]:
"""Build a strict CORS allow-list from environment variables."""
allowed_origins_env = os.getenv("FRONTEND_ALLOWED_ORIGINS", "")
parsed = [origin.strip() for origin in allowed_origins_env.split(",") if origin.strip()]
parsed = _normalized_unique(allowed_origins_env.split(","))

if parsed:
return parsed

# Backward-compatible fallback when comma-separated variable is not set.
legacy_origins = [o for o in [FRONTEND_DEV_URL, FRONTEND_PROD_URL] if o]
legacy_origins = _normalized_unique([FRONTEND_DEV_URL, FRONTEND_PROD_URL])
if legacy_origins:
return legacy_origins

# Safe local fallback for development/test only.
return ["http://localhost:3000", "http://127.0.0.1:3000", "*"]
return ["http://localhost:3000", "http://127.0.0.1:3000"]
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New origin normalization/allow-list building logic is security-sensitive and currently untested. Add tests that exercise _build_allowed_origins for env values with paths/trailing slashes, duplicates, invalid entries, and the legacy FRONTEND_DEV_URL/FRONTEND_PROD_URL fallback to ensure CORS behavior stays correct.

Copilot uses AI. Check for mistakes.
rosasbehoundja added a commit to Pinite37/MPVRP-CC that referenced this pull request Mar 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants