mirror of
https://github.com/Nezumi-2711/9router.git
synced 2026-09-22 13:38:31 +00:00
fix(codex): avoid bare-email OAuth dedup (#2477)
Only update an existing Codex OAuth row when both rows share the same chatgptAccountId, so a second Codex login no longer overwrites the first account's rotated token pair. Also fall back to workspaceId || chatgptAccountId || accountId for the chatgpt-account-id header.
This commit is contained in:
@@ -199,10 +199,17 @@ export class CodexExecutor extends BaseExecutor {
|
|||||||
headers["session_id"] = this._currentSessionId || credentials?.connectionId || "default";
|
headers["session_id"] = this._currentSessionId || credentials?.connectionId || "default";
|
||||||
// Identify client type to Codex backend (matches official codex CLI)
|
// Identify client type to Codex backend (matches official codex CLI)
|
||||||
if (!headers["originator"]) headers["originator"] = "codex_cli_rs";
|
if (!headers["originator"]) headers["originator"] = "codex_cli_rs";
|
||||||
// Workspace binding header — improves account scope + cache affinity
|
// Account/workspace binding header — required when multiple Codex accounts
|
||||||
const workspaceId = credentials?.providerSpecificData?.workspaceId || credentials?.providerSpecificData?.chatgptAccountId;
|
// are configured. OAuth import stores ChatGPT account ID as chatgptAccountId;
|
||||||
if (typeof workspaceId === "string" && workspaceId && !headers["ChatGPT-Account-ID"]) {
|
// older/custom rows may use workspaceId/accountId. Prefer explicit workspaceId
|
||||||
headers["ChatGPT-Account-ID"] = workspaceId;
|
// but fall back to chatgptAccountId so requests don't cross-bind to the wrong
|
||||||
|
// OpenAI account and surface as token_invalid after adding another account.
|
||||||
|
const accountId =
|
||||||
|
credentials?.providerSpecificData?.workspaceId ||
|
||||||
|
credentials?.providerSpecificData?.chatgptAccountId ||
|
||||||
|
credentials?.providerSpecificData?.accountId;
|
||||||
|
if (typeof accountId === "string" && accountId && !headers["ChatGPT-Account-ID"]) {
|
||||||
|
headers["ChatGPT-Account-ID"] = accountId;
|
||||||
}
|
}
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,18 @@ export async function createProviderConnection(data) {
|
|||||||
const incomingWs = data.providerSpecificData?.chatgptAccountId;
|
const incomingWs = data.providerSpecificData?.chatgptAccountId;
|
||||||
existing = all.find(c => {
|
existing = all.find(c => {
|
||||||
if (c.authType !== "oauth" || c.email !== data.email) return false;
|
if (c.authType !== "oauth" || c.email !== data.email) return false;
|
||||||
// Workspace providers (Codex) use workspace ID when both sides have it
|
|
||||||
|
// Codex/OpenAI can issue multiple OAuth grants for the same email.
|
||||||
|
// Refresh tokens are rotated single-use; collapsing a new login onto an
|
||||||
|
// existing bare-email row overwrites the first account's token pair and
|
||||||
|
// makes it look "invalid" after adding a second account. Only update an
|
||||||
|
// existing Codex row when both rows expose the same ChatGPT account ID.
|
||||||
|
if (data.provider === "codex") {
|
||||||
|
const existingWs = c.providerSpecificData?.chatgptAccountId;
|
||||||
|
return !!incomingWs && !!existingWs && incomingWs === existingWs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Workspace providers use workspace ID when both sides have it
|
||||||
const existingWs = c.providerSpecificData?.chatgptAccountId;
|
const existingWs = c.providerSpecificData?.chatgptAccountId;
|
||||||
if (incomingWs && existingWs) return incomingWs === existingWs;
|
if (incomingWs && existingWs) return incomingWs === existingWs;
|
||||||
if (incomingWs && !existingWs) return false;
|
if (incomingWs && !existingWs) return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user