auth(2fa): add one-time recovery codes with regenerate/status APIs
All checks were successful
CI / test (push) Successful in 40s

This commit is contained in:
2026-03-08 19:16:15 +03:00
parent f91a6493ff
commit fb812c9a39
10 changed files with 320 additions and 10 deletions

View File

@@ -16,6 +16,8 @@ from app.auth.schemas import (
TokenResponse,
SessionRead,
TwoFactorCodeRequest,
TwoFactorRecoveryCodesRead,
TwoFactorRecoveryStatusRead,
TwoFactorSetupRead,
VerifyEmailRequest,
)
@@ -37,6 +39,8 @@ from app.auth.service import (
resend_verification_email,
reset_password,
setup_twofa,
regenerate_twofa_recovery_codes,
get_twofa_recovery_codes_remaining,
verify_email,
oauth2_scheme,
)
@@ -224,3 +228,20 @@ async def disable_2fa(
) -> MessageResponse:
await disable_twofa(db, current_user, code=payload.code)
return MessageResponse(message="2FA disabled")
@router.post("/2fa/recovery-codes/regenerate", response_model=TwoFactorRecoveryCodesRead)
async def regenerate_2fa_recovery_codes(
payload: TwoFactorCodeRequest,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> TwoFactorRecoveryCodesRead:
codes = await regenerate_twofa_recovery_codes(db, current_user, code=payload.code)
return TwoFactorRecoveryCodesRead(codes=codes)
@router.get("/2fa/recovery-codes/status", response_model=TwoFactorRecoveryStatusRead)
async def get_2fa_recovery_codes_status(
current_user: User = Depends(get_current_user),
) -> TwoFactorRecoveryStatusRead:
return TwoFactorRecoveryStatusRead(remaining_codes=get_twofa_recovery_codes_remaining(current_user))