

























@@ -21,8 +21,11 @@ const expressControl = vi.hoisted(() => ({
2121}>,
2222}));
232324+const isDangerousNameMatchingEnabled = vi.hoisted(() => vi.fn());
25+2426vi.mock("../runtime-api.js", () => ({
2527DEFAULT_WEBHOOK_MAX_BODY_BYTES: 1024 * 1024,
28+ isDangerousNameMatchingEnabled,
2629normalizeSecretInputString: (value: unknown) =>
2730typeof value === "string" && value.trim() ? value.trim() : undefined,
2831hasConfiguredSecretInput: (value: unknown) =>
@@ -115,14 +118,19 @@ const loadMSTeamsSdkWithAuth = vi.hoisted(() =>
115118);
116119117120vi.mock("./monitor-handler.js", () => ({
118-registerMSTeamsHandlers: () => registerMSTeamsHandlers(),
121+registerMSTeamsHandlers: (...args: unknown[]) => registerMSTeamsHandlers(...args),
119122}));
120123121-vi.mock("./resolve-allowlist.js", () => ({
124+const resolveAllowlistMocks = vi.hoisted(() => ({
122125resolveMSTeamsChannelAllowlist: vi.fn(async () => []),
123126resolveMSTeamsUserAllowlist: vi.fn(async () => []),
124127}));
125128129+vi.mock("./resolve-allowlist.js", () => ({
130+resolveMSTeamsChannelAllowlist: resolveAllowlistMocks.resolveMSTeamsChannelAllowlist,
131+resolveMSTeamsUserAllowlist: resolveAllowlistMocks.resolveMSTeamsUserAllowlist,
132+}));
133+126134vi.mock("./sdk.js", () => ({
127135createMSTeamsAdapter: () => createMSTeamsAdapter(),
128136loadMSTeamsSdkWithAuth: () => loadMSTeamsSdkWithAuth(),
@@ -192,6 +200,9 @@ describe("monitorMSTeamsProvider lifecycle", () => {
192200vi.clearAllMocks();
193201expressControl.mode.value = "listening";
194202expressControl.apps.length = 0;
203+isDangerousNameMatchingEnabled.mockReset().mockReturnValue(false);
204+resolveAllowlistMocks.resolveMSTeamsChannelAllowlist.mockReset().mockResolvedValue([]);
205+resolveAllowlistMocks.resolveMSTeamsUserAllowlist.mockReset().mockResolvedValue([]);
195206jwtValidate.mockReset().mockResolvedValue(true);
196207});
197208@@ -277,4 +288,106 @@ describe("monitorMSTeamsProvider lifecycle", () => {
277288abort.abort();
278289await task;
279290});
291+292+it("does not resolve user allowlists by display name unless name matching is enabled", async () => {
293+const abort = new AbortController();
294+const cfg = createConfig(0);
295+cfg.channels!.msteams = {
296+ ...cfg.channels!.msteams!,
297+allowFrom: ["Alice", "user:40a1a0ed-4ff2-4164-a219-55518990c197"],
298+groupAllowFrom: ["Bob", "msteams:user:50a1a0ed-4ff2-4164-a219-55518990c198"],
299+teams: {
300+Product: {
301+channels: {
302+Roadmap: {},
303+},
304+},
305+},
306+};
307+resolveAllowlistMocks.resolveMSTeamsChannelAllowlist.mockResolvedValueOnce([
308+{
309+input: "Product/Roadmap",
310+resolved: true,
311+teamId: "team-id",
312+channelId: "channel-id",
313+},
314+]);
315+316+const task = monitorMSTeamsProvider({
317+ cfg,
318+runtime: createRuntime(),
319+abortSignal: abort.signal,
320+conversationStore: createStores().conversationStore,
321+pollStore: createStores().pollStore,
322+});
323+324+await vi.waitFor(() => {
325+expect(registerMSTeamsHandlers).toHaveBeenCalled();
326+});
327+328+expect(resolveAllowlistMocks.resolveMSTeamsUserAllowlist).not.toHaveBeenCalled();
329+expect(resolveAllowlistMocks.resolveMSTeamsChannelAllowlist).toHaveBeenCalledWith({
330+ cfg,
331+entries: ["Product/Roadmap"],
332+});
333+334+const registeredCfg = registerMSTeamsHandlers.mock.calls[0]?.[1] as { cfg: OpenClawConfig };
335+expect(registeredCfg.cfg.channels?.msteams?.allowFrom).toEqual([
336+"Alice",
337+"user:40a1a0ed-4ff2-4164-a219-55518990c197",
338+"40a1a0ed-4ff2-4164-a219-55518990c197",
339+]);
340+expect(registeredCfg.cfg.channels?.msteams?.groupAllowFrom).toEqual([
341+"Bob",
342+"msteams:user:50a1a0ed-4ff2-4164-a219-55518990c198",
343+"50a1a0ed-4ff2-4164-a219-55518990c198",
344+]);
345+346+abort.abort();
347+await task;
348+});
349+350+it("resolves user allowlists when name matching is enabled", async () => {
351+isDangerousNameMatchingEnabled.mockReturnValue(true);
352+resolveAllowlistMocks.resolveMSTeamsUserAllowlist
353+.mockResolvedValueOnce([{ input: "Alice", resolved: true, id: "alice-aad" }])
354+.mockResolvedValueOnce([{ input: "Bob", resolved: true, id: "bob-aad" }]);
355+356+const abort = new AbortController();
357+const cfg = createConfig(0);
358+cfg.channels!.msteams = {
359+ ...cfg.channels!.msteams!,
360+dangerouslyAllowNameMatching: true,
361+allowFrom: ["Alice"],
362+groupAllowFrom: ["Bob"],
363+};
364+365+const task = monitorMSTeamsProvider({
366+ cfg,
367+runtime: createRuntime(),
368+abortSignal: abort.signal,
369+conversationStore: createStores().conversationStore,
370+pollStore: createStores().pollStore,
371+});
372+373+await vi.waitFor(() => {
374+expect(registerMSTeamsHandlers).toHaveBeenCalled();
375+});
376+377+expect(resolveAllowlistMocks.resolveMSTeamsUserAllowlist).toHaveBeenNthCalledWith(1, {
378+ cfg,
379+entries: ["Alice"],
380+});
381+expect(resolveAllowlistMocks.resolveMSTeamsUserAllowlist).toHaveBeenNthCalledWith(2, {
382+ cfg,
383+entries: ["Bob"],
384+});
385+386+const registeredCfg = registerMSTeamsHandlers.mock.calls[0]?.[1] as { cfg: OpenClawConfig };
387+expect(registeredCfg.cfg.channels?.msteams?.allowFrom).toEqual(["Alice", "alice-aad"]);
388+expect(registeredCfg.cfg.channels?.msteams?.groupAllowFrom).toEqual(["Bob", "bob-aad"]);
389+390+abort.abort();
391+await task;
392+});
280393});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。