mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-31 11:23:33 +00:00
fix: enforce explicit group auth boundaries across channels
This commit is contained in:
@@ -27,7 +27,10 @@ import type { getChildLogger } from "../../../logging.js";
|
||||
import { getAgentScopedMediaLocalRoots } from "../../../media/local-roots.js";
|
||||
import { readChannelAllowFromStore } from "../../../pairing/pairing-store.js";
|
||||
import type { resolveAgentRoute } from "../../../routing/resolve-route.js";
|
||||
import { readStoreAllowFromForDmPolicy } from "../../../security/dm-policy-shared.js";
|
||||
import {
|
||||
readStoreAllowFromForDmPolicy,
|
||||
resolveDmGroupAccessWithCommandGate,
|
||||
} from "../../../security/dm-policy-shared.js";
|
||||
import { jidToE164, normalizeE164 } from "../../../utils.js";
|
||||
import { resolveWhatsAppAccount } from "../../accounts.js";
|
||||
import { newConnectionId } from "../../reconnect.js";
|
||||
@@ -49,15 +52,6 @@ export type GroupHistoryEntry = {
|
||||
senderJid?: string;
|
||||
};
|
||||
|
||||
function normalizeAllowFromE164(values: Array<string | number> | undefined): string[] {
|
||||
const list = Array.isArray(values) ? values : [];
|
||||
return list
|
||||
.map((entry) => String(entry).trim())
|
||||
.filter((entry) => entry && entry !== "*")
|
||||
.map((entry) => normalizeE164(entry))
|
||||
.filter((entry): entry is string => Boolean(entry));
|
||||
}
|
||||
|
||||
async function resolveWhatsAppCommandAuthorized(params: {
|
||||
cfg: ReturnType<typeof loadConfig>;
|
||||
msg: WebInboundMsg;
|
||||
@@ -77,38 +71,49 @@ async function resolveWhatsAppCommandAuthorized(params: {
|
||||
|
||||
const account = resolveWhatsAppAccount({ cfg: params.cfg, accountId: params.msg.accountId });
|
||||
const dmPolicy = account.dmPolicy ?? "pairing";
|
||||
const groupPolicy = account.groupPolicy ?? "allowlist";
|
||||
const configuredAllowFrom = account.allowFrom ?? [];
|
||||
const configuredGroupAllowFrom =
|
||||
account.groupAllowFrom ?? (configuredAllowFrom.length > 0 ? configuredAllowFrom : undefined);
|
||||
|
||||
if (isGroup) {
|
||||
if (!configuredGroupAllowFrom || configuredGroupAllowFrom.length === 0) {
|
||||
return false;
|
||||
}
|
||||
if (configuredGroupAllowFrom.some((v) => String(v).trim() === "*")) {
|
||||
return true;
|
||||
}
|
||||
return normalizeAllowFromE164(configuredGroupAllowFrom).includes(senderE164);
|
||||
}
|
||||
|
||||
const storeAllowFrom = await readStoreAllowFromForDmPolicy({
|
||||
provider: "whatsapp",
|
||||
dmPolicy,
|
||||
readStore: (provider) => readChannelAllowFromStore(provider, process.env, params.msg.accountId),
|
||||
});
|
||||
const combinedAllowFrom = Array.from(
|
||||
new Set([...(configuredAllowFrom ?? []), ...storeAllowFrom]),
|
||||
);
|
||||
const allowFrom =
|
||||
combinedAllowFrom.length > 0
|
||||
? combinedAllowFrom
|
||||
const storeAllowFrom =
|
||||
isGroup
|
||||
? []
|
||||
: await readStoreAllowFromForDmPolicy({
|
||||
provider: "whatsapp",
|
||||
dmPolicy,
|
||||
readStore: (provider) =>
|
||||
readChannelAllowFromStore(provider, process.env, params.msg.accountId),
|
||||
});
|
||||
const dmAllowFrom =
|
||||
configuredAllowFrom.length > 0
|
||||
? configuredAllowFrom
|
||||
: params.msg.selfE164
|
||||
? [params.msg.selfE164]
|
||||
: [];
|
||||
if (allowFrom.some((v) => String(v).trim() === "*")) {
|
||||
return true;
|
||||
}
|
||||
return normalizeAllowFromE164(allowFrom).includes(senderE164);
|
||||
const access = resolveDmGroupAccessWithCommandGate({
|
||||
isGroup,
|
||||
dmPolicy,
|
||||
groupPolicy,
|
||||
allowFrom: dmAllowFrom,
|
||||
groupAllowFrom: configuredGroupAllowFrom,
|
||||
storeAllowFrom,
|
||||
isSenderAllowed: (allowEntries) => {
|
||||
if (allowEntries.includes("*")) {
|
||||
return true;
|
||||
}
|
||||
const normalizedEntries = allowEntries
|
||||
.map((entry) => normalizeE164(String(entry)))
|
||||
.filter((entry): entry is string => Boolean(entry));
|
||||
return normalizedEntries.includes(senderE164);
|
||||
},
|
||||
command: {
|
||||
useAccessGroups,
|
||||
allowTextCommands: true,
|
||||
hasControlCommand: true,
|
||||
},
|
||||
});
|
||||
return access.commandAuthorized;
|
||||
}
|
||||
|
||||
export async function processMessage(params: {
|
||||
|
||||
Reference in New Issue
Block a user