fix(synology-chat): wrap malformed webhook json · openclaw/openclaw@e692f5c
vincentkoc
·
2026-05-14
·
via Recent Commits to openclaw:main
File tree
extensions/synology-chat/src
| Original file line number | Diff line number | Diff line change |
|---|
@@ -63,6 +63,7 @@ Docs: https://docs.openclaw.ai
|
63 | 63 | - Amazon Bedrock embeddings: report malformed provider response JSON with provider-owned errors instead of leaking raw parser failures. |
64 | 64 | - QQBot: report malformed access-token JSON with provider-owned errors instead of leaking raw parser failures. |
65 | 65 | - OpenAI embeddings: report malformed batch output JSONL with provider-owned errors instead of leaking raw parser failures. |
| 66 | +- Synology Chat: report malformed JSON webhook payloads with stable channel-owned parser errors. |
66 | 67 | - Models config/auth: stop inferring provider env-var markers from broad `^[A-Z_][A-Z0-9_]*$` strings, and resolve config-backed provider `apiKey` values only through structured env SecretRefs (`secrets.providers[id]` / `secrets.defaults`), so unrelated env vars cannot accidentally become provider credentials. Thanks @sallyom. |
67 | 68 | - Media fetch: skip allocating and buffering the response body for bodyless media responses (HEAD probes and 204-style empty bodies), avoiding wasted heap on streams that carry no payload. Thanks @shakkernerd. |
68 | 69 | - CLI/onboarding: forward provider-specific auth flags (e.g. `--openai-api-key`) through the onboarding wizard so they reach provider auth methods via `ctx.opts`, letting `--openai-api-key "$OPENAI_API_KEY"` skip the redundant "use existing env var?" prompt in non-interactive harnesses. (#81669) Thanks @sjf. |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -449,6 +449,29 @@ describe("createWebhookHandler", () => {
|
449 | 449 | expect(message.chatUserId).toBe("123"); |
450 | 450 | }); |
451 | 451 | |
| 452 | +it("rejects malformed application/json with a stable parser error", async () => { |
| 453 | +const deliver = vi.fn().mockResolvedValue(null); |
| 454 | +const handler = createWebhookHandler({ |
| 455 | +account: makeAccount({ accountId: "json-malformed-" + Date.now() }), |
| 456 | + deliver, |
| 457 | + log, |
| 458 | +}); |
| 459 | + |
| 460 | +const req = makeReq("POST", "{not json", { |
| 461 | +headers: { "content-type": "application/json" }, |
| 462 | +}); |
| 463 | +const res = makeRes(); |
| 464 | +await handler(req, res); |
| 465 | + |
| 466 | +expect(res._status).toBe(400); |
| 467 | +expect(res._body).toContain("Invalid request body"); |
| 468 | +expect(deliver).not.toHaveBeenCalled(); |
| 469 | +expect(log.warn).toHaveBeenCalledWith( |
| 470 | +"Failed to parse webhook payload", |
| 471 | +expect.objectContaining({ message: "Invalid JSON body" }), |
| 472 | +); |
| 473 | +}); |
| 474 | + |
452 | 475 | it("accepts token from query when body token is absent", async () => { |
453 | 476 | await expectTokenlessBodyAccepted({ |
454 | 477 | accountIdSuffix: "query-token-test", |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -224,7 +224,12 @@ function parseJsonBody(body: string): Record<string, unknown> {
|
224 | 224 | if (!body.trim()) { |
225 | 225 | return {}; |
226 | 226 | } |
227 | | -const parsed = JSON.parse(body); |
| 227 | +let parsed: unknown; |
| 228 | +try { |
| 229 | +parsed = JSON.parse(body) as unknown; |
| 230 | +} catch { |
| 231 | +throw new Error("Invalid JSON body"); |
| 232 | +} |
228 | 233 | if (!parsed || Array.isArray(parsed) || typeof parsed !== "object") { |
229 | 234 | throw new Error("Invalid JSON body"); |
230 | 235 | } |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。