Repository navigation
Fix qc throttling and 'session expired': Bearer auth for events, no refresh storm (0.5.1, qc 0.4.2) - #284
Merged
Conversation
…efresh storm (0.5.1, qc 0.4.2) - authenticateRequest's token client called setSession() with an empty refresh token, which auth-js rejects, so every Bearer request through it (qc's /api/events) was a 401. Use a client carrying the Authorization header and getUser(token). - qc reconnected /api/events on 401 straight after a refresh with no backoff, rotating refresh tokens in a tight loop (GoTrue logged several per 60ms) until the session died. Now one refresh per rejection, then stop. Parallel 401s share one refresh; a stale-token 401 just retries. - qc waits out 429s (Retry-After, which the middleware now sends). - The TUI no longer loads 40 chats on start to join their live rooms: the events stream joins all of the user's conversations on connect. - Closing one SSE connection no longer drops the user from every room while another of their connections is open. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ThreatCrush Security Scan13 finding(s) MEDIUM: 9 | LOW: 4
Snippets are redacted; ThreatCrush never prints matched credential material. |
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.
Anthony: "qc gets errors loading, once got throttled and another said session has expired".
Root cause:
createSupabaseServerClientWithTokencalledsetSession({ access_token, refresh_token: '' }). auth-js 2.74 throwsAuthSessionMissingErrorfor an empty refresh token, so every Bearer-authenticated request throughauthenticateRequestreturned 401 (29[SSE] Authentication failedin the live logs). Browsers use cookies, so only qc, MCP and API clients were affected.qc then refreshed and reconnected
/api/eventsimmediately, with no backoff. GoTrue loggedtoken_refreshed/token_revokedfor Anthony's account several times within 60 ms. Each refresh is an /api request, which pushed past the 60/min per-IP limit (the throttle), and the rotation eventually killed the session ("session has expired").Fixes
Authorizationheader (RLS still sees the user), and the route callsgetUser(token).Retry-After, which the middleware now sends (10 s)./api/eventsjoins all of the user's conversations on connect.sseManager.removeConnectiononly removes the user from rooms when their last connection closes. Before, qc reconnecting silenced the same user's open browser tab.Tests: 666/666, with new tests for qc 429 handling, single refresh and stopping the events loop, the token getUser call, and SSE rooms.
next buildpasses.🤖 Generated with Claude Code