feat(auth): switch signup to OTP verification flow
Replace legacy signup with start/verify/resend endpoints, add OTP-focused mail templates and auth rate limits, and align compose/env/runbook for local self-hosted Supabase OTP behavior.
This commit is contained in:
@@ -6,15 +6,20 @@ from fastapi import APIRouter, Depends, Response
|
||||
from fastapi import HTTPException
|
||||
|
||||
from core.auth.models import CurrentUser
|
||||
from v1.auth.rate_limit import enforce_rate_limit
|
||||
from v1.auth.dependencies import get_auth_service
|
||||
from v1.profile.dependencies import get_current_user
|
||||
from v1.auth.schemas import (
|
||||
AuthResendCodeResponse,
|
||||
AuthSignupStartResponse,
|
||||
AuthTokenResponse,
|
||||
AuthUserByEmailResponse,
|
||||
LoginRequest,
|
||||
LogoutRequest,
|
||||
RefreshRequest,
|
||||
SignupRequest,
|
||||
SignupResendRequest,
|
||||
SignupStartRequest,
|
||||
SignupVerifyRequest,
|
||||
)
|
||||
from v1.auth.service import AuthService
|
||||
|
||||
@@ -22,12 +27,46 @@ from v1.auth.service import AuthService
|
||||
router = APIRouter(prefix="/auth", tags=["auth"])
|
||||
|
||||
|
||||
@router.post("/signup", response_model=AuthTokenResponse)
|
||||
async def signup(
|
||||
payload: SignupRequest,
|
||||
@router.post("/signup/start", response_model=AuthSignupStartResponse, status_code=202)
|
||||
async def signup_start(
|
||||
payload: SignupStartRequest,
|
||||
service: AuthService = Depends(get_auth_service),
|
||||
) -> AuthSignupStartResponse:
|
||||
await enforce_rate_limit(
|
||||
scope="signup_start",
|
||||
identifier=payload.email,
|
||||
limit=5,
|
||||
window_seconds=60,
|
||||
)
|
||||
return await service.signup_start(payload)
|
||||
|
||||
|
||||
@router.post("/signup/verify", response_model=AuthTokenResponse)
|
||||
async def signup_verify(
|
||||
payload: SignupVerifyRequest,
|
||||
service: AuthService = Depends(get_auth_service),
|
||||
) -> AuthTokenResponse:
|
||||
return await service.signup(payload)
|
||||
await enforce_rate_limit(
|
||||
scope="signup_verify",
|
||||
identifier=payload.email,
|
||||
limit=10,
|
||||
window_seconds=600,
|
||||
)
|
||||
return await service.signup_verify(payload)
|
||||
|
||||
|
||||
@router.post("/signup/resend", response_model=AuthResendCodeResponse)
|
||||
async def signup_resend(
|
||||
payload: SignupResendRequest,
|
||||
service: AuthService = Depends(get_auth_service),
|
||||
) -> AuthResendCodeResponse:
|
||||
await enforce_rate_limit(
|
||||
scope="signup_resend",
|
||||
identifier=payload.email,
|
||||
limit=3,
|
||||
window_seconds=60,
|
||||
)
|
||||
return await service.signup_resend(payload)
|
||||
|
||||
|
||||
@router.post("/login", response_model=AuthTokenResponse)
|
||||
|
||||
Reference in New Issue
Block a user