From 3563cc4df6c6c002d8ef04f0fd3838ec5cc32118 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Tue, 17 Mar 2026 22:47:51 +0100 Subject: [PATCH] fix(ai): resolve codex oauth callback immediately closes #2316 --- packages/ai/src/utils/oauth/openai-codex.ts | 28 +++++++++++---------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/ai/src/utils/oauth/openai-codex.ts b/packages/ai/src/utils/oauth/openai-codex.ts index 820168d9..0d8c1a83 100644 --- a/packages/ai/src/utils/oauth/openai-codex.ts +++ b/packages/ai/src/utils/oauth/openai-codex.ts @@ -213,8 +213,17 @@ function startLocalOAuthServer(state: string): Promise { if (!_http) { throw new Error("OpenAI Codex OAuth is only available in Node.js environments"); } - let lastCode: string | null = null; - let cancelled = false; + + let settleWait: ((value: { code: string } | null) => void) | undefined; + const waitForCodePromise = new Promise<{ code: string } | null>((resolve) => { + let settled = false; + settleWait = (value) => { + if (settled) return; + settled = true; + resolve(value); + }; + }); + const server = _http.createServer((req, res) => { try { const url = new URL(req.url || "", "http://localhost"); @@ -237,7 +246,7 @@ function startLocalOAuthServer(state: string): Promise { res.statusCode = 200; res.setHeader("Content-Type", "text/html; charset=utf-8"); res.end(SUCCESS_HTML); - lastCode = code; + settleWait?.({ code }); } catch { res.statusCode = 500; res.end("Internal error"); @@ -250,17 +259,9 @@ function startLocalOAuthServer(state: string): Promise { resolve({ close: () => server.close(), cancelWait: () => { - cancelled = true; - }, - waitForCode: async () => { - const sleep = () => new Promise((r) => setTimeout(r, 100)); - for (let i = 0; i < 600; i += 1) { - if (lastCode) return { code: lastCode }; - if (cancelled) return null; - await sleep(); - } - return null; + settleWait?.(null); }, + waitForCode: () => waitForCodePromise, }); }) .on("error", (err: NodeJS.ErrnoException) => { @@ -269,6 +270,7 @@ function startLocalOAuthServer(state: string): Promise { err.code, ") Falling back to manual paste.", ); + settleWait?.(null); resolve({ close: () => { try {