From c5bd84309aeb634834c16fd8a7cff1159ffd18ac Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 7 Mar 2026 23:24:45 +0000 Subject: [PATCH] refactor: share allowFrom stringification helpers --- extensions/bluebubbles/src/monitor-processing.ts | 3 ++- extensions/zalo/src/channel.ts | 6 ++---- src/channels/allowlists/resolve-utils.ts | 6 ++---- src/channels/plugins/directory-config.ts | 3 ++- src/infra/outbound/targets.ts | 9 ++++----- src/infra/system-run-normalize.ts | 4 +++- src/plugin-sdk/bluebubbles.ts | 1 + 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/extensions/bluebubbles/src/monitor-processing.ts b/extensions/bluebubbles/src/monitor-processing.ts index a80f22df853..6eb2ab08bc0 100644 --- a/extensions/bluebubbles/src/monitor-processing.ts +++ b/extensions/bluebubbles/src/monitor-processing.ts @@ -8,6 +8,7 @@ import { logAckFailure, logInboundDrop, logTypingFailure, + mapAllowFromEntries, readStoreAllowFromForDmPolicy, recordPendingHistoryEntryIfEnabled, resolveAckReaction, @@ -510,7 +511,7 @@ export async function processMessage( const dmPolicy = account.config.dmPolicy ?? "pairing"; const groupPolicy = account.config.groupPolicy ?? "allowlist"; - const configuredAllowFrom = (account.config.allowFrom ?? []).map((entry) => String(entry)); + const configuredAllowFrom = mapAllowFromEntries(account.config.allowFrom); const storeAllowFrom = await readStoreAllowFromForDmPolicy({ provider: "bluebubbles", accountId: account.accountId, diff --git a/extensions/zalo/src/channel.ts b/extensions/zalo/src/channel.ts index 97fb8748fbe..454a29b3cbd 100644 --- a/extensions/zalo/src/channel.ts +++ b/extensions/zalo/src/channel.ts @@ -159,10 +159,8 @@ export const zaloPlugin: ChannelPlugin = { if (groupPolicy !== "open") { return []; } - const explicitGroupAllowFrom = (account.config.groupAllowFrom ?? []).map((entry) => - String(entry), - ); - const dmAllowFrom = (account.config.allowFrom ?? []).map((entry) => String(entry)); + const explicitGroupAllowFrom = mapAllowFromEntries(account.config.groupAllowFrom); + const dmAllowFrom = mapAllowFromEntries(account.config.allowFrom); const effectiveAllowFrom = explicitGroupAllowFrom.length > 0 ? explicitGroupAllowFrom : dmAllowFrom; if (effectiveAllowFrom.length > 0) { diff --git a/src/channels/allowlists/resolve-utils.ts b/src/channels/allowlists/resolve-utils.ts index 63dfa2be492..5ec898c1a1a 100644 --- a/src/channels/allowlists/resolve-utils.ts +++ b/src/channels/allowlists/resolve-utils.ts @@ -1,3 +1,4 @@ +import { mapAllowFromEntries } from "../../plugin-sdk/channel-config-helpers.js"; import type { RuntimeEnv } from "../../runtime.js"; export type AllowlistUserResolutionLike = { @@ -28,10 +29,7 @@ export function mergeAllowlist(params: { existing?: Array; additions: string[]; }): string[] { - return dedupeAllowlistEntries([ - ...(params.existing ?? []).map((entry) => String(entry)), - ...params.additions, - ]); + return dedupeAllowlistEntries([...mapAllowFromEntries(params.existing), ...params.additions]); } export function buildAllowlistResolutionSummary( diff --git a/src/channels/plugins/directory-config.ts b/src/channels/plugins/directory-config.ts index 2d308eccda3..eaf35fa33ef 100644 --- a/src/channels/plugins/directory-config.ts +++ b/src/channels/plugins/directory-config.ts @@ -1,5 +1,6 @@ import type { OpenClawConfig } from "../../config/types.js"; import { inspectDiscordAccount } from "../../discord/account-inspect.js"; +import { mapAllowFromEntries } from "../../plugin-sdk/channel-config-helpers.js"; import { inspectSlackAccount } from "../../slack/account-inspect.js"; import { inspectTelegramAccount } from "../../telegram/account-inspect.js"; import { resolveWhatsAppAccount } from "../../web/accounts.js"; @@ -161,7 +162,7 @@ export async function listTelegramDirectoryPeersFromConfig( ): Promise { const account = inspectTelegramAccount({ cfg: params.cfg, accountId: params.accountId }); const raw = [ - ...(account.config.allowFrom ?? []).map((entry) => String(entry)), + ...mapAllowFromEntries(account.config.allowFrom), ...Object.keys(account.config.dms ?? {}), ]; const ids = Array.from( diff --git a/src/infra/outbound/targets.ts b/src/infra/outbound/targets.ts index 89e68e57566..52e98a3089d 100644 --- a/src/infra/outbound/targets.ts +++ b/src/infra/outbound/targets.ts @@ -5,6 +5,7 @@ import type { OpenClawConfig } from "../../config/config.js"; import type { SessionEntry } from "../../config/sessions.js"; import type { AgentDefaultsConfig } from "../../config/types.agent-defaults.js"; import { parseDiscordTarget } from "../../discord/targets.js"; +import { mapAllowFromEntries } from "../../plugin-sdk/channel-config-helpers.js"; import { normalizeAccountId } from "../../routing/session-key.js"; import { parseSlackTarget } from "../../slack/targets.js"; import { parseTelegramTarget, resolveTelegramTargetChatType } from "../../telegram/targets.js"; @@ -203,7 +204,7 @@ export function resolveOutboundTarget(params: { accountId: params.accountId ?? undefined, }) : undefined); - const allowFrom = allowFromRaw?.map((entry) => String(entry)); + const allowFrom = allowFromRaw ? mapAllowFromEntries(allowFromRaw) : undefined; // Fall back to per-channel defaultTo when no explicit target is provided. const effectiveTo = @@ -496,9 +497,7 @@ function resolveHeartbeatSenderId(params: { provider && lastTo ? `${provider}:${lastTo}` : undefined, ].filter((val): val is string => Boolean(val?.trim())); - const allowList = allowFrom - .map((entry) => String(entry)) - .filter((entry) => entry && entry !== "*"); + const allowList = mapAllowFromEntries(allowFrom).filter((entry) => entry && entry !== "*"); if (allowFrom.includes("*")) { return candidates[0] ?? "heartbeat"; } @@ -536,7 +535,7 @@ export function resolveHeartbeatSenderContext(params: { accountId, }) ?? []) : []; - const allowFrom = allowFromRaw.map((entry) => String(entry)); + const allowFrom = mapAllowFromEntries(allowFromRaw); const sender = resolveHeartbeatSenderId({ allowFrom, diff --git a/src/infra/system-run-normalize.ts b/src/infra/system-run-normalize.ts index a3d928b9916..850685e033b 100644 --- a/src/infra/system-run-normalize.ts +++ b/src/infra/system-run-normalize.ts @@ -1,3 +1,5 @@ +import { mapAllowFromEntries } from "../plugin-sdk/channel-config-helpers.js"; + export function normalizeNonEmptyString(value: unknown): string | null { if (typeof value !== "string") { return null; @@ -7,5 +9,5 @@ export function normalizeNonEmptyString(value: unknown): string | null { } export function normalizeStringArray(value: unknown): string[] { - return Array.isArray(value) ? value.map((entry) => String(entry)) : []; + return Array.isArray(value) ? mapAllowFromEntries(value) : []; } diff --git a/src/plugin-sdk/bluebubbles.ts b/src/plugin-sdk/bluebubbles.ts index 5a1180a5770..736640b5a29 100644 --- a/src/plugin-sdk/bluebubbles.ts +++ b/src/plugin-sdk/bluebubbles.ts @@ -88,6 +88,7 @@ export { formatDocsLink } from "../terminal/links.js"; export type { WizardPrompter } from "../wizard/prompts.js"; export { isAllowedParsedChatSender } from "./allow-from.js"; export { readBooleanParam } from "./boolean-param.js"; +export { mapAllowFromEntries } from "./channel-config-helpers.js"; export { createScopedPairingAccess } from "./pairing-access.js"; export { issuePairingChallenge } from "../pairing/pairing-challenge.js"; export { resolveRequestUrl } from "./request-url.js";