fix(client): complete Android OAuth on cold start (#300) #383
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!383
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "300-oauth-cold-start"
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?
Closes #300
PR #298 fixed the warm-path OAuth return, but a true cold start — the OS kills the app while the system browser is foreground — lost the in-memory waiter, so the return deep link was queued but never drained. The user landed back on
/loginunauthenticated.What changed
lib/auth/oauthDeepLink.ts:drainOauthDeepLink()— an atomic read-and-clear of the single pending slot.lib/auth/oauthColdStart.ts(new): pure, node-testablecompleteOauthColdStartwith every side effect injected (drain, POST/api/auth/token, store tokens).app/_layout.tsx: the existingLinking.getInitialURL()handler now runs the cold-start completion and, on success, mirrorslogin.tsx(invalidateauth.me→router.replace("/chat")). Runs only on thegetInitialURLbranch, never on the warmaddEventListenerpath.Idempotency
A live warm waiter consumes the payload inline (pending stays
null→ drain no-ops); a cold start has no waiter (pending is set → drain + exchange exactly once). The init token is drained before the network call, so a failed exchange leaves nothing wedged.login.tsx(warm path) is deliberately untouched and is never double-exchanged.Verification
/chatsigned in. Re-confirm the warm path is not double-exchanged.Merge note
Independent of #236/#239 — touches only the OAuth files +
_layout.tsx(notlogin.tsxorserver-setup.tsx). No conflicts.🤖 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.