Repository navigation
fix(auth): only end a session when the gateway rejects the credentials - #27
Open
spacedevin wants to merge 1 commit into
Open
spacedevin wants to merge 1 commit into
spacedevin wants to merge 1 commit into
Conversation
Refresh and user-load failures both cleared token storage unconditionally, so a request that never reached the gateway — offline, DNS, a connection reset — or one it answered with a 5xx signed the user out and made them log in again. Neither says anything about whether the credentials are still valid. The callers could not do better: refreshAccessToken and getUserInfo threw a bare Error with no status, and the `await response.json()` in the error path threw on a non-JSON body (an HTML 502 page), masking the status entirely. - AuthError carries the HTTP status and the OAuth error code, and is thrown only when the gateway actually answered. - isCredentialFailure() is true for 400/401/403 and invalid_grant / invalid_token / unauthorized_client, and false for 5xx, 429 and every network rejection. - The provider clears storage only on a credential failure. On a transient one it keeps the tokens, and loadUser falls back to the cached user so an offline page load no longer looks like a sign-out.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reported as "I am constantly having to relog."
Cause
refreshAccessTokenandgetUserInfofailures both cleared token storage unconditionally. So a request that never reached the gateway — offline, DNS, a connection reset, a sleeping laptop — or one the gateway answered with a 5xx signed the user out. Neither of those says anything about whether the credentials are still valid.The callers could not have done better with what they were given:
Errorwith no status attached, so "the refresh token is revoked" and "the wifi dropped" arrived identical;await response.json()on the failure body, which itself throws on a non-JSON response (an HTML 502 page from a proxy), masking the status entirely.Fix
AuthErrorcarries the HTTP status and the OAuth error code, and is thrown only when the gateway actually answered. A network rejection stays a network rejection.isCredentialFailure()is true for400/401/403andinvalid_grant/invalid_token/unauthorized_client; false for5xx,429and every network rejection.loadUserfalls back to the cached user — so an offline page load no longer looks like a sign-out.This is the narrow reading on purpose: anything the gateway did not explicitly reject is treated as "try again later", because the cost of being wrong in that direction is a retry, and the cost of being wrong in the other direction is the bug being reported.
Verification
74 pass / 0 failacross 11 files, including a newsrc/lib/__tests__/credential-failure.test.tscovering each status and error code, non-JSON error bodies, and network rejections.docs/ADVANCED.mddocumentsAuthErrorand the retained-session behaviour.