Skip to content

Commit 66780c6

Browse files
committed
fix(oauth): adopt newer disk credentials before cleanup
1 parent 5ca2172 commit 66780c6

2 files changed

Lines changed: 12 additions & 6 deletions

File tree

src/oauth/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -786,10 +786,6 @@ export async function refreshAnthropicAccountWithLock(
786786
const account = getAccountSet(provider)?.accounts.find(candidate => candidate.id === accountId);
787787
const generation = credentialGeneration(stored);
788788
let pendingIntent = readOAuthRefreshIntent(provider, accountId);
789-
if (pendingIntent?.cleanupPending && pendingIntent.generation === generation) {
790-
resumeAnthropicRefreshIntentCleanup(provider, accountId, pendingIntent);
791-
pendingIntent = undefined;
792-
}
793789
const disk = newerClaudeCredential(stored, now());
794790
if (disk) {
795791
const outcome = await mergeAccountCredential(provider, accountId, disk, {
@@ -806,6 +802,10 @@ export async function refreshAnthropicAccountWithLock(
806802
if (pendingIntent) clearAnthropicRefreshIntentBestEffort(provider, accountId, pendingIntent);
807803
return disk.access;
808804
}
805+
if (pendingIntent?.cleanupPending && pendingIntent.generation === generation) {
806+
resumeAnthropicRefreshIntentCleanup(provider, accountId, pendingIntent);
807+
pendingIntent = undefined;
808+
}
809809
if (!pendingIntent?.uncertain && pendingIntent?.generation === generation) {
810810
if (pendingIntent.staleOwner) throw new OAuthTokenRefreshStaleError();
811811
if (deps.replacedStaleFlight && pendingIntent.flightId === deps.replacedStaleFlight.flightId) {

tests/oauth-refresh.test.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,8 +1210,13 @@ describe("oauth refresh hardening", () => {
12101210
await saveCredential("anthropic", { access: "old", refresh: "rt-old", expires: 1, source: "local-cli" });
12111211
const id = getAccountSet("anthropic")!.activeAccountId;
12121212
const stored = getAccountCredential("anthropic", id)!;
1213-
writeOAuthRefreshIntent("anthropic", id, credentialGeneration(stored));
1214-
expect(readOAuthRefreshIntent("anthropic", id)).toBeDefined();
1213+
const pending = writeOAuthRefreshIntent("anthropic", id, credentialGeneration(stored));
1214+
expect(markOAuthRefreshIntentCleanupPending(
1215+
"anthropic",
1216+
id,
1217+
pending,
1218+
"definitive-rejection",
1219+
)).toMatchObject({ cleanupPending: "definitive-rejection" });
12151220

12161221
seedClaudeCredentials("disk", "rt-new", Date.now() + 3600_000);
12171222
const mock = mockRefreshFetch([new Response("unexpected", { status: 500 })]);
@@ -1234,6 +1239,7 @@ describe("oauth refresh hardening", () => {
12341239
expect(mock.count()).toBe(0);
12351240
expect(getCredential("anthropic")?.refresh).toBe("rt-new");
12361241
expect(getAccountSet("anthropic")!.accounts[0]!.needsReauth).toBeUndefined();
1242+
expect(readOAuthRefreshIntent("anthropic", id)?.cleanupPending).toBe("definitive-rejection");
12371243
});
12381244

12391245
test("marked Anthropic local-cli account lazily recovers only from a newer disk generation", async () => {

0 commit comments

Comments
 (0)