fix(codex): durable OAuth refresh lifecycle

Add shared OAuth credential lifecycle manager with provider-aware refresh
decisions. Implement CodexExecutor.refreshCredentials so 401/403 retry
refresh works for Codex, track lastRefreshAt and refresh before the
upstream stale-token window, preserve omitted idToken, and add
per-connection single-flight refresh to avoid refresh-token rotation races.

Merged from PR #1664.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Kevin Le
2026-06-06 11:04:36 +07:00
committed by decolua
co-authored by Cursor
parent 38b73bfc6b
commit c233c7c8fc
15 changed files with 484 additions and 140 deletions
+4 -1
View File
@@ -225,9 +225,12 @@ const PROVIDERS = {
const mapped = {
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
idToken: tokens.id_token,
expiresIn: tokens.expires_in,
lastRefreshAt: new Date().toISOString(),
};
if (info.email) mapped.email = info.email;
const email = info.email || extractEmailFromAccessToken(tokens.access_token);
if (email) mapped.email = email;
if (info.chatgptAccountId || info.chatgptPlanType) {
mapped.providerSpecificData = {
chatgptAccountId: info.chatgptAccountId,
+1 -1
View File
@@ -54,6 +54,7 @@ export class CodexService extends OAuthService {
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
expiresIn: tokens.expires_in,
lastRefreshAt: new Date().toISOString(),
}),
});
@@ -141,4 +142,3 @@ export class CodexService extends OAuthService {
}
}
}