diff --git a/CHANGELOG.md b/CHANGELOG.md index f24322875..adb86c852 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ Docs: https://docs.openclaw.ai ### Fixes +- Synology Chat/webhook ingress hardening: enforce bounded body reads (size + timeout) via shared request-body guards to prevent unauthenticated slow-body hangs before token validation. (#25831) Thanks @bmendonca3. - Auto-reply/followup queue: avoid stale callback reuse across idle-window restarts by caching the followup runner only when a drain actually starts, preserving enqueue ordering after empty-finalize paths. (#31902) Thanks @Lanfei. - Gateway/Heartbeat model reload: treat `models.*` and `agents.defaults.model` config updates as heartbeat hot-reload triggers so heartbeat picks up model changes without a full gateway restart. (#32046) Thanks @stakeswky. - Slack/inbound debounce routing: isolate top-level non-DM message debounce keys by message timestamp to avoid cross-thread collisions, preserve DM batching, and flush pending top-level buffers before immediate non-debounce follow-ups to keep ordering stable. (#31951) Thanks @scoootscooob. diff --git a/extensions/synology-chat/src/test-http-utils.ts b/extensions/synology-chat/src/test-http-utils.ts index ea268a483..4ce67fa84 100644 --- a/extensions/synology-chat/src/test-http-utils.ts +++ b/extensions/synology-chat/src/test-http-utils.ts @@ -2,10 +2,22 @@ import { EventEmitter } from "node:events"; import type { IncomingMessage, ServerResponse } from "node:http"; export function makeReq(method: string, body: string): IncomingMessage { - const req = new EventEmitter() as IncomingMessage; + const req = new EventEmitter() as IncomingMessage & { destroyed: boolean }; req.method = method; + req.headers = {}; req.socket = { remoteAddress: "127.0.0.1" } as unknown as IncomingMessage["socket"]; + req.destroyed = false; + req.destroy = ((_: Error | undefined) => { + if (req.destroyed) { + return req; + } + req.destroyed = true; + return req; + }) as IncomingMessage["destroy"]; process.nextTick(() => { + if (req.destroyed) { + return; + } req.emit("data", Buffer.from(body)); req.emit("end"); });