fix(feishu): accept groupPolicy "allowall" as alias for "open" (#36358)

* 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>
This commit is contained in:
Sid
2026-03-06 01:32:01 +08:00
committed by GitHub
parent 89b303c553
commit 2972d6fa79
5 changed files with 55 additions and 3 deletions

View File

@@ -24,6 +24,14 @@ describe("FeishuConfigSchema webhook validation", () => {
expect(result.accounts?.main?.requireMention).toBeUndefined();
});
it("normalizes legacy groupPolicy allowall to open", () => {
const result = FeishuConfigSchema.parse({
groupPolicy: "allowall",
});
expect(result.groupPolicy).toBe("open");
});
it("rejects top-level webhook mode without verificationToken", () => {
const result = FeishuConfigSchema.safeParse({
connectionMode: "webhook",

View File

@@ -4,7 +4,10 @@ export { z };
import { buildSecretInputSchema, hasConfiguredSecretInput } from "./secret-input.js";
const DmPolicySchema = z.enum(["open", "pairing", "allowlist"]);
const GroupPolicySchema = z.enum(["open", "allowlist", "disabled"]);
const GroupPolicySchema = z.union([
z.enum(["open", "allowlist", "disabled"]),
z.literal("allowall").transform(() => "open" as const),
]);
const FeishuDomainSchema = z.union([
z.enum(["feishu", "lark"]),
z.string().url().startsWith("https://"),

View File

@@ -110,5 +110,45 @@ describe("feishu policy", () => {
}),
).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);
});
});
});

View File

@@ -92,7 +92,7 @@ export function resolveFeishuGroupToolPolicy(
}
export function isFeishuGroupAllowed(params: {
groupPolicy: "open" | "allowlist" | "disabled";
groupPolicy: "open" | "allowlist" | "disabled" | "allowall";
allowFrom: Array<string | number>;
senderId: string;
senderIds?: Array<string | null | undefined>;
@@ -102,7 +102,7 @@ export function isFeishuGroupAllowed(params: {
if (groupPolicy === "disabled") {
return false;
}
if (groupPolicy === "open") {
if (groupPolicy === "open" || groupPolicy === "allowall") {
return true;
}
return resolveFeishuAllowlistMatch(params).allowed;