From d52e5e1d859da5e6df8457cf288ebf1d7b72dd96 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 2 Mar 2026 18:33:05 +0000 Subject: [PATCH] fix: add regression tests for telegram token guard (#31973) (thanks @ningding97) --- CHANGELOG.md | 2 ++ extensions/telegram/src/channel.test.ts | 43 +++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf896af9445..d461cc2bf70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,8 @@ Docs: https://docs.openclaw.ai ### Fixes - Slack/Bolt startup compatibility: remove invalid `message.channels` and `message.groups` event registrations so Slack providers no longer crash on startup with Bolt 4.6+; channel/group traffic continues through the unified `message` handler (`channel_type`). (#32033) Thanks @mahopan. +- Telegram: guard duplicate-token checks and gateway startup token normalization when account tokens are missing, preventing `token.trim()` crashes during status/start flows. (#31973) Thanks @ningding97. +- Skills/sherpa-onnx-tts: run the `sherpa-onnx-tts` bin under ESM (replace CommonJS `require` imports) and add regression coverage to prevent `require is not defined in ES module scope` startup crashes. (#31965) Thanks @bmendonca3. - Sandbox/Docker setup command parsing: accept `agents.*.sandbox.docker.setupCommand` as either a string or a string array, and normalize arrays to newline-delimited shell scripts so multi-step setup commands no longer concatenate without separators. (#31953) Thanks @liuxiaopai-ai. - Gateway/Plugin HTTP route precedence: run explicit plugin HTTP routes before the Control UI SPA catch-all so registered plugin webhook/custom paths remain reachable, while unmatched paths still fall through to Control UI handling. (#31885) Thanks @Sid-Qin. - Security/Node exec approvals: preserve shell/dispatch-wrapper argv semantics during approval hardening so approved wrapper commands (for example `env sh -c ...`) cannot drift into a different runtime command shape, and add regression coverage for both approval-plan generation and approved runtime execution paths. Thanks @tdjackey for reporting. diff --git a/extensions/telegram/src/channel.test.ts b/extensions/telegram/src/channel.test.ts index 0fd75ae7664..a856502e60b 100644 --- a/extensions/telegram/src/channel.test.ts +++ b/extensions/telegram/src/channel.test.ts @@ -182,4 +182,47 @@ describe("telegramPlugin duplicate token guard", () => { ); expect(result).toMatchObject({ channel: "telegram", messageId: "tg-1" }); }); + + it("ignores accounts with missing tokens during duplicate-token checks", async () => { + const cfg = createCfg(); + cfg.channels!.telegram!.accounts!.ops = {} as never; + + const alertsAccount = telegramPlugin.config.resolveAccount(cfg, "alerts"); + expect(await telegramPlugin.config.isConfigured!(alertsAccount, cfg)).toBe(true); + }); + + it("does not crash startup when a resolved account token is undefined", async () => { + const monitorTelegramProvider = vi.fn(async () => undefined); + const probeTelegram = vi.fn(async () => ({ ok: false })); + const runtime = { + channel: { + telegram: { + monitorTelegramProvider, + probeTelegram, + }, + }, + logging: { + shouldLogVerbose: () => false, + }, + } as unknown as PluginRuntime; + setTelegramRuntime(runtime); + + const cfg = createCfg(); + const ctx = createStartAccountCtx({ + cfg, + accountId: "ops", + runtime: createRuntimeEnv(), + }); + ctx.account = { + ...ctx.account, + token: undefined as unknown as string, + } as ResolvedTelegramAccount; + + await expect(telegramPlugin.gateway!.startAccount!(ctx)).resolves.toBeUndefined(); + expect(monitorTelegramProvider).toHaveBeenCalledWith( + expect.objectContaining({ + token: "", + }), + ); + }); });