|
|
|
@ -1,7 +1,8 @@
|
|
|
|
from typing import List, Optional
|
|
|
|
from typing import List, Optional
|
|
|
|
from fastapi import APIRouter, Depends
|
|
|
|
from fastapi import APIRouter, Depends
|
|
|
|
from fastapi.responses import JSONResponse
|
|
|
|
from fastapi.responses import JSONResponse, FileResponse
|
|
|
|
from pydantic import BaseModel
|
|
|
|
from pydantic import BaseModel
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from src.auth.service import JWTBearer
|
|
|
|
from src.auth.service import JWTBearer
|
|
|
|
@ -75,5 +76,19 @@ authenticated_api_router.include_router(
|
|
|
|
yeardata_router, prefix="/yeardata", tags=["yeardata"]
|
|
|
|
yeardata_router, prefix="/yeardata", tags=["yeardata"]
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@api_router.get("/uploads/{file_path:path}", include_in_schema=False)
|
|
|
|
|
|
|
|
def uploads(file_path: str):
|
|
|
|
|
|
|
|
"""Endpoint to static folder on backend ."""
|
|
|
|
|
|
|
|
uploads_dir = os.path.join(os.path.dirname(__file__), "uploads")
|
|
|
|
|
|
|
|
abs_file_path = os.path.abspath(os.path.join(uploads_dir, file_path))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Security check: ensure abs_file_path is inside uploads_dir
|
|
|
|
|
|
|
|
if not abs_file_path.startswith(os.path.abspath(uploads_dir)):
|
|
|
|
|
|
|
|
return JSONResponse(status_code=403, content={"detail": [{"msg": "Forbidden"}]})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not os.path.isfile(abs_file_path):
|
|
|
|
|
|
|
|
return JSONResponse(status_code=404, content={"detail": [{"msg": "File not found"}]})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return FileResponse(abs_file_path)
|
|
|
|
|
|
|
|
|
|
|
|
api_router.include_router(authenticated_api_router)
|
|
|
|
api_router.include_router(authenticated_api_router)
|
|
|
|
|