@openclaw/msteams 2026.3.11 → 2026.3.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/monitor-handler/message-handler.ts +1 -0
- package/src/policy.test.ts +26 -1
- package/src/policy.ts +10 -6
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -175,6 +175,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
|
|
175
175
|
teamName,
|
|
176
176
|
conversationId,
|
|
177
177
|
channelName,
|
|
178
|
+
allowNameMatching: isDangerousNameMatchingEnabled(msteamsCfg),
|
|
178
179
|
});
|
|
179
180
|
const senderGroupPolicy = resolveSenderScopedGroupPolicy({
|
|
180
181
|
groupPolicy,
|
package/src/policy.test.ts
CHANGED
|
@@ -50,7 +50,7 @@ describe("msteams policy", () => {
|
|
|
50
50
|
expect(res.allowed).toBe(false);
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
-
it("
|
|
53
|
+
it("blocks team and channel name matches by default", () => {
|
|
54
54
|
const cfg: MSTeamsConfig = {
|
|
55
55
|
teams: {
|
|
56
56
|
"My Team": {
|
|
@@ -69,6 +69,31 @@ describe("msteams policy", () => {
|
|
|
69
69
|
conversationId: "ignored",
|
|
70
70
|
});
|
|
71
71
|
|
|
72
|
+
expect(res.teamConfig).toBeUndefined();
|
|
73
|
+
expect(res.channelConfig).toBeUndefined();
|
|
74
|
+
expect(res.allowed).toBe(false);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("matches team and channel by name when dangerous name matching is enabled", () => {
|
|
78
|
+
const cfg: MSTeamsConfig = {
|
|
79
|
+
teams: {
|
|
80
|
+
"My Team": {
|
|
81
|
+
requireMention: true,
|
|
82
|
+
channels: {
|
|
83
|
+
"General Chat": { requireMention: false },
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const res = resolveMSTeamsRouteConfig({
|
|
90
|
+
cfg,
|
|
91
|
+
teamName: "My Team",
|
|
92
|
+
channelName: "General Chat",
|
|
93
|
+
conversationId: "ignored",
|
|
94
|
+
allowNameMatching: true,
|
|
95
|
+
});
|
|
96
|
+
|
|
72
97
|
expect(res.teamConfig?.requireMention).toBe(true);
|
|
73
98
|
expect(res.channelConfig?.requireMention).toBe(false);
|
|
74
99
|
expect(res.allowed).toBe(true);
|
package/src/policy.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
resolveToolsBySender,
|
|
17
17
|
resolveChannelEntryMatchWithFallback,
|
|
18
18
|
resolveNestedAllowlistDecision,
|
|
19
|
+
isDangerousNameMatchingEnabled,
|
|
19
20
|
} from "openclaw/plugin-sdk/msteams";
|
|
20
21
|
|
|
21
22
|
export type MSTeamsResolvedRouteConfig = {
|
|
@@ -35,6 +36,7 @@ export function resolveMSTeamsRouteConfig(params: {
|
|
|
35
36
|
teamName?: string | null | undefined;
|
|
36
37
|
conversationId?: string | null | undefined;
|
|
37
38
|
channelName?: string | null | undefined;
|
|
39
|
+
allowNameMatching?: boolean;
|
|
38
40
|
}): MSTeamsResolvedRouteConfig {
|
|
39
41
|
const teamId = params.teamId?.trim();
|
|
40
42
|
const teamName = params.teamName?.trim();
|
|
@@ -44,8 +46,8 @@ export function resolveMSTeamsRouteConfig(params: {
|
|
|
44
46
|
const allowlistConfigured = Object.keys(teams).length > 0;
|
|
45
47
|
const teamCandidates = buildChannelKeyCandidates(
|
|
46
48
|
teamId,
|
|
47
|
-
teamName,
|
|
48
|
-
teamName ? normalizeChannelSlug(teamName) : undefined,
|
|
49
|
+
params.allowNameMatching ? teamName : undefined,
|
|
50
|
+
params.allowNameMatching && teamName ? normalizeChannelSlug(teamName) : undefined,
|
|
49
51
|
);
|
|
50
52
|
const teamMatch = resolveChannelEntryMatchWithFallback({
|
|
51
53
|
entries: teams,
|
|
@@ -58,8 +60,8 @@ export function resolveMSTeamsRouteConfig(params: {
|
|
|
58
60
|
const channelAllowlistConfigured = Object.keys(channels).length > 0;
|
|
59
61
|
const channelCandidates = buildChannelKeyCandidates(
|
|
60
62
|
conversationId,
|
|
61
|
-
channelName,
|
|
62
|
-
channelName ? normalizeChannelSlug(channelName) : undefined,
|
|
63
|
+
params.allowNameMatching ? channelName : undefined,
|
|
64
|
+
params.allowNameMatching && channelName ? normalizeChannelSlug(channelName) : undefined,
|
|
63
65
|
);
|
|
64
66
|
const channelMatch = resolveChannelEntryMatchWithFallback({
|
|
65
67
|
entries: channels,
|
|
@@ -101,6 +103,7 @@ export function resolveMSTeamsGroupToolPolicy(
|
|
|
101
103
|
const groupId = params.groupId?.trim();
|
|
102
104
|
const groupChannel = params.groupChannel?.trim();
|
|
103
105
|
const groupSpace = params.groupSpace?.trim();
|
|
106
|
+
const allowNameMatching = isDangerousNameMatchingEnabled(cfg);
|
|
104
107
|
|
|
105
108
|
const resolved = resolveMSTeamsRouteConfig({
|
|
106
109
|
cfg,
|
|
@@ -108,6 +111,7 @@ export function resolveMSTeamsGroupToolPolicy(
|
|
|
108
111
|
teamName: groupSpace,
|
|
109
112
|
conversationId: groupId,
|
|
110
113
|
channelName: groupChannel,
|
|
114
|
+
allowNameMatching,
|
|
111
115
|
});
|
|
112
116
|
|
|
113
117
|
if (resolved.channelConfig) {
|
|
@@ -158,8 +162,8 @@ export function resolveMSTeamsGroupToolPolicy(
|
|
|
158
162
|
|
|
159
163
|
const channelCandidates = buildChannelKeyCandidates(
|
|
160
164
|
groupId,
|
|
161
|
-
groupChannel,
|
|
162
|
-
groupChannel ? normalizeChannelSlug(groupChannel) : undefined,
|
|
165
|
+
allowNameMatching ? groupChannel : undefined,
|
|
166
|
+
allowNameMatching && groupChannel ? normalizeChannelSlug(groupChannel) : undefined,
|
|
163
167
|
);
|
|
164
168
|
for (const teamConfig of Object.values(cfg.teams ?? {})) {
|
|
165
169
|
const match = resolveChannelEntryMatchWithFallback({
|