from fastapi import APIRouter, HTTPException, Request, status from app.core.deps import CurrentUser, DbSession, SettingsDep from app.core.rate_limit import enforce_rate_limit from app.core.security import create_user_access_token from app.models.user import User from app.schemas.auth import LoginRequest, RegisterRequest, Token, UserPublic from app.services.users import EmailAlreadyRegisteredError, authenticate_user, register_user router = APIRouter(prefix="/auth", tags=["auth"]) @router.post("/register", response_model=Token, status_code=status.HTTP_201_CREATED) def register(body: RegisterRequest, request: Request, db: DbSession, settings: SettingsDep) -> Token: enforce_rate_limit(request, scope="auth_register", limit=10, window_seconds=60) try: user = register_user(db, body) except EmailAlreadyRegisteredError: raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail="An account with this email already exists", ) token = create_user_access_token(user.id, settings) return Token(access_token=token) @router.post("/login", response_model=Token) def login(body: LoginRequest, request: Request, db: DbSession, settings: SettingsDep) -> Token: enforce_rate_limit(request, scope="auth_login", limit=20, window_seconds=60) user = authenticate_user(db, body.email, body.password) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials", ) token = create_user_access_token(user.id, settings) return Token(access_token=token) @router.get("/me", response_model=UserPublic) def me(user: CurrentUser) -> User: return user