Merge pull request #1622 from jesieleo/fix/codex-oauth-live-credentials

fix(codex): 同步本地登录的最新 OAuth 凭据
This commit is contained in:
musi 2026-08-03 13:20:24 +08:00 committed by GitHub
commit 7a51e892cc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 46 additions and 8 deletions

View file

@ -448,9 +448,9 @@ function withCodexOauthRuntimeDefaults(providerPlugins: unknown[]): unknown[] {
const codexOauth = plugin.codexOauth;
const nextCodexOauth = {
...codexOauth,
...(!hasOwn(codexOauth, "accountId") && !hasOwn(codexOauth, "account_id") && codexAuth?.accountId
? { accountId: codexAuth.accountId }
: {})
...(codexAuth?.accessToken ? { accessToken: codexAuth.accessToken } : {}),
...(codexAuth?.refreshToken ? { refreshToken: codexAuth.refreshToken } : {}),
...(codexAuth?.accountId ? { accountId: codexAuth.accountId } : {})
};
const nextPlugin: Record<string, unknown> = {
...plugin,
@ -787,8 +787,3 @@ function addProviderNameVariants(names: Set<string>, providerName: string | unde
names.add(providerName.slice(0, capabilitySeparatorIndex));
}
}
function hasOwn(value: Record<string, unknown>, key: string): boolean {
return Object.prototype.hasOwnProperty.call(value, key);
}

View file

@ -96,6 +96,49 @@ test("Codex OAuth plugins retain the default base URL after runtime identity nor
assert.equal(compiled.providers[0].baseurl, codexDefaultBaseUrl);
});
test("Codex OAuth plugins prefer live login credentials over imported snapshots", async (t) => {
const home = useTemporaryCodexHome(t, "ccr-codex-runtime-live-credentials-");
fs.mkdirSync(path.join(home, ".codex"), { recursive: true });
fs.writeFileSync(path.join(home, ".codex", "auth.json"), JSON.stringify({
tokens: {
access_token: "access-live",
account_id: "acct-live",
refresh_token: "refresh-live"
}
}));
const config = createDefaultAppConfig();
config.providerPlugins = [{
codexOauth: {
accessToken: "access-imported",
accountId: "acct-imported",
refreshToken: "refresh-imported"
},
key: "ccr-local-agent-codex-api-codex-oauth",
providerName: "Codex API"
}];
config.Providers = [{
api_base_url: codexDefaultBaseUrl,
api_key: "ccr-local-agent-login",
id: "codex-api",
models: ["gpt-5.5"],
name: "Codex API",
type: "openai_responses"
}];
const compiled = await compileCoreGatewayConfig(
config,
"raw-trace-token",
"billing-usage-token",
"core-auth-token"
);
const codexPlugin = compiled.providerPlugins.find((item) => item.key === "ccr-local-agent-codex-api-codex-oauth");
assert.equal(codexPlugin.codexOauth.accessToken, "access-live");
assert.equal(codexPlugin.codexOauth.refreshToken, "refresh-live");
assert.equal(codexPlugin.codexOauth.accountId, "acct-live");
});
test("Codex local providers synthesize OAuth plugins when persisted plugins are missing", async (t) => {
const home = useTemporaryCodexHome(t, "ccr-codex-runtime-missing-plugins-");
fs.mkdirSync(path.join(home, ".codex"), { recursive: true });