from datetime import datetime, timedelta, timezone from fastapi import Depends, HTTPException, status from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer from jose import JWTError, jwt from app.config import get_settings bearer_scheme = HTTPBearer(auto_error=False) def create_access_token(subject: str) -> str: settings = get_settings() expire = datetime.now(timezone.utc) + timedelta(minutes=settings.jwt_expire_minutes) payload = {"sub": subject, "exp": expire} return jwt.encode(payload, settings.jwt_secret, algorithm=settings.jwt_algorithm) def _decode_username(token: str) -> str: settings = get_settings() try: payload = jwt.decode( token, settings.jwt_secret, algorithms=[settings.jwt_algorithm], ) username = payload.get("sub") if not username: raise HTTPException(status_code=401, detail="Invalid token") return str(username) except JWTError as exc: raise HTTPException(status_code=401, detail="Invalid token") from exc def verify_access_token(token: str) -> str: """Проверка JWT (в т.ч. query-параметр для SSE).""" return _decode_username(token) def get_current_user( credentials: HTTPAuthorizationCredentials | None = Depends(bearer_scheme), ) -> str: if credentials is None or credentials.scheme.lower() != "bearer": raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Not authenticated", ) return _decode_username(credentials.credentials)