refactor: unify group allowlist policy
This commit is contained in:
@@ -169,6 +169,36 @@ describe("monitorIMessageProvider", () => {
|
||||
expect(replyMock).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("blocks group messages when imessage.groups is set without a wildcard", async () => {
|
||||
config = {
|
||||
...config,
|
||||
imessage: { groups: { "99": { requireMention: false } } },
|
||||
};
|
||||
const run = monitorIMessageProvider();
|
||||
await waitForSubscribe();
|
||||
|
||||
notificationHandler?.({
|
||||
method: "message",
|
||||
params: {
|
||||
message: {
|
||||
id: 13,
|
||||
chat_id: 123,
|
||||
sender: "+15550001111",
|
||||
is_from_me: false,
|
||||
text: "@clawd hello",
|
||||
is_group: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await flush();
|
||||
closeResolve?.();
|
||||
await run;
|
||||
|
||||
expect(replyMock).not.toHaveBeenCalled();
|
||||
expect(sendMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("prefixes tool and final replies with responsePrefix", async () => {
|
||||
config = {
|
||||
...config,
|
||||
|
||||
@@ -9,6 +9,10 @@ import { createReplyDispatcher } from "../auto-reply/reply/reply-dispatcher.js";
|
||||
import { getReplyFromConfig } from "../auto-reply/reply.js";
|
||||
import type { ReplyPayload } from "../auto-reply/types.js";
|
||||
import { loadConfig } from "../config/config.js";
|
||||
import {
|
||||
resolveProviderGroupPolicy,
|
||||
resolveProviderGroupRequireMention,
|
||||
} from "../config/group-policy.js";
|
||||
import { resolveStorePath, updateLastRoute } from "../config/sessions.js";
|
||||
import { danger, logVerbose, shouldLogVerbose } from "../globals.js";
|
||||
import { mediaKindFromMime } from "../media/constants.js";
|
||||
@@ -71,24 +75,6 @@ function resolveAllowFrom(opts: MonitorIMessageOpts): string[] {
|
||||
return raw.map((entry) => String(entry).trim()).filter(Boolean);
|
||||
}
|
||||
|
||||
function resolveGroupRequireMention(
|
||||
cfg: ReturnType<typeof loadConfig>,
|
||||
opts: MonitorIMessageOpts,
|
||||
chatId?: number | null,
|
||||
): boolean {
|
||||
if (typeof opts.requireMention === "boolean") return opts.requireMention;
|
||||
const groupId = chatId != null ? String(chatId) : undefined;
|
||||
if (groupId) {
|
||||
const groupConfig = cfg.imessage?.groups?.[groupId];
|
||||
if (typeof groupConfig?.requireMention === "boolean") {
|
||||
return groupConfig.requireMention;
|
||||
}
|
||||
}
|
||||
const groupDefault = cfg.imessage?.groups?.["*"]?.requireMention;
|
||||
if (typeof groupDefault === "boolean") return groupDefault;
|
||||
return true;
|
||||
}
|
||||
|
||||
async function deliverReplies(params: {
|
||||
replies: ReplyPayload[];
|
||||
target: string;
|
||||
@@ -152,6 +138,21 @@ export async function monitorIMessageProvider(
|
||||
const isGroup = Boolean(message.is_group);
|
||||
if (isGroup && !chatId) return;
|
||||
|
||||
const groupId = isGroup ? String(chatId) : undefined;
|
||||
if (isGroup) {
|
||||
const groupPolicy = resolveProviderGroupPolicy({
|
||||
cfg,
|
||||
surface: "imessage",
|
||||
groupId,
|
||||
});
|
||||
if (groupPolicy.allowlistEnabled && !groupPolicy.allowed) {
|
||||
logVerbose(
|
||||
`imessage: skipping group message (${groupId ?? "unknown"}) not in allowlist`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const commandAuthorized = isAllowedIMessageSender({
|
||||
allowFrom,
|
||||
sender,
|
||||
@@ -168,7 +169,13 @@ export async function monitorIMessageProvider(
|
||||
const mentioned = isGroup
|
||||
? matchesMentionPatterns(messageText, mentionRegexes)
|
||||
: true;
|
||||
const requireMention = resolveGroupRequireMention(cfg, opts, chatId);
|
||||
const requireMention = resolveProviderGroupRequireMention({
|
||||
cfg,
|
||||
surface: "imessage",
|
||||
groupId,
|
||||
requireMentionOverride: opts.requireMention,
|
||||
overrideOrder: "before-config",
|
||||
});
|
||||
const canDetectMention = mentionRegexes.length > 0;
|
||||
const shouldBypassMention =
|
||||
isGroup &&
|
||||
|
||||
Reference in New Issue
Block a user