Skip to content

fix(auth): report a rotation that never reached the config - #116

Merged
yurenju merged 1 commit into
mainfrom
fix/log-token-persist-skip
Aug 18, 2026
Merged

fix(auth): report a rotation that never reached the config#116
yurenju merged 1 commit into
mainfrom
fix/log-token-persist-skip

Conversation

@yurenju

@yurenju yurenju commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Problem

onTokenRefresh writes a freshly rotated token pair back into the account slot. When the slot is absent it returns early and says nothing.

That silence is expensive. The server has already invalidated the token the process still holds, so the next refresh presents a superseded one. The server reads that as reuse, revokes the whole token family, and every client on that account is signed out. The operator sees a forced sign-out with nothing in any log that points at the write that was skipped.

We hit this in production on 2026-08-15: two accounts revoked 0.1s apart, both presenting a refresh token that had been rotated away 59 minutes earlier. Sync for both folders then stayed down for two days before anyone noticed. The server-side record is good (family id, gap, user agent), but nothing on the client says whether the rotation an hour earlier was ever saved, so the cause is still open.

Change

Track whether the mutator found the slot, and write one line to stderr when it did not:

wspc: token rotated but not saved: no account 'a@x.com' in env 'prod'; the next refresh will present a superseded token and may sign you out

Behavior is otherwise unchanged. This does not fix the revocation; it makes the suspected cause observable so the next occurrence is diagnosable.

Notes

  • The message carries no token material.
  • It does not match wspc-drive's isAuthLikeMessage, so a binding is not flipped to "sign in required". That is correct here: auth is still valid at this point.

Test

test/load-sdk-client-multi.test.ts removes the account slot after the interceptor resolves the account but before the rotation lands, then asserts stderr names the account and the env and does not leak the new token.

Full suite: 666 tests pass, typecheck clean.

A refresh that the server accepts but the config write skips is the worst
of both worlds: the server has already invalidated the token still held in
memory, so the next refresh presents a superseded one, reads as reuse, and
revokes the whole family. The account slot going missing between resolving
the account and writing the rotation back took that path silently, leaving
a forced sign-out with nothing in the logs pointing at the cause.

Track whether the mutator found the slot and write a line to stderr when it
did not. Behavior is otherwise unchanged; this only makes the existing skip
visible.
@yurenju
yurenju merged commit 81c6e9d into main Aug 18, 2026
2 checks passed
@yurenju
yurenju deleted the fix/log-token-persist-skip branch August 18, 2026 04:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant