fix(client): clear the native session on logout #385
No reviewers
Labels
No labels
area:auth
area:ci
area:db
area:infra
area:native
area:pwa
area:service
epic
feature
foundation
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
james/carol!385
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/native-logout-clears-session"
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?
The bug
On Android (any native build), tapping Log out sends you to the login screen — but close the app and reopen it and you're back on the chat screen, still signed in. Logging out never actually clears your credentials.
Cause
useLogout()(@carol/api-client) POSTs/api/auth/logoutand clears the query cache. That endpoint only revokes the webcarol_sessioncookie — native auth is the bearer access + refresh tokens in SecureStore (apps/client/lib/auth/storage.ts). Nothing ever calledclearTokens(), so on the next launch the proactive refresh (apps/client/lib/auth/refresh.ts→ensureFreshAccessToken) reads the surviving refresh token, mints a fresh pair, and the protected layout drops you straight back into the app. TheuseLogoutcomment even claimed "native consumers just discard their tokens" — but nothing did.Fix
New
apps/client/lib/auth/logout.ts→performLogout: fires the server logout and, on settle (success or failure — so an offline logout still ends the session), discards the stored bearer tokens and routes to/login.clearTokens()is a no-op on web, so the one path is correct for both targets. A failing keystore clear can't surface as an unhandled rejection (navigates regardless). BothSidebarlogout buttons (collapsed + expanded) now go through it, and the misleadinguseLogoutcomment is corrected to point here.Tests
apps/client/tests/logout.test.tspins the orchestration (mirrorsrefresh.test.ts's injected-deps style, no renderer): fires the mutation once + runs the drawer-close side effect; clears tokens then navigates on settle; still navigates if clearing throws.Follow-up (not in this PR)
This clears the session locally, which fixes the reported symptom completely. It does not revoke the refresh-token family server-side, so a token extracted from the device before logout stays valid until it expires (≤30 days). Worth a separate hardening pass —
apps/api/db/repositories/refresh-tokens.tsalready hasrevokeFamily();/api/auth/logoutwould need to accept the bearer/refresh token and revoke. Happy to do it next if you want it.🤖 Generated with Claude Code
📊 Test coverage
Patch coverage: no testable lines changed.
Overall (
app/,lib/,db/, excluding UI per ADR-0019):Soft thresholds per ADR-0019. Coverage is informational and does not block merge.