[PM-35118] fix: Prevent vault timeout from re-firing for already-soft-logged-out accounts#2571
[PM-35118] fix: Prevent vault timeout from re-firing for already-soft-logged-out accounts#2571morganzellers-bw wants to merge 4 commits intomainfrom
Conversation
…-logged-out accounts
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2571 +/- ##
========================================
Coverage 87.20% 87.21%
========================================
Files 1894 1895 +1
Lines 167519 167756 +237
========================================
+ Hits 146087 146302 +215
- Misses 21432 21454 +22 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
🤖 Bitwarden Claude Code ReviewOverall Assessment: APPROVE Reviewed the one-line fix in Code Review DetailsNo findings. |
🎟️ Tracking
PM-35118
📔 Objective
After setting Vault Timeout to Immediate + Log Out, the account is soft-logged-out on foreground (PM-11472 design, access token removed but account kept in state for email pre-fill). However,
checkSessionTimeoutswas re-firing the timeout on every subsequent foreground event becausehasPassedSessionTimeoutalways returnstruefor.immediately(0 seconds elapsed ≥ 0). This caused the app to navigate the user back to the landing screen even while they were mid-way through re-authenticating on the login screen.Fix: Add
&& !account.isLoggedOutto theshouldTimeoutguard incheckSessionTimeouts.account.isLoggedOutis!isAuthenticated, which (after PM-35285) correctly returnstruefor soft-logged-out accounts. This prevents the timeout from re-firing for accounts that are already logged out.Test corrections included:
lockAccount,logoutAccount) neededstateService.isAuthenticated[userId] = true—MockStateServicedefaultsisAuthenticatedtofalse, so without it the accounts appeared already-logged-out and the timeout was skipped.timedOut_activeAccount_handleActiveUser) was vacuously passing because the closure assertion was never reached; hardened with an explicithandleActiveUserCalledflag.didTimeout_sessionExpired_logout) was asserting.landingbut production actually returns.landingSoftLoggedOut— the old assertion only passed becauseauthRepository.activeAccountwas unset, forcinggetAccount()through the catch path.Screenshots
Before & After Videos
pm-35118-after-720.mov
pm-35118-before-720.mov