fix(THU-580): cache Better Auth session so app boots offline#954
Conversation
Semgrep Security ScanNo security issues found. |
|
Preview environment destroyed 🧹 Stack |
PR Metrics
Updated Mon, 06 Jul 2026 20:04:26 GMT · run #2198 |
1bc93c9 to
beab0c6
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit beab0c6. Configure here.
4676ae6 to
529eebd
Compare
529eebd to
df5b928
Compare
There was a problem hiding this comment.
🔭 thunder-deep-review (advisory)
Complements the other bots — surfaces only what they did not flag. Never approves, never requests changes, never gates merge.
head: df5b928bb810 · mode: single · deferred 2 item(s) already reported by other bots (best-effort dedup)
| clearCachedSession() | ||
| return | ||
| } | ||
| const sessionAtom = client.$store.atoms.session |
There was a problem hiding this comment.
📐 Convention — Reaching into Better Auth's $store.atoms.session internals
Both the seed and the persist subscription poke client.$store.atoms.session directly rather than going through Better Auth's public useSession/getSession surface. The tests even cast fake clients through as unknown to satisfy the shape, which is a hint that this path isn't well-typed for us. This is the same class of fragility we already flag for the powersync-web-internal alias — if a Better Auth upgrade renames or restructures the atom store, this breaks silently with no TypeScript error and the offline-boot feature just quietly stops working. Could we add a comment pinning the Better Auth version this shape was verified against, so an upgrade prompts a re-check?

Closes THU-580.
Better Auth's
useSessionneeds a/get-sessionround-trip to populatedata. Offline at boot that fetch fails,datastaysnull, anduseAuthGateredirects authenticated routes to/waitlist— the user is stuck on the login screen until they reconnect.Cache the last successful session payload in
localStorageand seedclient.\$store.atoms.sessionon auth-client creation.useAuthQuery.onErrorpreserves non-nulldataon non-401 errors, so the cached value survives the failing offline fetch. Better Auth's own online listener replaces it with fresh server data as soon as the network returns. Cache is cleared on 401 and onclearLocalData(logout / wipe).Note
Medium Risk
Touches auth boot path and stores richer profile data in localStorage alongside the token; invalidation on 401/logout/wipe and expiry checks limit stale-session risk.
Overview
Fixes offline startup for users who already have a bearer token: the last successful session is stored in localStorage and used to seed Better Auth’s session atom before
/get-sessionruns, so protected routes are not treated as logged-out when the network is down.session-cacheadds read/write/clear plusisCachedSessionValid(futuresession.expiresAtonly).hydrateSessionFromCacheruns when the auth client is created (token + valid cache required);subscribeSessionCachePersistmirrors atom updates that include both user and session, with unsubscribe on client swap.The cache is cleared on 401,
clearLocalData, and cross-tab token rotation (before reload) so stale or wrong-user data is not reused offline.Reviewed by Cursor Bugbot for commit df5b928. Bugbot is set up for automated code reviews on this repo. Configure here.