diff --git a/application/app.py b/application/app.py index 227c0f6d..31aef718 100644 --- a/application/app.py +++ b/application/app.py @@ -4,7 +4,7 @@ import platform import uuid import dotenv -from flask import Flask, jsonify, redirect, request +from flask import Flask, Response, jsonify, redirect, request from jose import jwt from application.auth import handle_auth @@ -148,5 +148,14 @@ def authenticate_request(): request.decoded_token = decoded_token +@app.after_request +def after_request(response: Response) -> Response: + """Add CORS headers for the pure Flask development entrypoint.""" + response.headers["Access-Control-Allow-Origin"] = "*" + response.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization" + response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS" + return response + + if __name__ == "__main__": app.run(debug=settings.FLASK_DEBUG_MODE, port=7091) diff --git a/tests/test_app_routes.py b/tests/test_app_routes.py index 96a48062..656b550b 100644 --- a/tests/test_app_routes.py +++ b/tests/test_app_routes.py @@ -105,6 +105,26 @@ class TestAuthenticateRequest: assert response.status_code == 200 -# CORS is handled at the Starlette layer (application/asgi.py) so that -# both the Flask mount and the /mcp mount get consistent headers. See -# tests/test_asgi.py for the replacement coverage. +class TestFlaskCors: + + @pytest.mark.unit + def test_cors_headers_on_flask_route(self, client): + response = client.get("/api/health", headers={"Origin": "http://localhost:5173"}) + assert response.headers["Access-Control-Allow-Origin"] == "*" + assert response.headers["Access-Control-Allow-Headers"] == "Content-Type, Authorization" + assert response.headers["Access-Control-Allow-Methods"] == "GET, POST, PUT, DELETE, OPTIONS" + + @pytest.mark.unit + def test_cors_headers_on_flask_preflight(self, client): + response = client.options( + "/api/health", + headers={ + "Origin": "http://localhost:5173", + "Access-Control-Request-Method": "GET", + "Access-Control-Request-Headers": "Content-Type", + }, + ) + assert response.status_code == 200 + assert response.headers["Access-Control-Allow-Origin"] == "*" + assert response.headers["Access-Control-Allow-Headers"] == "Content-Type, Authorization" + assert response.headers["Access-Control-Allow-Methods"] == "GET, POST, PUT, DELETE, OPTIONS"