From 6957354d4819de65d3cb74eb1fd888b96a0d38b6 Mon Sep 17 00:00:00 2001 From: Vignesh Natarajan Date: Sun, 15 Feb 2026 19:09:07 -0800 Subject: [PATCH] fix (telegram/whatsapp): use account-scoped pairing allowlists --- src/telegram/bot-handlers.ts | 14 ++++++++++++-- src/telegram/bot-message-context.ts | 1 + src/telegram/bot-native-commands.ts | 5 +++++ src/telegram/bot/helpers.ts | 7 ++++++- src/web/auto-reply/monitor/process-message.ts | 6 +++++- src/web/inbound/access-control.ts | 7 ++++++- 6 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/telegram/bot-handlers.ts b/src/telegram/bot-handlers.ts index 688ed9a4897..f8873aa9da2 100644 --- a/src/telegram/bot-handlers.ts +++ b/src/telegram/bot-handlers.ts @@ -227,7 +227,11 @@ export const registerTelegramHandlers = ({ } } - const storeAllowFrom = await readChannelAllowFromStore("telegram").catch(() => []); + const storeAllowFrom = await readChannelAllowFromStore( + "telegram", + process.env, + accountId, + ).catch(() => []); await processMessage(primaryEntry.ctx, allMedia, storeAllowFrom); } catch (err) { runtime.error?.(danger(`media group handler failed: ${String(err)}`)); @@ -258,7 +262,11 @@ export const registerTelegramHandlers = ({ date: last.msg.date ?? first.msg.date, }; - const storeAllowFrom = await readChannelAllowFromStore("telegram").catch(() => []); + const storeAllowFrom = await readChannelAllowFromStore( + "telegram", + process.env, + accountId, + ).catch(() => []); const baseCtx = first.ctx; const getFile = typeof baseCtx.getFile === "function" ? baseCtx.getFile.bind(baseCtx) : async () => ({}); @@ -330,6 +338,7 @@ export const registerTelegramHandlers = ({ const isForum = callbackMessage.chat.is_forum === true; const groupAllowContext = await resolveTelegramGroupAllowFromContext({ chatId, + accountId, isForum, messageThreadId, groupAllowFrom, @@ -699,6 +708,7 @@ export const registerTelegramHandlers = ({ const isForum = msg.chat.is_forum === true; const groupAllowContext = await resolveTelegramGroupAllowFromContext({ chatId, + accountId, isForum, messageThreadId, groupAllowFrom, diff --git a/src/telegram/bot-message-context.ts b/src/telegram/bot-message-context.ts index 9723419f4da..a8ae50db178 100644 --- a/src/telegram/bot-message-context.ts +++ b/src/telegram/bot-message-context.ts @@ -273,6 +273,7 @@ export const buildTelegramMessageContext = async ({ const { code, created } = await upsertChannelPairingRequest({ channel: "telegram", id: telegramUserId, + accountId: account.accountId, meta: { username: from?.username, firstName: from?.first_name, diff --git a/src/telegram/bot-native-commands.ts b/src/telegram/bot-native-commands.ts index 27a3cd92849..468726e2bb8 100644 --- a/src/telegram/bot-native-commands.ts +++ b/src/telegram/bot-native-commands.ts @@ -127,6 +127,7 @@ async function resolveTelegramCommandAuth(params: { msg: NonNullable; bot: Bot; cfg: OpenClawConfig; + accountId: string; telegramCfg: TelegramAccountConfig; allowFrom?: Array; groupAllowFrom?: Array; @@ -142,6 +143,7 @@ async function resolveTelegramCommandAuth(params: { msg, bot, cfg, + accountId, telegramCfg, allowFrom, groupAllowFrom, @@ -156,6 +158,7 @@ async function resolveTelegramCommandAuth(params: { const isForum = (msg.chat as { is_forum?: boolean }).is_forum === true; const groupAllowContext = await resolveTelegramGroupAllowFromContext({ chatId, + accountId, isForum, messageThreadId, groupAllowFrom, @@ -371,6 +374,7 @@ export const registerTelegramNativeCommands = ({ msg, bot, cfg, + accountId, telegramCfg, allowFrom, groupAllowFrom, @@ -623,6 +627,7 @@ export const registerTelegramNativeCommands = ({ msg, bot, cfg, + accountId, telegramCfg, allowFrom, groupAllowFrom, diff --git a/src/telegram/bot/helpers.ts b/src/telegram/bot/helpers.ts index 8170bf99d8a..b5b33667d70 100644 --- a/src/telegram/bot/helpers.ts +++ b/src/telegram/bot/helpers.ts @@ -18,6 +18,7 @@ export type TelegramThreadSpec = { export async function resolveTelegramGroupAllowFromContext(params: { chatId: string | number; + accountId?: string; isForum?: boolean; messageThreadId?: number | null; groupAllowFrom?: Array; @@ -38,7 +39,11 @@ export async function resolveTelegramGroupAllowFromContext(params: { isForum: params.isForum, messageThreadId: params.messageThreadId, }); - const storeAllowFrom = await readChannelAllowFromStore("telegram").catch(() => []); + const storeAllowFrom = await readChannelAllowFromStore( + "telegram", + process.env, + params.accountId, + ).catch(() => []); const { groupConfig, topicConfig } = params.resolveTelegramGroupConfig( params.chatId, resolvedThreadId, diff --git a/src/web/auto-reply/monitor/process-message.ts b/src/web/auto-reply/monitor/process-message.ts index 90e857474da..ed86bf93098 100644 --- a/src/web/auto-reply/monitor/process-message.ts +++ b/src/web/auto-reply/monitor/process-message.ts @@ -88,7 +88,11 @@ async function resolveWhatsAppCommandAuthorized(params: { return normalizeAllowFromE164(configuredGroupAllowFrom).includes(senderE164); } - const storeAllowFrom = await readChannelAllowFromStore("whatsapp").catch(() => []); + const storeAllowFrom = await readChannelAllowFromStore( + "whatsapp", + process.env, + params.msg.accountId, + ).catch(() => []); const combinedAllowFrom = Array.from( new Set([...(configuredAllowFrom ?? []), ...storeAllowFrom]), ); diff --git a/src/web/inbound/access-control.ts b/src/web/inbound/access-control.ts index 08d97acd584..96671e7bc77 100644 --- a/src/web/inbound/access-control.ts +++ b/src/web/inbound/access-control.ts @@ -40,7 +40,11 @@ export async function checkInboundAccessControl(params: { }); const dmPolicy = account.dmPolicy ?? "pairing"; const configuredAllowFrom = account.allowFrom; - const storeAllowFrom = await readChannelAllowFromStore("whatsapp").catch(() => []); + const storeAllowFrom = await readChannelAllowFromStore( + "whatsapp", + process.env, + account.accountId, + ).catch(() => []); // Without user config, default to self-only DM access so the owner can talk to themselves. const combinedAllowFrom = Array.from( new Set([...(configuredAllowFrom ?? []), ...storeAllowFrom]), @@ -148,6 +152,7 @@ export async function checkInboundAccessControl(params: { const { code, created } = await upsertChannelPairingRequest({ channel: "whatsapp", id: candidate, + accountId: account.accountId, meta: { name: (params.pushName ?? "").trim() || undefined }, }); if (created) {