๐ฆ NestJS Module Structure
src/
โโโ auth-2fa/
โ โโโ auth-2fa.module.ts # Auth2FAModule
โ โโโ controllers/
โ โ โโโ totp.controller.ts # TOTP endpoints
โ โ โโโ webauthn.controller.ts # WebAuthn endpoints
โ โ โโโ backup.controller.ts # Backup codes
โ โ โโโ recovery.controller.ts # Account recovery
โ โโโ services/
โ โ โโโ totp.service.ts # TOTP logic (otplib)
โ โ โโโ webauthn.service.ts # WebAuthn (@simplewebauthn/server)
โ โ โโโ backup-code.service.ts # Backup code generation/verification
โ โ โโโ recovery.service.ts # Account recovery flow
โ โ โโโ vault.service.ts # Vault/HSM encryption client
โ โ โโโ audit.service.ts # Audit logging
โ โโโ guards/
โ โ โโโ two-fa.guard.ts # Require 2FA on protected routes
โ โ โโโ two-fa-setup.guard.ts # Ensure user has active session
โ โโโ decorators/
โ โ โโโ require-2fa.decorator.ts
โ โโโ dto/
โ โ โโโ totp-setup.dto.ts
โ โ โโโ totp-verify.dto.ts
โ โ โโโ webauthn-register.dto.ts
โ โ โโโ webauthn-auth.dto.ts
โ โ โโโ backup-verify.dto.ts
โ โโโ entities/
โ โ โโโ user-2fa-settings.entity.ts
โ โ โโโ totp-secret.entity.ts
โ โ โโโ webauthn-credential.entity.ts
โ โ โโโ backup-code.entity.ts
โ โ โโโ audit-log.entity.ts
โ โโโ constants/
โ โโโ 2fa.constants.ts
โโโ app.module.ts
โโโ main.ts
Module Registration
// auth-2fa.module.ts
@Module({
imports: [
TypeOrmModule.forFeature([
User2FASettings, TotpSecret,
WebAuthnCredential, BackupCode, AuditLog
]),
ThrottlerModule.forRoot({ ttl: 300, limit: 5 }),
VaultModule,
RedisModule,
],
controllers: [
TotpController, WebAuthnController,
BackupController, RecoveryController
],
providers: [
TotpService, WebAuthnService, BackupCodeService,
RecoveryService, VaultService, AuditService,
TwoFAGuard, TwoFASetupGuard
],
exports: [TwoFAGuard, TotpService, WebAuthnService]
})
export class Auth2FAModule {}
๐ User Stories
US-001: Enable TOTP Authentication
As a registered eToro user, I want to set up TOTP-based 2FA, so that my account has an additional layer of security.
- โ
User can access 2FA settings from account security page
- โ
System generates a TOTP secret and displays QR code
- โ
User must verify a valid code before 2FA is activated
- โ
10 backup codes are generated and displayed once
- โ
Audit log entry created on successful enable
US-002: Login with TOTP
As a user with TOTP enabled, I want to enter my authenticator code after password, so that my login is protected.
- โ
After password validation, user is prompted for TOTP code
- โ
Code accepts ยฑ1 time step window (90 seconds)
- โ
Same code cannot be reused (replay protection)
- โ
5 failed attempts triggers 5-minute lockout
- โ
Option to use backup code or passkey instead
US-003: Register Passkey
As a user, I want to register my device's biometric as a passkey, so that I can log in without typing codes.
- โ
User can add multiple passkeys (up to 10)
- โ
Device biometric prompt (Face ID/fingerprint/Windows Hello) shown
- โ
Credential stored with user-friendly device name (auto-suggested, editable)
- โ
Resident key / discoverable credential enabled for passwordless-ready
- โ
Works alongside TOTP (user chooses at login)
- โ
Passkey synced via iCloud Keychain / Google Password Manager automatically
- โ
backup_eligible and backup_state flags stored for credential management
US-004: Login with Passkey
As a user with registered passkeys, I want to authenticate using biometrics, so that login is fast and phishing-proof.
- โ
After password, "Sign in with Passkey" shown as preferred option
- โ
Biometric prompt appears with registered credential
- โ
Sign counter is incremented (clone detection)
- โ
Falls back to TOTP โ backup code โ recovery if passkey fails
- โ
Cross-device auth via QR code (hybrid transport) when on unfamiliar device
US-004b: Passwordless Login with Passkey (Phase 3)
As a user with a discoverable passkey, I want to sign in without entering my username or password, so that login is instant.
- โ
Login page supports conditional UI (WebAuthn autofill)
- โ
Browser shows passkey suggestion in username field
- โ
User taps suggestion โ biometric โ logged in (no password)
- โ
userHandle in assertion maps to eToro user ID
- โ
Audit log records passwordless_login event
US-004c: Manage Passkeys
As a user with registered passkeys, I want to view, rename, and delete my passkeys, so that I can manage my devices.
- โ
List shows device name, last used date, created date, sync status
- โ
User can rename passkeys (e.g., "iPhone 15 Pro" โ "Work Phone")
- โ
User can delete passkeys (requires 2FA verification)
- โ
Cannot delete last passkey if it's the only 2FA method
- โ
Warning when deleting a synced passkey (affects all synced devices)
US-004d: Cross-Device Passkey Authentication
As a user logging in on a device without my passkey, I want to use my phone as an authenticator via QR code, so that I can securely log in anywhere.
- โ
QR code displayed on desktop browser
- โ
User scans with phone camera โ BLE proximity check
- โ
Biometric prompt on phone โ assertion tunneled to desktop
- โ
Works across ecosystems (iPhone authenticating on Windows)
US-004e: Passkey Nudge (Migration)
As a user currently using SMS or TOTP, I want to be prompted to upgrade to Passkey, so that I benefit from better security and UX.
- โ
Post-login bottom sheet shown after successful SMS/TOTP login
- โ
Shows speed comparison: "Sign in 5x faster with Passkey"
- โ
"Set up now" (primary) and "Maybe later" (dismiss) buttons
- โ
Dismissed nudge reappears after 7 days (max 3 times then stops)
- โ
Nudge suppressed if device doesn't support WebAuthn
US-005: Use Backup Code
As a user who lost access to their authenticator, I want to use a backup code, so that I can still log in.
- โ
Each backup code is single-use
- โ
Warning shown when โค3 codes remaining
- โ
User prompted to regenerate when โค2 remaining
US-006: Disable 2FA
As a user, I want to disable 2FA, so that I can simplify my login if needed.
- โ
Requires current TOTP code or passkey verification
- โ
Confirmation dialog warns about reduced security
- โ
All TOTP secrets and backup codes are deleted
- โ
WebAuthn credentials optionally retained
- โ
Audit log entry created
US-007: Account Recovery
As a user who lost all 2FA methods, I want to recover my account, so that I'm not permanently locked out.
- โ
Recovery requires email verification + ID document
- โ
Manual review by security team (24-48 hour SLA)
- โ
2FA is temporarily disabled upon approval
- โ
User forced to set up new 2FA within 72 hours