""" JWT verification middleware for FastAPI. Validates JWT tokens on all protected endpoints. """ from fastapi import Request from starlette.responses import JSONResponse from jose import JWTError, jwt from app.core.config import settings from typing import Callable async def verify_jwt_token(request: Request, call_next: Callable): # Skip CORS preflight requests if request.method == "OPTIONS": return await call_next(request) # Public endpoints that don't require authentication public_paths = [ "/api/auth/signup", "/api/auth/signin", "/docs", "/openapi.json", "/redoc", "/health", ] if request.url.path in public_paths: return await call_next(request) auth_header = request.headers.get("Authorization") if not auth_header: return JSONResponse( status_code=401, content={"detail": "Missing authentication token"}, ) if not auth_header.startswith("Bearer "): return JSONResponse( status_code=401, content={"detail": "Invalid authentication scheme"}, ) token = auth_header.replace("Bearer ", "") try: payload = jwt.decode( token, settings.JWT_SECRET, algorithms=[settings.JWT_ALGORITHM], ) user_id = payload.get("user_id") if not user_id: return JSONResponse( status_code=401, content={"detail": "Invalid token payload"}, ) request.state.user_id = user_id request.state.username = payload.get("username") except JWTError as e: return JSONResponse( status_code=401, content={"detail": f"Invalid or expired token: {str(e)}"}, ) return await call_next(request)