From b0a8909a733ecb119bb26bebe62cc350ef3e2b58 Mon Sep 17 00:00:00 2001 From: Jealous Date: Sat, 28 Feb 2026 13:39:21 +0800 Subject: [PATCH] fix(feishu): fix group policy enforcement gaps (#25439) - Respect groupConfig.enabled flag (was parsed but never enforced) - Fix misleading log: group allowlist rejection now logs group ID and policy instead of sender open_id --- extensions/feishu/src/bot.test.ts | 32 +++++++++++++++++++++++++++++++ extensions/feishu/src/bot.ts | 8 +++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/extensions/feishu/src/bot.test.ts b/extensions/feishu/src/bot.test.ts index 3fb679cc8..69121a8fb 100644 --- a/extensions/feishu/src/bot.test.ts +++ b/extensions/feishu/src/bot.test.ts @@ -554,6 +554,38 @@ describe("handleFeishuMessage command authorization", () => { expect(mockDispatchReplyFromConfig).not.toHaveBeenCalled(); }); + it("drops message when groupConfig.enabled is false", async () => { + const cfg: ClawdbotConfig = { + channels: { + feishu: { + groups: { + "oc-disabled-group": { + enabled: false, + }, + }, + }, + }, + } as ClawdbotConfig; + + const event: FeishuMessageEvent = { + sender: { + sender_id: { open_id: "ou-sender" }, + }, + message: { + message_id: "msg-disabled-group", + chat_id: "oc-disabled-group", + chat_type: "group", + message_type: "text", + content: JSON.stringify({ text: "hello" }), + }, + }; + + await dispatchMessage({ cfg, event }); + + expect(mockFinalizeInboundContext).not.toHaveBeenCalled(); + expect(mockDispatchReplyFromConfig).not.toHaveBeenCalled(); + }); + it("uses video file_key (not thumbnail image_key) for inbound video download", async () => { mockShouldComputeCommandAuthorized.mockReturnValue(false); diff --git a/extensions/feishu/src/bot.ts b/extensions/feishu/src/bot.ts index f0f3249c3..8d9ee0edc 100644 --- a/extensions/feishu/src/bot.ts +++ b/extensions/feishu/src/bot.ts @@ -742,6 +742,10 @@ export async function handleFeishuMessage(params: { const useAccessGroups = cfg.commands?.useAccessGroups !== false; if (isGroup) { + if (groupConfig?.enabled === false) { + log(`feishu[${account.accountId}]: group ${ctx.chatId} is disabled`); + return; + } const defaultGroupPolicy = resolveDefaultGroupPolicy(cfg); const { groupPolicy, providerMissingFallbackApplied } = resolveOpenProviderRuntimeGroupPolicy({ providerConfigPresent: cfg.channels?.feishu !== undefined, @@ -766,7 +770,9 @@ export async function handleFeishuMessage(params: { }); if (!groupAllowed) { - log(`feishu[${account.accountId}]: sender ${ctx.senderOpenId} not in group allowlist`); + log( + `feishu[${account.accountId}]: group ${ctx.chatId} not in groupAllowFrom (groupPolicy=${groupPolicy})`, + ); return; }