Fix/issues 200 201 202 203 - #335
Open
yvl4life wants to merge 4 commits into
Open
Conversation
OTPRateLimiter previously kept failureCount and cooldownSecondsRemaining as in-memory-only @published properties, so an app relaunch mid-cooldown reset a user's failed-attempt count and let an attacker bypass the throttle. Persist the failure count and an absolute cooldown deadline (not a remaining-seconds counter) to UserDefaults and rehydrate/resume the cooldown on init, mirroring Android's SavedStateHandle-backed TwoFactorViewModel (ethos-protocol#172). Closes ethos-protocol#201
TwoFactorSetupView lost all progress on process death mid-verification, forcing the user back through method selection and a brand-new code send even though a code had already been sent. Persist just the method and a "code sent" flag (never the OTP or the TOTP secret/provisioning URI) keyed by vault ID, with a 10-minute expiry so a stale session isn't restored once the underlying code has almost certainly expired server-side. Closes ethos-protocol#202
8d8d59d reconciled two duplicate, conflicting offline check-in queue systems (CheckInQueue/CheckInSyncService vs. PendingCheckInStore/ CheckInSyncTask) after the dead one shipped silently with zero test coverage of either. Add behavioral tests for PendingCheckInStore and CheckInSyncTask, plus an assertion that CheckInSyncTask's default store is PendingCheckInStore.shared, so a reintroduced second queue would be caught. Document the canonical queue path in README's Offline Support section. Closes ethos-protocol#203
…ssociations PARITY.md marked cross-device sync as an Android gap: iOS syncs vault ID -> passkey credential ID mappings across devices via ICloudSyncService (NSUbiquitousKeyValueStore), Android had no equivalent. Add VaultAssociationStore, a SharedPreferences-backed store for the same non-secret mapping, and include only that file in Android's Auto Backup for Apps (data_extraction_rules.xml / backup_rules.xml) so it restores transparently on a new device signed into the same Google account — auth tokens (EncryptedSharedPreferences) and the offline queue database are explicitly excluded. Clear local associations on sign-out, mirroring iOS's behavior of leaving the synced copy for other devices intact. Closes ethos-protocol#200
|
@yvl4life 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! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes four Stellar Wave parity/hardening issues, each in its own commit:
#201 — Persist OTP rate-limiter state across process death (iOS)
OTPRateLimiter kept failureCount/cooldownSecondsRemaining in-memory only, so an app relaunch mid-cooldown reset a user's failed-attempt count — letting an attacker bypass the throttle. Now persists the failure count and an absolute cooldown deadline (not a countdown) to UserDefaults and rehydrates on init, mirroring Android's SavedStateHandle-backed TwoFactorViewModel (#172).
#202 — Restore in-flight 2FA verify screen state (iOS)
TwoFactorSetupView lost all progress on process death mid-verification, forcing users back through method selection and a brand-new code send. Added PendingTwoFactorSessionStore, which persists only the selected method and a "code sent" flag (never the OTP or TOTP secret/provisioning URI) keyed by vault ID, with a 10-minute expiry so stale sessions aren't restored.
#203 — Regression guard for the duplicate check-in queue (iOS)
Commit 8d8d59d reconciled two duplicate, conflicting check-in queue implementations that had zero test coverage. Added behavioral tests for PendingCheckInStore/CheckInSyncTask, plus an assertion that CheckInSyncTask's default store is PendingCheckInStore.shared. Documented the canonical queue path in README's Offline Support section.
#200 — Cross-device backup/restore for Android
iOS syncs vault-ID → passkey-credential-ID mappings across devices via ICloudSyncService (NSUbiquitousKeyValueStore); Android had no equivalent. Added VaultAssociationStore, a dedicated SharedPreferences file included in Android's Auto Backup for Apps (data_extraction_rules.xml / backup_rules.xml), so it restores transparently on a new device signed into the same Google account — no new cloud API or consent flow needed. Only the non-secret mapping is ever backed up; auth tokens (EncryptedSharedPreferences) and the offline queue database are explicitly excluded. Cleared on sign-out, leaving the synced copy for other devices intact.
Notes / follow-ups
#200: wiring VaultAssociationStore.save() into the actual vault-creation flow (mirroring iOS's per-vault save(vaultID:credentialID:) calls) needs a persisted account-level credential ID on Android, which doesn't currently exist outside the passkey registration ceremony. Left as a natural follow-up rather than adding new persistence to the auth/token layer in this PR.
Test plan
iOS: run OTPRateLimiterTests, PendingTwoFactorSessionStoreTests, PendingCheckInStoreTests, CheckInSyncTaskTests
Android: run AuthViewModelTest, VaultAssociationStoreTest
Manually verify OTP cooldown survives a force-quit mid-cooldown
Manually verify 2FA setup resumes at the verify step after a force-quit post-code-send
Verify Android backup: adb shell bmgr backupnow com.ethosprotocol, reinstall, confirm vault_associations_sync restores while auth state does not
Closes #200
Closes #201
Closes #202
Closes #203