From ac5ac0c2a794239d7598b144b2cda201f4d676dd Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Mon, 1 Jun 2026 03:00:13 -0300 Subject: [PATCH] fix(api): guard rotating providers in manual token-refresh route (Codex family-revocation) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit POST /api/providers/[id]/refresh was the last unguarded proactive-refresh entry point for rotating-refresh providers. The dashboard auto-refreshes every expiring connection on a page load (and an old cached frontend bulk-calls this endpoint), so each Codex account's single-use refresh_token got rotated; Auth0 then revoked the whole token family (openai/codex#9648) — every account but the last died with [403] readFile(ROUTE, "utf8"); + +test("manual refresh route imports rotationGroupFor", async () => { + const src = await read(); + assert.match( + src, + /import\s*\{[^}]*rotationGroupFor[^}]*\}\s*from\s*["'][^"']*refreshSerializer/, + "refresh route must import rotationGroupFor to detect rotating providers" + ); +}); + +test("manual refresh route skips proactive refresh for rotating providers BEFORE calling getAccessToken", async () => { + const src = await read(); + + const guardIdx = src.search(/rotationGroupFor\s*\(\s*[\w.]*provider[\w.]*\s*\)\s*!==\s*null/); + assert.ok( + guardIdx >= 0, + "refresh route must guard with `rotationGroupFor(provider) !== null` to skip rotating providers" + ); + + const getAccessTokenIdx = src.indexOf("getAccessToken("); + assert.ok(getAccessTokenIdx >= 0, "refresh route still calls getAccessToken for non-rotating providers"); + + assert.ok( + guardIdx < getAccessTokenIdx, + "the rotating-provider guard must run BEFORE getAccessToken so the rotating refresh_token is never exercised" + ); + + // The guard short-circuits with an early return (no token rotation). + const guardBlock = src.slice(guardIdx, getAccessTokenIdx); + assert.match( + guardBlock, + /return\b/, + "the rotating-provider guard must return early (defer to the reactive 401 path) instead of refreshing" + ); +});