fix(openai): return structured failure for malformed OAuth token JSON (#122962)

* fix(openai): return structured failure for malformed OAuth token JSON

A truncated or otherwise malformed token response from auth.openai.com
made response.json() throw a raw SyntaxError. The exchange path called
the shared parser outside its try/catch, so the exception escaped
exchangeOpenAIAuthorizationCode and crashed the login flow instead of
surfacing a structured failure. Catch parse errors inside
readOpenAITokenResponse so both exchange and refresh return a failed
TokenResult.

* ci: retrigger checks after concurrency-cancelled lint run
This commit is contained in:
wanyongstar
2026-08-23 03:00:33 +08:00
committed by GitHub
parent 2eecf3d3f2
commit 0a35d54846
2 changed files with 33 additions and 1 deletions
@@ -356,6 +356,30 @@ describe("OpenAI Codex OAuth flow", () => {
});
});
it.each([
{
operation: "exchange" as const,
run: () =>
exchangeOpenAIAuthorizationCode("code", "verifier", resolveOpenAIRedirectUri("localhost")),
},
{
operation: "refresh" as const,
run: () => refreshOpenAIAccessToken("old-refresh-token"),
},
])(
"returns a failed result when the token $operation response is malformed JSON",
async ({ operation, run }) => {
mockTokenResponseText('{"access_token":"access-token","refresh_to');
const result = await run();
expect(result).toEqual({
type: "failed",
message: `OpenAI Codex token ${operation} failed: response is not valid JSON`,
});
},
);
it("times out token refresh requests", async () => {
ssrfMocks.fetchWithSsrFGuard.mockRejectedValueOnce(timeoutError());
@@ -112,7 +112,15 @@ async function readOpenAITokenResponse(
message: `OpenAI Codex token ${operation} failed (${response.status}): ${text || response.statusText}`,
};
}
const json = (await response.json()) as TokenResponseJson;
let json: TokenResponseJson;
try {
json = (await response.json()) as TokenResponseJson;
} catch {
return {
type: "failed",
message: `OpenAI Codex token ${operation} failed: response is not valid JSON`,
};
}
if (!isRecord(json)) {
return {
type: "failed",