from fastapi import APIRouter, Depends, Request, status from sqlalchemy.ext.asyncio import AsyncSession from app.auth.schemas import ( AuthUserResponse, LoginRequest, MessageResponse, RefreshTokenRequest, RegisterRequest, RequestPasswordResetRequest, ResendVerificationRequest, ResetPasswordRequest, TokenResponse, VerifyEmailRequest, ) from app.auth.service import ( get_current_user, get_email_sender, login_user, refresh_tokens, register_user, request_password_reset, resend_verification_email, reset_password, verify_email, ) from app.database.session import get_db from app.email.service import EmailService from app.config.settings import settings from app.utils.rate_limit import enforce_ip_rate_limit from app.users.models import User router = APIRouter(prefix="/auth", tags=["auth"]) @router.post("/register", response_model=MessageResponse, status_code=status.HTTP_201_CREATED) async def register( payload: RegisterRequest, request: Request, db: AsyncSession = Depends(get_db), email_service: EmailService = Depends(get_email_sender), ) -> MessageResponse: await enforce_ip_rate_limit( request, scope="auth_register", limit=settings.register_rate_limit_per_minute, ) await register_user(db, payload, email_service) return MessageResponse(message="Registration successful. Verification email sent.") @router.post("/login", response_model=TokenResponse) async def login(payload: LoginRequest, request: Request, db: AsyncSession = Depends(get_db)) -> TokenResponse: await enforce_ip_rate_limit( request, scope="auth_login", limit=settings.login_rate_limit_per_minute, ) return await login_user(db, payload) @router.post("/refresh", response_model=TokenResponse) async def refresh( payload: RefreshTokenRequest, request: Request, db: AsyncSession = Depends(get_db), ) -> TokenResponse: await enforce_ip_rate_limit( request, scope="auth_refresh", limit=settings.refresh_rate_limit_per_minute, ) return await refresh_tokens(db, payload) @router.post("/verify-email", response_model=MessageResponse) async def verify_email_endpoint(payload: VerifyEmailRequest, db: AsyncSession = Depends(get_db)) -> MessageResponse: await verify_email(db, payload) return MessageResponse(message="Email verified successfully.") @router.post("/resend-verification", response_model=MessageResponse) async def resend_verification( payload: ResendVerificationRequest, request: Request, db: AsyncSession = Depends(get_db), email_service: EmailService = Depends(get_email_sender), ) -> MessageResponse: await enforce_ip_rate_limit( request, scope="auth_resend_verification", limit=settings.reset_rate_limit_per_minute, ) await resend_verification_email(db, payload, email_service) return MessageResponse(message="If the account exists, a verification email was sent.") @router.post("/request-password-reset", response_model=MessageResponse) async def request_password_reset_endpoint( payload: RequestPasswordResetRequest, request: Request, db: AsyncSession = Depends(get_db), email_service: EmailService = Depends(get_email_sender), ) -> MessageResponse: await enforce_ip_rate_limit( request, scope="auth_request_reset", limit=settings.reset_rate_limit_per_minute, ) await request_password_reset(db, payload, email_service) return MessageResponse(message="If the account exists, a reset email was sent.") @router.post("/reset-password", response_model=MessageResponse) async def reset_password_endpoint(payload: ResetPasswordRequest, db: AsyncSession = Depends(get_db)) -> MessageResponse: await reset_password(db, payload) return MessageResponse(message="Password reset successfully.") @router.get("/me", response_model=AuthUserResponse) async def me(current_user: User = Depends(get_current_user)) -> AuthUserResponse: return current_user