Spaces:
Running
Running
File size: 2,718 Bytes
c2ea5ed bcbd2ec c2ea5ed bcbd2ec c2ea5ed 3dc5183 c2ea5ed bcbd2ec c2ea5ed bcbd2ec c2ea5ed bcbd2ec c2ea5ed bcbd2ec c2ea5ed bcbd2ec c2ea5ed bcbd2ec |
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 |
from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse, FileResponse, JSONResponse
from pathlib import Path
router = APIRouter()
# Security: Define base directories for path traversal protection
DIST_DIR = Path("frontend/dist").resolve()
ASSETS_DIR = Path("frontend/dist/assets").resolve()
def is_safe_path(base_dir: Path, requested_path: Path) -> bool:
"""Check if the requested path is within the allowed base directory"""
try:
resolved = requested_path.resolve()
return str(resolved).startswith(str(base_dir))
except (OSError, ValueError):
return False
@router.get("/agentgraph", response_class=HTMLResponse)
async def agentgraph_interface(request: Request):
"""Serve the React-based AgentGraph interface (requires authentication)"""
# Serve the built React app from the new location
dist_path = DIST_DIR / "index.html"
if dist_path.exists():
with open(dist_path, 'r') as f:
content = f.read()
return HTMLResponse(content=content)
else:
# Return error message if React app not built
return JSONResponse(
content={"error": "React app not built. Please run 'npm run build' in the frontend directory."},
status_code=503
)
@router.get("/agentgraph/{path:path}")
async def agentgraph_assets(path: str):
"""Serve static assets for the React app with path traversal protection"""
requested_path = (DIST_DIR / path).resolve()
# Security: Prevent path traversal attacks
if not is_safe_path(DIST_DIR, requested_path):
return JSONResponse(
content={"error": "Access denied"},
status_code=403
)
if requested_path.is_file():
return FileResponse(requested_path)
return JSONResponse(content={"error": "File not found"}, status_code=404)
@router.get("/assets/{path:path}")
async def serve_assets(path: str):
"""Serve React assets from /assets/ path with path traversal protection"""
requested_path = (ASSETS_DIR / path).resolve()
# Security: Prevent path traversal attacks
if not is_safe_path(ASSETS_DIR, requested_path):
return JSONResponse(
content={"error": "Access denied"},
status_code=403
)
if requested_path.is_file():
return FileResponse(requested_path)
return JSONResponse(content={"error": "Asset not found"}, status_code=404)
@router.get("/vite.svg")
async def serve_vite_svg():
"""Serve the vite.svg favicon"""
file_path = DIST_DIR / "vite.svg"
if file_path.exists():
return FileResponse(file_path)
return JSONResponse(content={"error": "Favicon not found"}, status_code=404)
|