diff --git a/CHANGELOG.md b/CHANGELOG.md index 079ad76cb82..99db9758816 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -81,6 +81,7 @@ Docs: https://docs.openclaw.ai - Gateway/WS: close repeated post-handshake `unauthorized role:*` request floods per connection and sample duplicate rejection logs, preventing a single misbehaving client from degrading gateway responsiveness. (#20168) Thanks @acy103, @vibecodooor, and @vincentkoc. - Gateway/Restart: treat child listener PIDs as owned by the service runtime PID during restart health checks to avoid false stale-process kills and restart timeouts on launchd/systemd. (#24696) Thanks @gumadeiras. - Config/Write: apply `unsetPaths` with immutable path-copy updates so config writes never mutate caller-provided objects, and harden `openclaw config get/set/unset` path traversal by rejecting prototype-key segments and inherited-property traversal. (#24134) thanks @frankekn. +- Channels/WhatsApp: accept `channels.whatsapp.enabled` in config validation to match built-in channel auto-enable behavior, preventing `Unrecognized key: "enabled"` failures during channel setup. (#24263) - Security/Exec: detect obfuscated commands before exec allowlist decisions and require explicit approval for obfuscation patterns. (#8592) Thanks @CornBrother0x and @vincentkoc. - Security/ACP: harden ACP client permission auto-approval to require trusted core tool IDs, ignore untrusted `toolCall.kind` hints, and scope `read` auto-approval to the active working directory so unknown tool names and out-of-scope file reads always prompt. This ships in the next npm release. Thanks @nedlir for reporting. - Security/Skills: escape user-controlled prompt, filename, and output-path values in `openai-image-gen` HTML gallery generation to prevent stored XSS in generated `index.html` output. (#12538) Thanks @CornBrother0x. diff --git a/src/config/config.schema-regressions.test.ts b/src/config/config.schema-regressions.test.ts index ff42403f868..c183b34fa8e 100644 --- a/src/config/config.schema-regressions.test.ts +++ b/src/config/config.schema-regressions.test.ts @@ -63,6 +63,18 @@ describe("config schema regressions", () => { expect(res.ok).toBe(true); }); + it("accepts channels.whatsapp.enabled", () => { + const res = validateConfigObject({ + channels: { + whatsapp: { + enabled: true, + }, + }, + }); + + expect(res.ok).toBe(true); + }); + it("rejects unsafe iMessage remoteHost", () => { const res = validateConfigObject({ channels: { diff --git a/src/config/plugin-auto-enable.test.ts b/src/config/plugin-auto-enable.test.ts index 7f5779a1818..f3ef2961f4e 100644 --- a/src/config/plugin-auto-enable.test.ts +++ b/src/config/plugin-auto-enable.test.ts @@ -1,4 +1,5 @@ import { describe, expect, it } from "vitest"; +import { validateConfigObject } from "./config.js"; import { applyPluginAutoEnable } from "./plugin-auto-enable.js"; describe("applyPluginAutoEnable", () => { @@ -48,6 +49,23 @@ describe("applyPluginAutoEnable", () => { expect(result.changes).toEqual([]); }); + it("keeps auto-enabled WhatsApp config schema-valid", () => { + const result = applyPluginAutoEnable({ + config: { + channels: { + whatsapp: { + allowFrom: ["+15555550123"], + }, + }, + }, + env: {}, + }); + + expect(result.config.channels?.whatsapp?.enabled).toBe(true); + const validated = validateConfigObject(result.config); + expect(validated.ok).toBe(true); + }); + it("respects explicit disable", () => { const result = applyPluginAutoEnable({ config: { diff --git a/src/config/types.whatsapp.ts b/src/config/types.whatsapp.ts index 6fa99ea7b84..395ce3b06b2 100644 --- a/src/config/types.whatsapp.ts +++ b/src/config/types.whatsapp.ts @@ -36,6 +36,8 @@ export type WhatsAppAckReactionConfig = { }; type WhatsAppSharedConfig = { + /** Whether the WhatsApp channel is enabled. */ + enabled?: boolean; /** Direct message access policy (default: pairing). */ dmPolicy?: DmPolicy; /** Same-phone setup (bot uses your personal WhatsApp number). */ diff --git a/src/config/zod-schema.providers-whatsapp.ts b/src/config/zod-schema.providers-whatsapp.ts index 92c6daeffc3..4387ed1abb5 100644 --- a/src/config/zod-schema.providers-whatsapp.ts +++ b/src/config/zod-schema.providers-whatsapp.ts @@ -32,6 +32,7 @@ const WhatsAppAckReactionSchema = z .optional(); const WhatsAppSharedSchema = z.object({ + enabled: z.boolean().optional(), capabilities: z.array(z.string()).optional(), markdown: MarkdownConfigSchema, configWrites: z.boolean().optional(),