Fix PDF viewing: cookie auth fallback + .mjs MIME type
- /file and /pdf endpoints: make token optional, fall back to hnf_session cookie auth when no valid JWT token provided. Kitchen frontend passes the literal '__session__' compat shim so token-only auth always 401'd. - Add Request injection so cookie-based fallback path can read hnf_session. - nginx: add types block mapping .mjs → text/javascript so pdf.worker.min.mjs passes browser strict MIME check for ES module scripts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
cd9e7dbfef
commit
742bc91b3b
2 changed files with 31 additions and 12 deletions
|
|
@ -6,7 +6,7 @@ from datetime import date, timedelta
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, BackgroundTasks
|
from fastapi import APIRouter, Depends, HTTPException, Request, UploadFile, File, BackgroundTasks
|
||||||
from fastapi.responses import FileResponse
|
from fastapi.responses import FileResponse
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy import select, func, text
|
from sqlalchemy import select, func, text
|
||||||
|
|
@ -1233,17 +1233,25 @@ async def get_invoice_image(
|
||||||
@router.get("/{invoice_id}/file")
|
@router.get("/{invoice_id}/file")
|
||||||
async def get_invoice_file(
|
async def get_invoice_file(
|
||||||
invoice_id: int,
|
invoice_id: int,
|
||||||
token: str,
|
request: Request,
|
||||||
|
token: Optional[str] = None,
|
||||||
db: AsyncSession = Depends(get_db)
|
db: AsyncSession = Depends(get_db)
|
||||||
):
|
):
|
||||||
"""Get invoice file (image or PDF) with token in query param - works through proxies"""
|
"""Get invoice file (image or PDF) — supports both cookie auth and ?token= JWT"""
|
||||||
from starlette.responses import Response
|
from starlette.responses import Response
|
||||||
from services.file_archival_service import FileArchivalService
|
from services.file_archival_service import FileArchivalService
|
||||||
|
|
||||||
# Verify token and get user
|
# Try JWT token param first, fall back to hnf_session cookie
|
||||||
|
current_user = None
|
||||||
|
if token:
|
||||||
current_user = await get_current_user_from_token(token, db)
|
current_user = await get_current_user_from_token(token, db)
|
||||||
if not current_user:
|
if not current_user:
|
||||||
raise HTTPException(status_code=401, detail="Invalid token")
|
try:
|
||||||
|
current_user = await get_current_user(request)
|
||||||
|
except HTTPException:
|
||||||
|
pass
|
||||||
|
if not current_user:
|
||||||
|
raise HTTPException(status_code=401, detail="Authentication required")
|
||||||
|
|
||||||
invoice = await get_invoice_or_404(invoice_id, current_user, db)
|
invoice = await get_invoice_or_404(invoice_id, current_user, db)
|
||||||
|
|
||||||
|
|
@ -1282,17 +1290,23 @@ async def get_invoice_file(
|
||||||
@router.get("/{invoice_id}/pdf")
|
@router.get("/{invoice_id}/pdf")
|
||||||
async def get_invoice_pdf(
|
async def get_invoice_pdf(
|
||||||
invoice_id: int,
|
invoice_id: int,
|
||||||
token: str,
|
request: Request,
|
||||||
|
token: Optional[str] = None,
|
||||||
db: AsyncSession = Depends(get_db)
|
db: AsyncSession = Depends(get_db)
|
||||||
):
|
):
|
||||||
"""Get invoice PDF with token in query param (for iframe embedding) - DEPRECATED, use /file"""
|
"""Get invoice PDF — DEPRECATED, use /file"""
|
||||||
from auth import get_current_user, require_cap_from_token
|
|
||||||
from starlette.responses import Response
|
from starlette.responses import Response
|
||||||
|
|
||||||
# Verify token and get user
|
current_user = None
|
||||||
|
if token:
|
||||||
current_user = await get_current_user_from_token(token, db)
|
current_user = await get_current_user_from_token(token, db)
|
||||||
if not current_user:
|
if not current_user:
|
||||||
raise HTTPException(status_code=401, detail="Invalid token")
|
try:
|
||||||
|
current_user = await get_current_user(request)
|
||||||
|
except HTTPException:
|
||||||
|
pass
|
||||||
|
if not current_user:
|
||||||
|
raise HTTPException(status_code=401, detail="Authentication required")
|
||||||
|
|
||||||
invoice = await get_invoice_or_404(invoice_id, current_user, db)
|
invoice = await get_invoice_or_404(invoice_id, current_user, db)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
types {
|
||||||
|
text/javascript js mjs;
|
||||||
|
application/pdf pdf;
|
||||||
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
server_name _;
|
server_name _;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue