Skip to content

feat(jef-36): backup email account recovery - #283

Merged
mankatcheung merged 3 commits into
mainfrom
feature/jef-36-account-recovery-beyond-email
Aug 8, 2026
Merged

mankatcheung merged 3 commits into
mainfrom
feature/jef-36-account-recovery-beyond-email

Conversation

@mankatcheung

@mankatcheung mankatcheung commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Summary

Implement backup email account recovery end to end.

Backend

  • Add backup email fields and verification-token persistence
  • Add setup, confirmation, removal, and recovery use cases
  • Add GraphQL mutations and DI wiring
  • Add rate limiting, token expiry, anti-enumeration, password checks, and TOTP step-up protection
  • Resolve the migration conflict with main and generate migration 0014 for the backup-email schema

Frontend

  • Add backup email setup and removal to Security settings
  • Add public backup-email verification route
  • Add backup-email recovery option to Forgot Password
  • Expose backup email status through the User GraphQL type

Verification

  • API and web typechecks pass
  • Web: 29 test files, 245 tests pass
  • Targeted lint passes for changed frontend files
  • Existing container timeout and generated-output lint issues remain documented

- Add backupEmail and backupEmailVerifiedAt fields to User entity
- Add BackupEmailVerificationToken table and domain entity
- Add DrizzleBackupEmailVerificationTokenRepository
- Add use cases: RequestAddBackupEmail, ConfirmBackupEmail, RemoveBackupEmail, RequestBackupEmailRecovery
- Add GraphQL mutations: requestAddBackupEmail, confirmBackupEmail, removeBackupEmail, requestBackupEmailRecovery
- Add rate limiters: REQUEST_ADD_BACKUP_EMAIL (3/1h), BACKUP_EMAIL_RECOVERY (5/15min)
- Add sendBackupEmailVerification email template
- Wire all new dependencies in DI container
- Update test mocks and test DB schema for new fields
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@mankatcheung, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 22 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e8406ac9-4c96-4451-b45f-a6b06768d292

📥 Commits

Reviewing files that changed from the base of the PR and between 3240e2c and 602aa37.

📒 Files selected for processing (47)
  • apps/api/drizzle/0014_purple_thunderbolt.sql
  • apps/api/drizzle/meta/0014_snapshot.json
  • apps/api/drizzle/meta/_journal.json
  • apps/api/src/__tests__/application/auth/RequestPasswordResetUseCase.test.ts
  • apps/api/src/__tests__/application/auth/SendEmailVerificationUseCase.test.ts
  • apps/api/src/__tests__/application/reminders/SendFollowUpRemindersUseCase.test.ts
  • apps/api/src/__tests__/application/sessions/CreateSessionUseCase.test.ts
  • apps/api/src/__tests__/application/user/RequestEmailChangeUseCase.test.ts
  • apps/api/src/__tests__/digest/SendWeeklyDigestUseCase.test.ts
  • apps/api/src/__tests__/helpers/createTestDb.ts
  • apps/api/src/__tests__/helpers/mocks.ts
  • apps/api/src/__tests__/interface-adapters/resolvers/AuthResolver.test.ts
  • apps/api/src/__tests__/interface-adapters/resolvers/UserResolver.test.ts
  • apps/api/src/__tests__/security/authorizationGuards.test.ts
  • apps/api/src/constants.ts
  • apps/api/src/domain/backupEmailVerificationToken/BackupEmailVerificationToken.ts
  • apps/api/src/domain/user/User.ts
  • apps/api/src/http/container.ts
  • apps/api/src/http/schema/mutations/authMutations.ts
  • apps/api/src/http/schema/mutations/userMutations.ts
  • apps/api/src/http/schema/types/UserType.ts
  • apps/api/src/infrastructure/db/repositories/DrizzleBackupEmailVerificationTokenRepository.ts
  • apps/api/src/infrastructure/db/repositories/DrizzleUserRepository.ts
  • apps/api/src/infrastructure/db/schema.ts
  • apps/api/src/infrastructure/email/BrevoEmailService.ts
  • apps/api/src/infrastructure/email/templates/backupEmailVerificationTemplate.ts
  • apps/api/src/interface-adapters/mappers/UserMapper.ts
  • apps/api/src/interface-adapters/resolvers/AuthResolver.ts
  • apps/api/src/interface-adapters/resolvers/UserResolver.ts
  • apps/api/src/use-cases/auth/IRequestBackupEmailRecoveryUseCase.ts
  • apps/api/src/use-cases/auth/RequestBackupEmailRecoveryUseCase.ts
  • apps/api/src/use-cases/ports/IBackupEmailVerificationTokenRepository.ts
  • apps/api/src/use-cases/ports/IEmailService.ts
  • apps/api/src/use-cases/ports/IUserRepository.ts
  • apps/api/src/use-cases/user/ConfirmBackupEmailUseCase.ts
  • apps/api/src/use-cases/user/IConfirmBackupEmailUseCase.ts
  • apps/api/src/use-cases/user/IRemoveBackupEmailUseCase.ts
  • apps/api/src/use-cases/user/IRequestAddBackupEmailUseCase.ts
  • apps/api/src/use-cases/user/RemoveBackupEmailUseCase.ts
  • apps/api/src/use-cases/user/RequestAddBackupEmailUseCase.ts
  • apps/web/src/__tests__/components/ForgotPasswordPage.test.tsx
  • apps/web/src/routeTree.gen.ts
  • apps/web/src/routes/-components/ConfirmBackupEmailPage.tsx
  • apps/web/src/routes/-components/ForgotPasswordPage.tsx
  • apps/web/src/routes/_authenticated/settings/-components/SettingsSecurityPage.tsx
  • apps/web/src/routes/_authenticated/settings/-components/shared.ts
  • apps/web/src/routes/confirm-backup-email.tsx

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mankatcheung mankatcheung changed the title feat(jef-36): backup email recovery infrastructure feat(jef-36): backup email account recovery Aug 8, 2026
@mankatcheung
mankatcheung merged commit ea27b5f into main Aug 8, 2026
11 checks passed
@mankatcheung
mankatcheung deleted the feature/jef-36-account-recovery-beyond-email branch August 18, 2026 13:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant