From e1c6537f38bedac2c4c5a993f05d04107f7abbcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?IT=E7=8B=97?= Date: Mon, 20 Jul 2026 23:45:40 +0800 Subject: [PATCH] Fix HTML report auth: accept ?token= query param for new-window download --- backend/main.py | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/backend/main.py b/backend/main.py index 21b0363..37351c3 100644 --- a/backend/main.py +++ b/backend/main.py @@ -982,13 +982,54 @@ def _make_chart_config(data, rows, section): @app.get("/api/report/{section}/html") async def export_html_report( + request: Request, section: str, - current_user: User = Depends(get_current_user) + token: Optional[str] = Query(None), ): """Generate self-contained HTML5 report with embedded data, charts, sorting, filtering, popup.""" from fastapi.responses import HTMLResponse import json from datetime import datetime + from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials + from jose import JWTError, jwt + from database import SECRET_KEY, ALGORITHM + from app.database import get_db + + credentials_exception = HTTPException( + status_code=401, + detail="Invalid or expired token", + headers={"WWW-Authenticate": "Bearer"}, + ) + + current_user = None + + # If token in query, use it + if token: + try: + payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) + user_id = int(payload.get("sub")) + db = next(get_db()) + current_user = db.query(User).filter(User.id == user_id, User.is_active == True).first() + db.close() + except (JWTError, ValueError, TypeError): + pass + + # If no query token, try Authorization header + if not current_user: + auth_header = request.headers.get("Authorization", "") + if auth_header.startswith("Bearer "): + bearer_token = auth_header[7:] + try: + payload = jwt.decode(bearer_token, SECRET_KEY, algorithms=[ALGORITHM]) + user_id = int(payload.get("sub")) + db = next(get_db()) + current_user = db.query(User).filter(User.id == user_id, User.is_active == True).first() + db.close() + except (JWTError, ValueError, TypeError): + pass + + if not current_user: + raise credentials_exception if section not in ["attendance", "accident"]: raise HTTPException(status_code=400, detail="Invalid section")