mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 19:54:32 +00:00
refactor(bluebubbles): share dm/group access policy checks
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { resolveDmAllowState } from "./dm-policy-shared.js";
|
||||
import {
|
||||
resolveDmAllowState,
|
||||
resolveDmGroupAccessDecision,
|
||||
resolveEffectiveAllowFromLists,
|
||||
} from "./dm-policy-shared.js";
|
||||
|
||||
describe("security/dm-policy-shared", () => {
|
||||
it("normalizes config + store allow entries and counts distinct senders", async () => {
|
||||
@@ -28,4 +32,94 @@ describe("security/dm-policy-shared", () => {
|
||||
expect(state.allowCount).toBe(0);
|
||||
expect(state.isMultiUserDm).toBe(false);
|
||||
});
|
||||
|
||||
it("builds effective DM/group allowlists from config + pairing store", () => {
|
||||
const lists = resolveEffectiveAllowFromLists({
|
||||
allowFrom: [" owner ", "", "owner2"],
|
||||
groupAllowFrom: ["group:abc"],
|
||||
storeAllowFrom: [" owner3 ", ""],
|
||||
});
|
||||
expect(lists.effectiveAllowFrom).toEqual(["owner", "owner2", "owner3"]);
|
||||
expect(lists.effectiveGroupAllowFrom).toEqual(["group:abc", "owner3"]);
|
||||
});
|
||||
|
||||
it("falls back to DM allowlist for groups when groupAllowFrom is empty", () => {
|
||||
const lists = resolveEffectiveAllowFromLists({
|
||||
allowFrom: [" owner "],
|
||||
groupAllowFrom: [],
|
||||
storeAllowFrom: [" owner2 "],
|
||||
});
|
||||
expect(lists.effectiveAllowFrom).toEqual(["owner", "owner2"]);
|
||||
expect(lists.effectiveGroupAllowFrom).toEqual(["owner", "owner2"]);
|
||||
});
|
||||
|
||||
const channels = [
|
||||
"bluebubbles",
|
||||
"imessage",
|
||||
"signal",
|
||||
"telegram",
|
||||
"whatsapp",
|
||||
"msteams",
|
||||
"matrix",
|
||||
"zalo",
|
||||
] as const;
|
||||
|
||||
for (const channel of channels) {
|
||||
it(`[${channel}] blocks DM allowlist mode when allowlist is empty`, () => {
|
||||
const decision = resolveDmGroupAccessDecision({
|
||||
isGroup: false,
|
||||
dmPolicy: "allowlist",
|
||||
groupPolicy: "allowlist",
|
||||
effectiveAllowFrom: [],
|
||||
effectiveGroupAllowFrom: [],
|
||||
isSenderAllowed: () => false,
|
||||
});
|
||||
expect(decision).toEqual({
|
||||
decision: "block",
|
||||
reason: "dmPolicy=allowlist (not allowlisted)",
|
||||
});
|
||||
});
|
||||
|
||||
it(`[${channel}] uses pairing flow when DM sender is not allowlisted`, () => {
|
||||
const decision = resolveDmGroupAccessDecision({
|
||||
isGroup: false,
|
||||
dmPolicy: "pairing",
|
||||
groupPolicy: "allowlist",
|
||||
effectiveAllowFrom: [],
|
||||
effectiveGroupAllowFrom: [],
|
||||
isSenderAllowed: () => false,
|
||||
});
|
||||
expect(decision).toEqual({
|
||||
decision: "pairing",
|
||||
reason: "dmPolicy=pairing (not allowlisted)",
|
||||
});
|
||||
});
|
||||
|
||||
it(`[${channel}] allows DM sender when allowlisted`, () => {
|
||||
const decision = resolveDmGroupAccessDecision({
|
||||
isGroup: false,
|
||||
dmPolicy: "allowlist",
|
||||
groupPolicy: "allowlist",
|
||||
effectiveAllowFrom: ["owner"],
|
||||
effectiveGroupAllowFrom: [],
|
||||
isSenderAllowed: () => true,
|
||||
});
|
||||
expect(decision.decision).toBe("allow");
|
||||
});
|
||||
|
||||
it(`[${channel}] blocks group allowlist mode when sender/group is not allowlisted`, () => {
|
||||
const decision = resolveDmGroupAccessDecision({
|
||||
isGroup: true,
|
||||
dmPolicy: "pairing",
|
||||
groupPolicy: "allowlist",
|
||||
effectiveAllowFrom: ["owner"],
|
||||
effectiveGroupAllowFrom: ["group:abc"],
|
||||
isSenderAllowed: () => false,
|
||||
});
|
||||
expect(decision).toEqual({
|
||||
decision: "block",
|
||||
reason: "groupPolicy=allowlist (not allowlisted)",
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user