mirror of https://github.com/openclaw/openclaw.git
115 lines
3.4 KiB
TypeScript
115 lines
3.4 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import type { OpenClawConfig } from "../../config/config.js";
|
|
import {
|
|
buildAccountScopedDmSecurityPolicy,
|
|
formatPairingApproveHint,
|
|
parseOptionalDelimitedEntries,
|
|
} from "./helpers.js";
|
|
|
|
function cfgWithChannel(channelKey: string, accounts?: Record<string, unknown>): OpenClawConfig {
|
|
return {
|
|
channels: {
|
|
[channelKey]: accounts ? { accounts } : {},
|
|
},
|
|
} as unknown as OpenClawConfig;
|
|
}
|
|
|
|
describe("buildAccountScopedDmSecurityPolicy", () => {
|
|
it("builds top-level dm policy paths when no account config exists", () => {
|
|
expect(
|
|
buildAccountScopedDmSecurityPolicy({
|
|
cfg: cfgWithChannel("telegram"),
|
|
channelKey: "telegram",
|
|
fallbackAccountId: "default",
|
|
policy: "pairing",
|
|
allowFrom: ["123"],
|
|
policyPathSuffix: "dmPolicy",
|
|
}),
|
|
).toEqual({
|
|
policy: "pairing",
|
|
allowFrom: ["123"],
|
|
policyPath: "channels.telegram.dmPolicy",
|
|
allowFromPath: "channels.telegram.",
|
|
approveHint: formatPairingApproveHint("telegram"),
|
|
normalizeEntry: undefined,
|
|
});
|
|
});
|
|
|
|
it("uses account-scoped paths when account config exists", () => {
|
|
expect(
|
|
buildAccountScopedDmSecurityPolicy({
|
|
cfg: cfgWithChannel("signal", { work: {} }),
|
|
channelKey: "signal",
|
|
accountId: "work",
|
|
fallbackAccountId: "default",
|
|
policy: "allowlist",
|
|
allowFrom: ["+12125551212"],
|
|
policyPathSuffix: "dmPolicy",
|
|
}),
|
|
).toEqual({
|
|
policy: "allowlist",
|
|
allowFrom: ["+12125551212"],
|
|
policyPath: "channels.signal.accounts.work.dmPolicy",
|
|
allowFromPath: "channels.signal.accounts.work.",
|
|
approveHint: formatPairingApproveHint("signal"),
|
|
normalizeEntry: undefined,
|
|
});
|
|
});
|
|
|
|
it("supports nested dm paths without explicit policyPath", () => {
|
|
expect(
|
|
buildAccountScopedDmSecurityPolicy({
|
|
cfg: cfgWithChannel("discord", { work: {} }),
|
|
channelKey: "discord",
|
|
accountId: "work",
|
|
policy: "pairing",
|
|
allowFrom: [],
|
|
allowFromPathSuffix: "dm.",
|
|
}),
|
|
).toEqual({
|
|
policy: "pairing",
|
|
allowFrom: [],
|
|
policyPath: undefined,
|
|
allowFromPath: "channels.discord.accounts.work.dm.",
|
|
approveHint: formatPairingApproveHint("discord"),
|
|
normalizeEntry: undefined,
|
|
});
|
|
});
|
|
|
|
it("supports custom defaults and approve hints", () => {
|
|
expect(
|
|
buildAccountScopedDmSecurityPolicy({
|
|
cfg: cfgWithChannel("synology-chat"),
|
|
channelKey: "synology-chat",
|
|
fallbackAccountId: "default",
|
|
allowFrom: ["user-1"],
|
|
defaultPolicy: "allowlist",
|
|
policyPathSuffix: "dmPolicy",
|
|
approveHint: "openclaw pairing approve synology-chat <code>",
|
|
}),
|
|
).toEqual({
|
|
policy: "allowlist",
|
|
allowFrom: ["user-1"],
|
|
policyPath: "channels.synology-chat.dmPolicy",
|
|
allowFromPath: "channels.synology-chat.",
|
|
approveHint: "openclaw pairing approve synology-chat <code>",
|
|
normalizeEntry: undefined,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("parseOptionalDelimitedEntries", () => {
|
|
it("returns undefined for empty input", () => {
|
|
expect(parseOptionalDelimitedEntries(" ")).toBeUndefined();
|
|
});
|
|
|
|
it("splits comma, newline, and semicolon separated entries", () => {
|
|
expect(parseOptionalDelimitedEntries("alpha, beta\ngamma; delta")).toEqual([
|
|
"alpha",
|
|
"beta",
|
|
"gamma",
|
|
"delta",
|
|
]);
|
|
});
|
|
});
|