Skip to content

Commit 8aa58c5

Browse files
committed
fix(minimax): bound oauth token bodies
1 parent e7e85f5 commit 8aa58c5

2 files changed

Lines changed: 41 additions & 3 deletions

File tree

extensions/minimax/oauth.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,46 @@ describe("loginMiniMaxPortalOAuth", () => {
122122
expect(textSpy).not.toHaveBeenCalled();
123123
});
124124

125+
it("bounds HTTP 200 token bodies before app-level parsing", async () => {
126+
const tracked = cancelTrackedResponse(`${'{"status":"error","detail":"'.repeat(512)}tail`, {
127+
status: 200,
128+
headers: { "Content-Type": "application/json" },
129+
});
130+
const textSpy = vi.spyOn(tracked.response, "text").mockRejectedValue(new Error("unbounded"));
131+
let callCount = 0;
132+
const fetchMock = vi.fn(async (_input: RequestInfo | URL, init?: RequestInit) => {
133+
callCount += 1;
134+
const body =
135+
init?.body instanceof URLSearchParams
136+
? init.body
137+
: new URLSearchParams(typeof init?.body === "string" ? init.body : "");
138+
if (callCount === 1) {
139+
return new Response(
140+
JSON.stringify({
141+
user_code: "CODE",
142+
verification_uri: "https://example.com/device",
143+
expired_in: Date.now() + 10_000,
144+
state: body.get("state"),
145+
}),
146+
{ status: 200, headers: { "Content-Type": "application/json" } },
147+
);
148+
}
149+
return tracked.response;
150+
});
151+
vi.stubGlobal("fetch", fetchMock);
152+
153+
const error = await loginMiniMaxPortalOAuth({
154+
openUrl: vi.fn(async () => undefined),
155+
note: vi.fn(async () => undefined),
156+
progress: { update: vi.fn(), stop: vi.fn() },
157+
}).catch((cause: unknown) => cause);
158+
159+
expect(error).toBeInstanceOf(Error);
160+
expect((error as Error).message).toBe("MiniMax OAuth failed to parse response.");
161+
expect(tracked.wasCanceled()).toBe(true);
162+
expect(textSpy).not.toHaveBeenCalled();
163+
});
164+
125165
it("uses MiniMax account OAuth endpoints directly for global and CN login", async () => {
126166
for (const [region, expectedHosts] of [
127167
[

extensions/minimax/oauth.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,7 @@ async function pollOAuthToken(params: {
173173
}
174174

175175
async function parseMiniMaxOAuthTokenResponse(response: Response): Promise<TokenResult> {
176-
const text = response.ok
177-
? await response.text()
178-
: await readResponseTextLimited(response, MINIMAX_OAUTH_ERROR_BODY_LIMIT_BYTES);
176+
const text = await readResponseTextLimited(response, MINIMAX_OAUTH_ERROR_BODY_LIMIT_BYTES);
179177
let payload:
180178
| {
181179
status?: string;

0 commit comments

Comments
 (0)