fix(auth): wipe account data at login boundary on DID change (closes #31) #36
No reviewers
Labels
No labels
auth
bug
composer
correctness
database
durability
enhancement
feeds
interactions
notifications
performance
reliability
safety
security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
starsetbyte/peregrine!36
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/login-boundary-account-wipe"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Closes the remaining leak vector from #31 (Multi-account support). The account-data wipe from PR #30 only fired in
AuthRepository.logout(), but three session-establishing paths bypassed it:TokenAuthenticatorcallssessionManager.clearSession()directly on refresh failure (no wipe).OAuthLoginViewModel.completeLogin()calledsessionManager.saveOAuthSession()directly (bypassedAuthRepository).AuthRepository.login()(app-password) saved the session without comparing against the previous account.Result: token-expiry forced logout → different account logs in → sees the previous account's cached timeline/feeds/drafts/notifications.
Fix — login-boundary chokepoint
AccountDidTracker(new): persists the last-known DID in its own SharedPreferences file (peregrine_account_boundary) that survivesSessionManager.clearSession(). Without this, a forced logout would erase the last-known DID and the next different-account login wouldn't trigger a wipe.AuthRepository.establishSession(did, saveSession)(new private): when the new DID differs from the tracker's last-known DID, wipes account-bound data before saving the new session. Bothlogin()and the newcompleteOAuthLogin(session)route through it.OAuthLoginViewModelnow callsauthRepository.completeOAuthLogin(session)instead ofsessionManager.saveOAuthSession()directly — the OAuth path no longer bypasses the boundary.logout()clears the tracker (logout already wiped; the next login should start fresh, not be treated as a switch).Scope note
This closes the leak-vector / "no account sees another's data" acceptance criterion of #31. The other criterion — per-DID data scoping (preserving each account's cache across switches without re-download) — remains a larger follow-up (separate DB/DataStore per DID or
accountDidcolumns). That's a schema-level change better tracked as its own issue; this PR makes the safety guarantee airtight first.Test plan
AuthRepositoryTest(7 new tests, 9 total):OAuthLoginViewModelTestupdated for the new constructor (verifiesauthRepository.completeOAuthLoginis called)assembleDebugbuilds (Hilt wiring verified —OAuthLoginViewModelconstructor changed)💘 Generated with Crush