mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-18 17:34:45 +00:00
fix(msteams): wrap malformed api json
This commit is contained in:
@@ -85,6 +85,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Brave Search: report malformed web and LLM-context API JSON with provider-owned errors instead of leaking raw parser failures.
|
||||
- xAI tools: report malformed web search, X search, and code execution JSON with provider-owned errors instead of leaking raw parser failures.
|
||||
- Nextcloud Talk: report malformed room-info and bot-admin JSON with channel-owned errors instead of leaking raw parser failures.
|
||||
- Microsoft Teams: report malformed Graph and delegated OAuth JSON with channel-owned errors instead of leaking raw parser failures.
|
||||
- Twilio voice-call: report malformed successful API JSON responses with provider-owned errors instead of leaking raw parser failures.
|
||||
- Voice-call provider APIs: report malformed successful guarded JSON responses with provider-prefixed errors instead of leaking raw parser failures.
|
||||
- Realtime transcription: report malformed provider websocket JSON frames with owned parser errors instead of leaking raw `SyntaxError` objects.
|
||||
|
||||
@@ -193,6 +193,19 @@ describe("msteams graph helpers", () => {
|
||||
}),
|
||||
"Graph /teams/team-1/channels failed (403): forbidden",
|
||||
);
|
||||
|
||||
mockTextFetchResponse("{ nope", {
|
||||
status: 200,
|
||||
headers: { "content-type": "application/json" },
|
||||
});
|
||||
|
||||
await expectRejectsToThrow(
|
||||
fetchGraphJson({
|
||||
token: graphToken,
|
||||
path: "/teams/team-1/channels",
|
||||
}),
|
||||
"Graph /teams/team-1/channels failed: malformed JSON response",
|
||||
);
|
||||
});
|
||||
|
||||
it("posts Graph JSON to v1 and beta roots and treats empty mutation responses as undefined", async () => {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { readProviderJsonResponse } from "openclaw/plugin-sdk/provider-http";
|
||||
import { fetchWithSsrFGuard, type MSTeamsConfig } from "../runtime-api.js";
|
||||
import { GRAPH_ROOT } from "./attachments/shared.js";
|
||||
|
||||
@@ -118,7 +119,7 @@ export async function fetchGraphAbsoluteUrl<T>(params: {
|
||||
`Graph ${params.url} failed (${response.status}): ${text || "unknown error"}`,
|
||||
);
|
||||
}
|
||||
return (await response.json()) as T;
|
||||
return await readProviderJsonResponse<T>(response, `Graph ${params.url} failed`);
|
||||
} finally {
|
||||
await release();
|
||||
}
|
||||
|
||||
@@ -228,6 +228,25 @@ describe("exchangeMSTeamsCodeForTokens", () => {
|
||||
}),
|
||||
).rejects.toThrow(/MSTeams token exchange failed \(400\)/);
|
||||
});
|
||||
|
||||
it("reports malformed token exchange JSON with a stable OAuth error", async () => {
|
||||
fetchSpy.mockResolvedValueOnce(
|
||||
new Response("{ nope", {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}),
|
||||
);
|
||||
|
||||
await expect(
|
||||
exchangeMSTeamsCodeForTokens({
|
||||
tenantId: "t",
|
||||
clientId: "c",
|
||||
clientSecret: "s", // pragma: allowlist secret
|
||||
code: "bad-json",
|
||||
verifier: "v",
|
||||
}),
|
||||
).rejects.toThrow("MSTeams token exchange failed: malformed JSON response");
|
||||
});
|
||||
});
|
||||
|
||||
describe("refreshMSTeamsDelegatedTokens", () => {
|
||||
@@ -310,4 +329,22 @@ describe("refreshMSTeamsDelegatedTokens", () => {
|
||||
}),
|
||||
).rejects.toThrow(/MSTeams token refresh failed \(401\)/);
|
||||
});
|
||||
|
||||
it("reports malformed token refresh JSON with a stable OAuth error", async () => {
|
||||
fetchSpy.mockResolvedValueOnce(
|
||||
new Response("{ nope", {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}),
|
||||
);
|
||||
|
||||
await expect(
|
||||
refreshMSTeamsDelegatedTokens({
|
||||
tenantId: "t",
|
||||
clientId: "c",
|
||||
clientSecret: "s", // pragma: allowlist secret
|
||||
refreshToken: "bad-json",
|
||||
}),
|
||||
).rejects.toThrow("MSTeams token refresh failed: malformed JSON response");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { readProviderJsonResponse } from "openclaw/plugin-sdk/provider-http";
|
||||
import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import {
|
||||
MSTEAMS_DEFAULT_DELEGATED_SCOPES,
|
||||
@@ -65,7 +66,10 @@ async function fetchMSTeamsTokens(params: {
|
||||
const errorText = await response.text();
|
||||
throw new Error(`MSTeams ${params.failureLabel} failed (${response.status}): ${errorText}`);
|
||||
}
|
||||
return (await response.json()) as MSTeamsTokenResponse;
|
||||
return await readProviderJsonResponse<MSTeamsTokenResponse>(
|
||||
response,
|
||||
`MSTeams ${params.failureLabel} failed`,
|
||||
);
|
||||
} finally {
|
||||
await release();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user