fix(oauth): clear the token-refresh backoff when a downstream token is saved - #7004
Open
pedrofrxncx wants to merge 1 commit into
Open
fix(oauth): clear the token-refresh backoff when a downstream token is saved#7004pedrofrxncx wants to merge 1 commit into
pedrofrxncx wants to merge 1 commit into
Conversation
…s saved Reconnecting a connection (POST /connections/:id/oauth-token) saves a fresh, never-failed token, but left any suppression window from the connection's previous dead token armed for up to 5 minutes, so a forced refresh right after reconnect could still be bounced by stale backoff state.
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.
Bug in
apps/api/src/oauth/token-refresh.ts/apps/api/src/api/routes/downstream-token.ts.refreshAndStorearms a per-connection exponential backoff (refreshBackoff, up toREFRESH_BACKOFF_CAP_MS= 5 minutes) after a failed refresh, so a broken upstream isn't hammered. That map is keyed only byconnectionIdand, until now, was only ever cleared on a successful refresh or on connection delete (#6980).Failure scenario: a connection's token refresh keeps failing (upstream blip, or a refresh_token that's dead but not classified
permanent) and arms the backoff window. The user then reconnects — the frontend callsPOST /connections/:id/oauth-tokenwith a brand-new, never-used access+refresh token. If a proxy request needs a forced refresh (e.g. it just got a 401) before the old backoff window naturally expires,refreshAndStoreshort-circuits on the stale backoff entry and returnsnullimmediately, without even attempting the new refresh_token. The connection looks broken for up to 5 minutes after the user did everything right to fix it.Fix: call
clearRefreshBackoff(connectionId)right after the token upsert in theoauth-tokenPOST route — a freshly saved token has never failed, so any suppression window is stale.Regression test: added
clears the token-refresh backoff entry on savetodownstream-token.integration.test.ts, mocking../../oauth/token-refresh(samemock.modulepattern asdelete.test.ts's equivalent case for #6980) and assertingclearRefreshBackoffis called with the connection id after a successful save.To confirm:
bun test apps/api/src/api/routes/downstream-token.integration.test.ts(needs a running Postgres — this laptop has none, so I verified withcd apps/api && bunx tsc --noEmit(clean) andbunx oxlinton both changed files (0 warnings/errors); full CI runs the integration suite.Does not touch
delete.ts/delete.test.ts(already covered by open PR #6980) — this is the reconnect/save path, not the delete path.Summary by cubic
Clears the token-refresh backoff when a downstream token is saved, so reconnects aren't blocked by a stale suppression window from the previous dead token.
POST /connections/:id/oauth-tokenroute now callsclearRefreshBackoffimmediately after the token upsert.Written for commit 568eb01. Summary will update on new commits.