mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-30 02:22:25 +00:00
refactor: harden plugin install flow and main DM route pinning
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
resolveDmGroupAccessDecision,
|
||||
resolveDmGroupAccessWithLists,
|
||||
resolveEffectiveAllowFromLists,
|
||||
resolvePinnedMainDmOwnerFromAllowlist,
|
||||
} from "./dm-policy-shared.js";
|
||||
|
||||
describe("security/dm-policy-shared", () => {
|
||||
@@ -106,6 +107,43 @@ describe("security/dm-policy-shared", () => {
|
||||
expect(lists.effectiveGroupAllowFrom).toEqual([]);
|
||||
});
|
||||
|
||||
it("infers pinned main DM owner from a single configured allowlist entry", () => {
|
||||
const pinnedOwner = resolvePinnedMainDmOwnerFromAllowlist({
|
||||
dmScope: "main",
|
||||
allowFrom: [" line:user:U123 "],
|
||||
normalizeEntry: (entry) =>
|
||||
entry
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/^line:(?:user:)?/, ""),
|
||||
});
|
||||
expect(pinnedOwner).toBe("u123");
|
||||
});
|
||||
|
||||
it("does not infer pinned owner for wildcard/multi-owner/non-main scope", () => {
|
||||
expect(
|
||||
resolvePinnedMainDmOwnerFromAllowlist({
|
||||
dmScope: "main",
|
||||
allowFrom: ["*"],
|
||||
normalizeEntry: (entry) => entry.trim(),
|
||||
}),
|
||||
).toBeNull();
|
||||
expect(
|
||||
resolvePinnedMainDmOwnerFromAllowlist({
|
||||
dmScope: "main",
|
||||
allowFrom: ["u123", "u456"],
|
||||
normalizeEntry: (entry) => entry.trim(),
|
||||
}),
|
||||
).toBeNull();
|
||||
expect(
|
||||
resolvePinnedMainDmOwnerFromAllowlist({
|
||||
dmScope: "per-channel-peer",
|
||||
allowFrom: ["u123"],
|
||||
normalizeEntry: (entry) => entry.trim(),
|
||||
}),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it("excludes storeAllowFrom when dmPolicy is allowlist", () => {
|
||||
const lists = resolveEffectiveAllowFromLists({
|
||||
allowFrom: ["+1111"],
|
||||
|
||||
@@ -4,6 +4,28 @@ import type { ChannelId } from "../channels/plugins/types.js";
|
||||
import { readChannelAllowFromStore } from "../pairing/pairing-store.js";
|
||||
import { normalizeStringEntries } from "../shared/string-normalization.js";
|
||||
|
||||
export function resolvePinnedMainDmOwnerFromAllowlist(params: {
|
||||
dmScope?: string | null;
|
||||
allowFrom?: Array<string | number> | null;
|
||||
normalizeEntry: (entry: string) => string | undefined;
|
||||
}): string | null {
|
||||
if ((params.dmScope ?? "main") !== "main") {
|
||||
return null;
|
||||
}
|
||||
const rawAllowFrom = Array.isArray(params.allowFrom) ? params.allowFrom : [];
|
||||
if (rawAllowFrom.some((entry) => String(entry).trim() === "*")) {
|
||||
return null;
|
||||
}
|
||||
const normalizedOwners = Array.from(
|
||||
new Set(
|
||||
rawAllowFrom
|
||||
.map((entry) => params.normalizeEntry(String(entry)))
|
||||
.filter((entry): entry is string => Boolean(entry)),
|
||||
),
|
||||
);
|
||||
return normalizedOwners.length === 1 ? normalizedOwners[0] : null;
|
||||
}
|
||||
|
||||
export function resolveEffectiveAllowFromLists(params: {
|
||||
allowFrom?: Array<string | number> | null;
|
||||
groupAllowFrom?: Array<string | number> | null;
|
||||
|
||||
Reference in New Issue
Block a user