-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathfrontend_server.py
More file actions
89 lines (73 loc) · 2.76 KB
/
Copy pathfrontend_server.py
File metadata and controls
89 lines (73 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import os
import uvicorn
from dotenv import load_dotenv
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse, HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
# Load environment variables from .env file
load_dotenv()
app = FastAPI()
# Read allowed origins from environment; fall back to same-origin only
_allowed_origins = os.getenv("ALLOWED_ORIGINS", "").split(",")
_allowed_origins = [o.strip() for o in _allowed_origins if o.strip()]
app.add_middleware(
CORSMiddleware,
allow_origins=_allowed_origins,
allow_methods=["GET"],
allow_headers=["*"],
)
# Build paths
BUILD_DIR = os.path.join(os.path.dirname(__file__), "dist")
INDEX_HTML = os.path.join(BUILD_DIR, "index.html")
# Serve static files from build directory
app.mount(
"/assets", StaticFiles(directory=os.path.join(BUILD_DIR, "assets")), name="assets"
)
@app.get("/")
async def serve_index():
return FileResponse(INDEX_HTML)
@app.get("/config")
async def get_config(request: Request):
# Only serve config to same-origin requests by checking the Referer/Origin
origin = request.headers.get("origin") or ""
referer = request.headers.get("referer") or ""
host = request.headers.get("host") or ""
if origin and not origin.endswith(host):
return JSONResponse(status_code=403, content={"detail": "Forbidden"})
config = {
"API_URL": os.getenv("API_URL", ""),
"REACT_APP_MSAL_AUTH_CLIENTID": os.getenv(
"REACT_APP_MSAL_AUTH_CLIENTID", ""
),
"REACT_APP_MSAL_AUTH_AUTHORITY": os.getenv(
"REACT_APP_MSAL_AUTH_AUTHORITY", ""
),
"REACT_APP_MSAL_REDIRECT_URL": os.getenv(
"REACT_APP_MSAL_REDIRECT_URL", ""
),
"REACT_APP_MSAL_POST_REDIRECT_URL": os.getenv(
"REACT_APP_MSAL_POST_REDIRECT_URL", ""
),
"REACT_APP_WEB_SCOPE": os.getenv(
"REACT_APP_WEB_SCOPE", ""
),
"REACT_APP_API_SCOPE": os.getenv(
"REACT_APP_API_SCOPE", ""
),
"ENABLE_AUTH": os.getenv("ENABLE_AUTH", "false"),
}
return config
@app.get("/{full_path:path}")
async def serve_app(full_path: str):
# Resolve the requested path and ensure it stays within BUILD_DIR
file_path = os.path.realpath(os.path.join(BUILD_DIR, full_path))
build_dir_real = os.path.realpath(BUILD_DIR)
if not file_path.startswith(build_dir_real + os.sep) and file_path != build_dir_real:
return FileResponse(INDEX_HTML)
if os.path.isfile(file_path):
return FileResponse(file_path)
# Otherwise serve index.html for client-side routing
return FileResponse(INDEX_HTML)
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=3000)