fix: only terminate the session on 400 invalid_grant - #57
Conversation
🦋 Changeset detectedLatest commit: ba721c5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Extended to cover a third case from a parallel review: That also removes the second |
|
Self-review follow-up: a validator shared across both flows may throw |
e0375d1 to
bd6c767
Compare
Non-OAuth error bodies and 400 invalid_request are not confirmation that the refresh token is gone. These three cases fail against the current allowlist, which only preserves the session for structured OAuth errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Invert the refresh catch into an allowlist so undecodable error bodies (proxy HTML, empty 5xx) and invalid_request propagate instead of nilling the session. Preserving is now the default for anything unrecognized. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
TokenRefreshOptions documents a thrown error as "unable to resolve the validity", e.g. an offline client, but the refresh path nilled the session for it just the same. Only an explicit false now terminates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
TokenAuthorizeOptions directs validators to throw tokenInvalid, so a validator shared across both flows may signal invalidity that way rather than returning false. Without this, that throw would preserve the session and retry a definitively invalid response indefinitely. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
a55b10d to
ba721c5
Compare
Follow-on to #53, which narrowed session termination on token refresh but still defaulted to terminate: only
OAuth.Errors.oauthErrorwas inspected, so anything else fell through toreturn niland signed the user out.Two cases that don't confirm the refresh token is dead still terminated the session:
HTTPResponseError.unsuccessful, notoauthError. Probably the most common transient failure in practice.400 invalid_request—processGenericAccessTokenremaps this before theoauthErrorcase; per RFC 6749 it means a malformed request, not a revoked grant.Inverts the catch into an allowlist: only
400 invalid_grantreturns nil, everything else propagates. Preserving is now the default for unrecognized errors.Stacked on #51 — merge after it lands. Based on
feat/token-revocationwithmainmerged in, so CI runs the true post-stack state; the error assertions rely on GermConvenience 0.3.0, which that branch already pins.Tests: three new cases in
RefreshErrorTests(HTML 503, empty-body 502, 400 invalid_request), added in a separate commit that fails against the pre-fix code. Full suite green.🤖 Generated with Claude Code