Skip to content

feat: 2FA improvements (#224, #225, #226, #227) - #329

Open
katefominmoore23 wants to merge 1 commit into
ethos-protocol:mainfrom
katefominmoore23:feature/2fa-improvements-224-225-226-227
Open

feat: 2FA improvements (#224, #225, #226, #227)#329
katefominmoore23 wants to merge 1 commit into
ethos-protocol:mainfrom
katefominmoore23:feature/2fa-improvements-224-225-226-227

Conversation

@katefominmoore23

Copy link
Copy Markdown

#227 — Surface server-side 2FA method availability

  • Add available_methods field to TwoFactorStatus (iOS + Android)
  • Decode defensively: absent field defaults to all three (backward-compat)
  • TwoFactorSetupView / TwoFactorSetupScreen filter picker to available methods only
  • Pass availableMethods from loaded status through to setup/switch views

#226 — Add 'Remember This Device' trusted-device option

  • Add trust_device opt-in field to Verify2FARequest (iOS + Android)
  • Add Verify2FAResponse carrying optional device_trust_token + expires_at
  • TwoFactorVerifyView / TwoFactorVerifyScreen show 'Remember this device' checkbox
  • iOS: persist trust token per-vault in Keychain (KeychainService.saveTrustToken)
  • Android: store token in TwoFactorUiState for the screen to persist securely
  • TrustDeviceRequest/Response models + /2fa/trust-device API endpoint

#224 — TOTP backup/recovery codes generation and display

  • Add BackupCodesResponse + BackupCodesStatus models (iOS + Android)
  • Add /2fa/backup-codes/generate and /2fa/backup-codes/status endpoints
  • Show backup codes screen automatically after initial TOTP setup verification
  • Codes displayed once only; user confirms they have saved them before proceeding
  • Non-fatal: failures to generate codes do not block setup completion
  • BackupCodesScreen composable (Android) + backupCodesView (iOS)

#225 — Switch 2FA method without fully disabling first

  • Add Switch2FARequest model + /2fa/switch endpoint (iOS + Android)
  • TwoFactorSwitchView (iOS) + TwoFactorSwitchScreen (Android): set up new method in pending state, verify it, then old method is torn down atomically — no gap
  • VaultDetailView/VaultDetailScreen: show 'Switch Method' when >1 method available
  • TwoFactorViewModel.switch2FAMethod / clearSwitchResponse

Housekeeping

  • Update .gitignore: exclude test snapshots, IDE files, build artifacts
  • Remove tracked Paparazzi snapshot PNGs from index (git rm --cached)
  • Add TwoFAImprovementsTests.swift (iOS) + TwoFAImprovementsTest.kt (Android)
  • Fix existing TwoFactorViewModelTest to use new Verify2FAResponse return type
  • Update shared/api-contract.md with full contracts for all four issues

Summary

Closes #224
Closes #225
Closes #226
Closes #227

Changes

Testing

Parity checklist

This project maintains a feature-parity table in PARITY.md that
tracks which features are implemented on iOS vs Android. Please answer the
questions below before requesting review.

  • This PR does not add, change, or remove any user-facing feature on either
    platform — no PARITY.md update needed.

    — OR —

  • This PR adds/changes/removes a user-facing feature. I have updated PARITY.md:

    • Updated the status symbol(s) for the affected row(s).
    • Added or updated "Notes" if the implementation is partial or has caveats.
    • Removed or updated any rows in the "Known gaps" table that this PR closes.

Related issues

…-protocol#226, ethos-protocol#227)

ethos-protocol#227 — Surface server-side 2FA method availability
- Add `available_methods` field to TwoFactorStatus (iOS + Android)
- Decode defensively: absent field defaults to all three (backward-compat)
- TwoFactorSetupView / TwoFactorSetupScreen filter picker to available methods only
- Pass availableMethods from loaded status through to setup/switch views

ethos-protocol#226 — Add 'Remember This Device' trusted-device option
- Add `trust_device` opt-in field to Verify2FARequest (iOS + Android)
- Add Verify2FAResponse carrying optional device_trust_token + expires_at
- TwoFactorVerifyView / TwoFactorVerifyScreen show 'Remember this device' checkbox
- iOS: persist trust token per-vault in Keychain (KeychainService.saveTrustToken)
- Android: store token in TwoFactorUiState for the screen to persist securely
- TrustDeviceRequest/Response models + /2fa/trust-device API endpoint

ethos-protocol#224 — TOTP backup/recovery codes generation and display
- Add BackupCodesResponse + BackupCodesStatus models (iOS + Android)
- Add /2fa/backup-codes/generate and /2fa/backup-codes/status endpoints
- Show backup codes screen automatically after initial TOTP setup verification
- Codes displayed once only; user confirms they have saved them before proceeding
- Non-fatal: failures to generate codes do not block setup completion
- BackupCodesScreen composable (Android) + backupCodesView (iOS)

ethos-protocol#225 — Switch 2FA method without fully disabling first
- Add Switch2FARequest model + /2fa/switch endpoint (iOS + Android)
- TwoFactorSwitchView (iOS) + TwoFactorSwitchScreen (Android): set up new method
  in pending state, verify it, then old method is torn down atomically — no gap
- VaultDetailView/VaultDetailScreen: show 'Switch Method' when >1 method available
- TwoFactorViewModel.switch2FAMethod / clearSwitchResponse

Housekeeping
- Update .gitignore: exclude test snapshots, IDE files, build artifacts
- Remove tracked Paparazzi snapshot PNGs from index (git rm --cached)
- Add TwoFAImprovementsTests.swift (iOS) + TwoFAImprovementsTest.kt (Android)
- Fix existing TwoFactorViewModelTest to use new Verify2FAResponse return type
- Update shared/api-contract.md with full contracts for all four issues
@drips-wave

drips-wave Bot commented Aug 26, 2026

Copy link
Copy Markdown

@katefominmoore23 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant