import secrets from fastapi import APIRouter, HTTPException, Request, Response from pydantic import BaseModel from app.core.config import SESSION_COOKIE_SECURE, SESSION_MAX_AGE_DAYS, SITE_PASSWORD from app.core.site_auth import COOKIE_NAME, create_session_token, verify_session_token router = APIRouter(prefix="/api/auth", tags=["auth"]) class LoginRequest(BaseModel): password: str class AuthStatus(BaseModel): required: bool authenticated: bool @router.get("/status", response_model=AuthStatus) def status(request: Request): if not SITE_PASSWORD: return AuthStatus(required=False, authenticated=True) token = request.cookies.get(COOKIE_NAME) return AuthStatus(required=True, authenticated=bool(token and verify_session_token(token))) @router.post("/login", response_model=AuthStatus) def login(req: LoginRequest, response: Response): if not SITE_PASSWORD: raise HTTPException(status_code=403, detail="SITE_PASSWORD is not configured on the server") if not secrets.compare_digest(req.password, SITE_PASSWORD): raise HTTPException(status_code=401, detail="Invalid password") response.set_cookie( COOKIE_NAME, create_session_token(), max_age=SESSION_MAX_AGE_DAYS * 86400, httponly=True, secure=SESSION_COOKIE_SECURE, samesite="lax", path="/", ) return AuthStatus(required=True, authenticated=True) @router.post("/logout", response_model=AuthStatus) def logout(response: Response): response.delete_cookie(COOKIE_NAME, path="/") return AuthStatus(required=bool(SITE_PASSWORD), authenticated=False)