fix: enforce feishu dm policy + pairing flow (#14876) (thanks @coygeek)

This commit is contained in:
Peter Steinberger
2026-02-13 05:43:30 +01:00
parent f05553413d
commit daf13dbb06
4 changed files with 214 additions and 24 deletions

View File

@@ -21,7 +21,7 @@ import {
} from "./policy.js";
import { createFeishuReplyDispatcher } from "./reply-dispatcher.js";
import { getFeishuRuntime } from "./runtime.js";
import { getMessageFeishu } from "./send.js";
import { getMessageFeishu, sendMessageFeishu } from "./send.js";
// --- Message deduplication ---
// Prevent duplicate processing when WebSocket reconnects or Feishu redelivers messages.
@@ -647,16 +647,6 @@ export async function handleFeishuMessage(params: {
return;
}
} else {
if (dmPolicy === "allowlist") {
const match = resolveFeishuAllowlistMatch({
allowFrom: configAllowFrom,
senderId: ctx.senderOpenId,
});
if (!match.allowed) {
log(`feishu[${account.accountId}]: sender ${ctx.senderOpenId} not in DM allowlist`);
return;
}
}
}
try {
@@ -666,12 +656,51 @@ export async function handleFeishuMessage(params: {
cfg,
);
const storeAllowFrom =
!isGroup && shouldComputeCommandAuthorized
!isGroup && (dmPolicy !== "open" || shouldComputeCommandAuthorized)
? await core.channel.pairing.readAllowFromStore("feishu").catch(() => [])
: [];
const commandAllowFrom = isGroup
? (groupConfig?.allowFrom ?? [])
: [...configAllowFrom, ...storeAllowFrom];
const effectiveDmAllowFrom = [...configAllowFrom, ...storeAllowFrom];
const dmAllowed = resolveFeishuAllowlistMatch({
allowFrom: effectiveDmAllowFrom,
senderId: ctx.senderOpenId,
senderName: ctx.senderName,
}).allowed;
if (!isGroup && dmPolicy !== "open" && !dmAllowed) {
if (dmPolicy === "pairing") {
const { code, created } = await core.channel.pairing.upsertPairingRequest({
channel: "feishu",
id: ctx.senderOpenId,
meta: { name: ctx.senderName },
});
if (created) {
log(`feishu[${account.accountId}]: pairing request sender=${ctx.senderOpenId}`);
try {
await sendMessageFeishu({
cfg,
to: `user:${ctx.senderOpenId}`,
text: core.channel.pairing.buildPairingReply({
channel: "feishu",
idLine: `Your Feishu user id: ${ctx.senderOpenId}`,
code,
}),
accountId: account.accountId,
});
} catch (err) {
log(
`feishu[${account.accountId}]: pairing reply failed for ${ctx.senderOpenId}: ${String(err)}`,
);
}
}
} else {
log(
`feishu[${account.accountId}]: blocked unauthorized sender ${ctx.senderOpenId} (dmPolicy=${dmPolicy})`,
);
}
return;
}
const commandAllowFrom = isGroup ? (groupConfig?.allowFrom ?? []) : effectiveDmAllowFrom;
const senderAllowedForCommands = resolveFeishuAllowlistMatch({
allowFrom: commandAllowFrom,
senderId: ctx.senderOpenId,