* fix(feishu): accept groupPolicy "allowall" as alias for "open" When users configure groupPolicy: "allowall" in Feishu channel config, the Zod schema rejects the value and the runtime policy check falls through to the allowlist path. With an empty allowFrom array, all group messages are silently dropped despite the intended "allow all" semantics. Accept "allowall" at the schema level (transform to "open") and add a runtime guard in isFeishuGroupAllowed so the value is handled even if it bypasses schema validation. Closes #36312 Made-with: Cursor * Feishu: tighten allowall alias handling and coverage --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
155 lines
4.1 KiB
TypeScript
155 lines
4.1 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
isFeishuGroupAllowed,
|
|
resolveFeishuAllowlistMatch,
|
|
resolveFeishuGroupConfig,
|
|
} from "./policy.js";
|
|
import type { FeishuConfig } from "./types.js";
|
|
|
|
describe("feishu policy", () => {
|
|
describe("resolveFeishuGroupConfig", () => {
|
|
it("falls back to wildcard group config when direct match is missing", () => {
|
|
const cfg = {
|
|
groups: {
|
|
"*": { requireMention: false },
|
|
"oc-explicit": { requireMention: true },
|
|
},
|
|
} as unknown as FeishuConfig;
|
|
|
|
const resolved = resolveFeishuGroupConfig({
|
|
cfg,
|
|
groupId: "oc-missing",
|
|
});
|
|
|
|
expect(resolved).toEqual({ requireMention: false });
|
|
});
|
|
|
|
it("prefers exact group config over wildcard", () => {
|
|
const cfg = {
|
|
groups: {
|
|
"*": { requireMention: false },
|
|
"oc-explicit": { requireMention: true },
|
|
},
|
|
} as unknown as FeishuConfig;
|
|
|
|
const resolved = resolveFeishuGroupConfig({
|
|
cfg,
|
|
groupId: "oc-explicit",
|
|
});
|
|
|
|
expect(resolved).toEqual({ requireMention: true });
|
|
});
|
|
|
|
it("keeps case-insensitive matching for explicit group ids", () => {
|
|
const cfg = {
|
|
groups: {
|
|
"*": { requireMention: false },
|
|
OC_UPPER: { requireMention: true },
|
|
},
|
|
} as unknown as FeishuConfig;
|
|
|
|
const resolved = resolveFeishuGroupConfig({
|
|
cfg,
|
|
groupId: "oc_upper",
|
|
});
|
|
|
|
expect(resolved).toEqual({ requireMention: true });
|
|
});
|
|
});
|
|
|
|
describe("resolveFeishuAllowlistMatch", () => {
|
|
it("allows wildcard", () => {
|
|
expect(
|
|
resolveFeishuAllowlistMatch({
|
|
allowFrom: ["*"],
|
|
senderId: "ou-attacker",
|
|
}),
|
|
).toEqual({ allowed: true, matchKey: "*", matchSource: "wildcard" });
|
|
});
|
|
|
|
it("matches normalized ID entries", () => {
|
|
expect(
|
|
resolveFeishuAllowlistMatch({
|
|
allowFrom: ["feishu:user:OU_ALLOWED"],
|
|
senderId: "ou_allowed",
|
|
}),
|
|
).toEqual({ allowed: true, matchKey: "ou_allowed", matchSource: "id" });
|
|
});
|
|
|
|
it("supports user_id as an additional immutable sender candidate", () => {
|
|
expect(
|
|
resolveFeishuAllowlistMatch({
|
|
allowFrom: ["on_user_123"],
|
|
senderId: "ou_other",
|
|
senderIds: ["on_user_123"],
|
|
}),
|
|
).toEqual({ allowed: true, matchKey: "on_user_123", matchSource: "id" });
|
|
});
|
|
|
|
it("does not authorize based on display-name collision", () => {
|
|
const victimOpenId = "ou_4f4ec5aa111122223333444455556666";
|
|
|
|
expect(
|
|
resolveFeishuAllowlistMatch({
|
|
allowFrom: [victimOpenId],
|
|
senderId: "ou_attacker_real_open_id",
|
|
senderIds: ["on_attacker_user_id"],
|
|
senderName: victimOpenId,
|
|
}),
|
|
).toEqual({ allowed: false });
|
|
});
|
|
});
|
|
|
|
describe("isFeishuGroupAllowed", () => {
|
|
it("matches group IDs with chat: prefix", () => {
|
|
expect(
|
|
isFeishuGroupAllowed({
|
|
groupPolicy: "allowlist",
|
|
allowFrom: ["chat:oc_group_123"],
|
|
senderId: "oc_group_123",
|
|
}),
|
|
).toBe(true);
|
|
});
|
|
|
|
it("allows group when groupPolicy is 'open'", () => {
|
|
expect(
|
|
isFeishuGroupAllowed({
|
|
groupPolicy: "open",
|
|
allowFrom: [],
|
|
senderId: "oc_group_999",
|
|
}),
|
|
).toBe(true);
|
|
});
|
|
|
|
it("treats 'allowall' as equivalent to 'open'", () => {
|
|
expect(
|
|
isFeishuGroupAllowed({
|
|
groupPolicy: "allowall",
|
|
allowFrom: [],
|
|
senderId: "oc_group_999",
|
|
}),
|
|
).toBe(true);
|
|
});
|
|
|
|
it("rejects group when groupPolicy is 'disabled'", () => {
|
|
expect(
|
|
isFeishuGroupAllowed({
|
|
groupPolicy: "disabled",
|
|
allowFrom: ["oc_group_999"],
|
|
senderId: "oc_group_999",
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("rejects group when groupPolicy is 'allowlist' and allowFrom is empty", () => {
|
|
expect(
|
|
isFeishuGroupAllowed({
|
|
groupPolicy: "allowlist",
|
|
allowFrom: [],
|
|
senderId: "oc_group_999",
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
});
|
|
});
|