mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-14 11:30:41 +00:00
Adds IRC as a first-class channel with core config surfaces (schema/hints/dock), plugin auto-enable detection, routing/policy alignment, and docs/tests. Co-authored-by: Vignesh <vigneshnatarajan92@gmail.com>
133 lines
3.7 KiB
TypeScript
133 lines
3.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { resolveChannelGroupPolicy } from "../../../src/config/group-policy.js";
|
|
import {
|
|
resolveIrcGroupAccessGate,
|
|
resolveIrcGroupMatch,
|
|
resolveIrcGroupSenderAllowed,
|
|
resolveIrcMentionGate,
|
|
resolveIrcRequireMention,
|
|
} from "./policy.js";
|
|
|
|
describe("irc policy", () => {
|
|
it("matches direct and wildcard group entries", () => {
|
|
const direct = resolveIrcGroupMatch({
|
|
groups: {
|
|
"#ops": { requireMention: false },
|
|
},
|
|
target: "#ops",
|
|
});
|
|
expect(direct.allowed).toBe(true);
|
|
expect(resolveIrcRequireMention({ groupConfig: direct.groupConfig })).toBe(false);
|
|
|
|
const wildcard = resolveIrcGroupMatch({
|
|
groups: {
|
|
"*": { requireMention: true },
|
|
},
|
|
target: "#random",
|
|
});
|
|
expect(wildcard.allowed).toBe(true);
|
|
expect(resolveIrcRequireMention({ wildcardConfig: wildcard.wildcardConfig })).toBe(true);
|
|
});
|
|
|
|
it("enforces allowlist by default in groups", () => {
|
|
const message = {
|
|
messageId: "m1",
|
|
target: "#ops",
|
|
senderNick: "alice",
|
|
senderUser: "ident",
|
|
senderHost: "example.org",
|
|
text: "hi",
|
|
timestamp: Date.now(),
|
|
isGroup: true,
|
|
};
|
|
|
|
expect(
|
|
resolveIrcGroupSenderAllowed({
|
|
groupPolicy: "allowlist",
|
|
message,
|
|
outerAllowFrom: [],
|
|
innerAllowFrom: [],
|
|
}),
|
|
).toBe(false);
|
|
|
|
expect(
|
|
resolveIrcGroupSenderAllowed({
|
|
groupPolicy: "allowlist",
|
|
message,
|
|
outerAllowFrom: ["alice"],
|
|
innerAllowFrom: [],
|
|
}),
|
|
).toBe(true);
|
|
});
|
|
|
|
it('allows unconfigured channels when groupPolicy is "open"', () => {
|
|
const groupMatch = resolveIrcGroupMatch({
|
|
groups: undefined,
|
|
target: "#random",
|
|
});
|
|
const gate = resolveIrcGroupAccessGate({
|
|
groupPolicy: "open",
|
|
groupMatch,
|
|
});
|
|
expect(gate.allowed).toBe(true);
|
|
expect(gate.reason).toBe("open");
|
|
});
|
|
|
|
it("honors explicit group disable even in open mode", () => {
|
|
const groupMatch = resolveIrcGroupMatch({
|
|
groups: {
|
|
"#ops": { enabled: false },
|
|
},
|
|
target: "#ops",
|
|
});
|
|
const gate = resolveIrcGroupAccessGate({
|
|
groupPolicy: "open",
|
|
groupMatch,
|
|
});
|
|
expect(gate.allowed).toBe(false);
|
|
expect(gate.reason).toBe("disabled");
|
|
});
|
|
|
|
it("allows authorized control commands without mention", () => {
|
|
const gate = resolveIrcMentionGate({
|
|
isGroup: true,
|
|
requireMention: true,
|
|
wasMentioned: false,
|
|
hasControlCommand: true,
|
|
allowTextCommands: true,
|
|
commandAuthorized: true,
|
|
});
|
|
expect(gate.shouldSkip).toBe(false);
|
|
});
|
|
|
|
it("keeps case-insensitive group matching aligned with shared channel policy resolution", () => {
|
|
const groups = {
|
|
"#Ops": { requireMention: false },
|
|
"#Hidden": { enabled: false },
|
|
"*": { requireMention: true },
|
|
};
|
|
|
|
const inboundDirect = resolveIrcGroupMatch({ groups, target: "#ops" });
|
|
const sharedDirect = resolveChannelGroupPolicy({
|
|
cfg: { channels: { irc: { groups } } },
|
|
channel: "irc",
|
|
groupId: "#ops",
|
|
groupIdCaseInsensitive: true,
|
|
});
|
|
expect(sharedDirect.allowed).toBe(inboundDirect.allowed);
|
|
expect(sharedDirect.groupConfig?.requireMention).toBe(
|
|
inboundDirect.groupConfig?.requireMention,
|
|
);
|
|
|
|
const inboundDisabled = resolveIrcGroupMatch({ groups, target: "#hidden" });
|
|
const sharedDisabled = resolveChannelGroupPolicy({
|
|
cfg: { channels: { irc: { groups } } },
|
|
channel: "irc",
|
|
groupId: "#hidden",
|
|
groupIdCaseInsensitive: true,
|
|
});
|
|
expect(sharedDisabled.allowed).toBe(inboundDisabled.allowed);
|
|
expect(sharedDisabled.groupConfig?.enabled).toBe(inboundDisabled.groupConfig?.enabled);
|
|
});
|
|
});
|