@openclaw/msteams 2026.5.14-beta.1 → 2026.5.14-beta.2
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/dist/api.js +2 -2
- package/dist/{channel-C7J7iUD1.js → channel-C5CVTygn.js} +138 -8
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-B14HY4Hr.js → channel.runtime-fqvE_yLN.js} +2 -2
- package/dist/contract-api.js +1 -1
- package/dist/{graph-users-OieoCBxW.js → graph-users-ChPPxUzD.js} +44 -23
- package/dist/{oauth-BWJyilR1.js → oauth-DsVj42gA.js} +1 -1
- package/dist/{oauth.token-xxpoLWy5.js → oauth.token-mUfXUE0j.js} +2 -1
- package/dist/{probe-D3LwpZwU.js → probe-I2DM0U-s.js} +2 -2
- package/dist/secret-contract-api.js +1 -1
- package/dist/setup-plugin-api.js +2 -2
- package/dist/{setup-surface-D9_2tf9Q.js → setup-surface-CQrMX-nJ.js} +220 -4
- package/dist/{src-CBRN2aXw.js → src-CYZq-lQ4.js} +4 -4
- package/dist/test-api.js +1 -1
- package/package.json +6 -6
- package/dist/policy-bM71GXRd.js +0 -134
- package/dist/resolve-allowlist-DWp32o4l.js +0 -219
- /package/dist/{secret-contract-BuoEXmPS.js → secret-contract-DDPQm4fE.js} +0 -0
package/dist/api.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import {
|
|
1
|
+
import { i as msteamsSetupAdapter, n as openDelegatedOAuthUrl, r as createMSTeamsSetupWizardBase, t as msteamsSetupWizard } from "./setup-surface-CQrMX-nJ.js";
|
|
2
|
+
import { t as msteamsPlugin } from "./channel-C5CVTygn.js";
|
|
3
3
|
export { createMSTeamsSetupWizardBase, msteamsPlugin, msteamsSetupAdapter, msteamsSetupWizard, openDelegatedOAuthUrl };
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { o as buildProbeChannelStatusSummary, r as PAIRING_APPROVED_MESSAGE, s as chunkTextForOutbound, t as DEFAULT_ACCOUNT_ID, u as createDefaultChannelRuntimeState } from "./runtime-api-C3EIaIpt.js";
|
|
2
|
-
import { h as resolveMSTeamsCredentials } from "./graph-users-
|
|
3
|
-
import { a as
|
|
1
|
+
import { O as resolveNestedAllowlistDecision, S as normalizeChannelSlug, T as resolveChannelEntryMatchWithFallback, _ as isDangerousNameMatchingEnabled, i as buildChannelKeyCandidates, k as resolveToolsBySender, o as buildProbeChannelStatusSummary, r as PAIRING_APPROVED_MESSAGE, s as chunkTextForOutbound, t as DEFAULT_ACCOUNT_ID, u as createDefaultChannelRuntimeState, w as resolveAllowlistMatchSimple } from "./runtime-api-C3EIaIpt.js";
|
|
2
|
+
import { h as resolveMSTeamsCredentials } from "./graph-users-ChPPxUzD.js";
|
|
3
|
+
import { a as looksLikeMSTeamsTargetId, c as parseMSTeamsConversationId, d as resolveMSTeamsUserAllowlist, i as msteamsSetupAdapter, l as parseMSTeamsTeamChannelInput, o as normalizeMSTeamsMessagingTarget, s as normalizeMSTeamsUserInput, t as msteamsSetupWizard, u as resolveMSTeamsChannelAllowlist } from "./setup-surface-CQrMX-nJ.js";
|
|
4
4
|
import { t as MSTeamsChannelConfigSchema } from "./config-schema-DwOEthCC.js";
|
|
5
|
-
import { n as resolveMSTeamsGroupToolPolicy } from "./policy-bM71GXRd.js";
|
|
6
|
-
import { i as msteamsSetupAdapter, t as msteamsSetupWizard } from "./setup-surface-D9_2tf9Q.js";
|
|
7
5
|
import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
|
|
8
6
|
import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
|
|
9
7
|
import { createTopLevelChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
@@ -67,6 +65,138 @@ const collectMSTeamsMutableAllowlistWarnings = createDangerousNameMatchingMutabl
|
|
|
67
65
|
}]
|
|
68
66
|
});
|
|
69
67
|
//#endregion
|
|
68
|
+
//#region extensions/msteams/src/policy.ts
|
|
69
|
+
function resolveMSTeamsRouteConfig(params) {
|
|
70
|
+
const teamId = params.teamId?.trim();
|
|
71
|
+
const teamName = params.teamName?.trim();
|
|
72
|
+
const conversationId = params.conversationId?.trim();
|
|
73
|
+
const channelName = params.channelName?.trim();
|
|
74
|
+
const teams = params.cfg?.teams ?? {};
|
|
75
|
+
const allowlistConfigured = Object.keys(teams).length > 0;
|
|
76
|
+
const teamMatch = resolveChannelEntryMatchWithFallback({
|
|
77
|
+
entries: teams,
|
|
78
|
+
keys: buildChannelKeyCandidates(teamId, params.allowNameMatching ? teamName : void 0, params.allowNameMatching && teamName ? normalizeChannelSlug(teamName) : void 0),
|
|
79
|
+
wildcardKey: "*",
|
|
80
|
+
normalizeKey: normalizeChannelSlug
|
|
81
|
+
});
|
|
82
|
+
const teamConfig = teamMatch.entry;
|
|
83
|
+
const channels = teamConfig?.channels ?? {};
|
|
84
|
+
const channelAllowlistConfigured = Object.keys(channels).length > 0;
|
|
85
|
+
const channelMatch = resolveChannelEntryMatchWithFallback({
|
|
86
|
+
entries: channels,
|
|
87
|
+
keys: buildChannelKeyCandidates(conversationId, params.allowNameMatching ? channelName : void 0, params.allowNameMatching && channelName ? normalizeChannelSlug(channelName) : void 0),
|
|
88
|
+
wildcardKey: "*",
|
|
89
|
+
normalizeKey: normalizeChannelSlug
|
|
90
|
+
});
|
|
91
|
+
const channelConfig = channelMatch.entry;
|
|
92
|
+
return {
|
|
93
|
+
teamConfig,
|
|
94
|
+
channelConfig,
|
|
95
|
+
allowlistConfigured,
|
|
96
|
+
allowed: resolveNestedAllowlistDecision({
|
|
97
|
+
outerConfigured: allowlistConfigured,
|
|
98
|
+
outerMatched: Boolean(teamConfig),
|
|
99
|
+
innerConfigured: channelAllowlistConfigured,
|
|
100
|
+
innerMatched: Boolean(channelConfig)
|
|
101
|
+
}),
|
|
102
|
+
teamKey: teamMatch.matchKey ?? teamMatch.key,
|
|
103
|
+
channelKey: channelMatch.matchKey ?? channelMatch.key,
|
|
104
|
+
channelMatchKey: channelMatch.matchKey,
|
|
105
|
+
channelMatchSource: channelMatch.matchSource === "direct" || channelMatch.matchSource === "wildcard" ? channelMatch.matchSource : void 0
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function resolveMSTeamsGroupToolPolicy(params) {
|
|
109
|
+
const cfg = params.cfg.channels?.msteams;
|
|
110
|
+
if (!cfg) return;
|
|
111
|
+
const groupId = params.groupId?.trim();
|
|
112
|
+
const groupChannel = params.groupChannel?.trim();
|
|
113
|
+
const groupSpace = params.groupSpace?.trim();
|
|
114
|
+
const allowNameMatching = isDangerousNameMatchingEnabled(cfg);
|
|
115
|
+
const resolved = resolveMSTeamsRouteConfig({
|
|
116
|
+
cfg,
|
|
117
|
+
teamId: groupSpace,
|
|
118
|
+
teamName: groupSpace,
|
|
119
|
+
conversationId: groupId,
|
|
120
|
+
channelName: groupChannel,
|
|
121
|
+
allowNameMatching
|
|
122
|
+
});
|
|
123
|
+
if (resolved.channelConfig) {
|
|
124
|
+
const senderPolicy = resolveToolsBySender({
|
|
125
|
+
toolsBySender: resolved.channelConfig.toolsBySender,
|
|
126
|
+
senderId: params.senderId,
|
|
127
|
+
senderName: params.senderName,
|
|
128
|
+
senderUsername: params.senderUsername,
|
|
129
|
+
senderE164: params.senderE164
|
|
130
|
+
});
|
|
131
|
+
if (senderPolicy) return senderPolicy;
|
|
132
|
+
if (resolved.channelConfig.tools) return resolved.channelConfig.tools;
|
|
133
|
+
const teamSenderPolicy = resolveToolsBySender({
|
|
134
|
+
toolsBySender: resolved.teamConfig?.toolsBySender,
|
|
135
|
+
senderId: params.senderId,
|
|
136
|
+
senderName: params.senderName,
|
|
137
|
+
senderUsername: params.senderUsername,
|
|
138
|
+
senderE164: params.senderE164
|
|
139
|
+
});
|
|
140
|
+
if (teamSenderPolicy) return teamSenderPolicy;
|
|
141
|
+
return resolved.teamConfig?.tools;
|
|
142
|
+
}
|
|
143
|
+
if (resolved.teamConfig) {
|
|
144
|
+
const teamSenderPolicy = resolveToolsBySender({
|
|
145
|
+
toolsBySender: resolved.teamConfig.toolsBySender,
|
|
146
|
+
senderId: params.senderId,
|
|
147
|
+
senderName: params.senderName,
|
|
148
|
+
senderUsername: params.senderUsername,
|
|
149
|
+
senderE164: params.senderE164
|
|
150
|
+
});
|
|
151
|
+
if (teamSenderPolicy) return teamSenderPolicy;
|
|
152
|
+
if (resolved.teamConfig.tools) return resolved.teamConfig.tools;
|
|
153
|
+
}
|
|
154
|
+
if (!groupId) return;
|
|
155
|
+
const channelCandidates = buildChannelKeyCandidates(groupId, allowNameMatching ? groupChannel : void 0, allowNameMatching && groupChannel ? normalizeChannelSlug(groupChannel) : void 0);
|
|
156
|
+
for (const teamConfig of Object.values(cfg.teams ?? {})) {
|
|
157
|
+
const match = resolveChannelEntryMatchWithFallback({
|
|
158
|
+
entries: teamConfig?.channels ?? {},
|
|
159
|
+
keys: channelCandidates,
|
|
160
|
+
wildcardKey: "*",
|
|
161
|
+
normalizeKey: normalizeChannelSlug
|
|
162
|
+
});
|
|
163
|
+
if (match.entry) {
|
|
164
|
+
const senderPolicy = resolveToolsBySender({
|
|
165
|
+
toolsBySender: match.entry.toolsBySender,
|
|
166
|
+
senderId: params.senderId,
|
|
167
|
+
senderName: params.senderName,
|
|
168
|
+
senderUsername: params.senderUsername,
|
|
169
|
+
senderE164: params.senderE164
|
|
170
|
+
});
|
|
171
|
+
if (senderPolicy) return senderPolicy;
|
|
172
|
+
if (match.entry.tools) return match.entry.tools;
|
|
173
|
+
const teamSenderPolicy = resolveToolsBySender({
|
|
174
|
+
toolsBySender: teamConfig?.toolsBySender,
|
|
175
|
+
senderId: params.senderId,
|
|
176
|
+
senderName: params.senderName,
|
|
177
|
+
senderUsername: params.senderUsername,
|
|
178
|
+
senderE164: params.senderE164
|
|
179
|
+
});
|
|
180
|
+
if (teamSenderPolicy) return teamSenderPolicy;
|
|
181
|
+
return teamConfig?.tools;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function resolveMSTeamsAllowlistMatch(params) {
|
|
186
|
+
return resolveAllowlistMatchSimple(params);
|
|
187
|
+
}
|
|
188
|
+
function resolveMSTeamsReplyPolicy(params) {
|
|
189
|
+
if (params.isDirectMessage) return {
|
|
190
|
+
requireMention: false,
|
|
191
|
+
replyStyle: "thread"
|
|
192
|
+
};
|
|
193
|
+
const requireMention = params.channelConfig?.requireMention ?? params.teamConfig?.requireMention ?? params.globalConfig?.requireMention ?? true;
|
|
194
|
+
return {
|
|
195
|
+
requireMention,
|
|
196
|
+
replyStyle: params.channelConfig?.replyStyle ?? params.teamConfig?.replyStyle ?? params.globalConfig?.replyStyle ?? (requireMention ? "thread" : "top-level")
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
//#endregion
|
|
70
200
|
//#region extensions/msteams/src/presentation.ts
|
|
71
201
|
function buildMSTeamsPresentationCard(params) {
|
|
72
202
|
const body = [];
|
|
@@ -183,7 +313,7 @@ const collectMSTeamsSecurityWarnings = createAllowlistProviderGroupPolicyWarning
|
|
|
183
313
|
resolveGroupPolicy: ({ cfg }) => cfg.channels?.msteams?.groupPolicy,
|
|
184
314
|
collect: ({ groupPolicy }) => groupPolicy === "open" ? ["- MS Teams groups: groupPolicy=\"open\" allows any member to trigger (mention-gated). Set channels.msteams.groupPolicy=\"allowlist\" + channels.msteams.groupAllowFrom to restrict senders."] : []
|
|
185
315
|
});
|
|
186
|
-
const loadMSTeamsChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-
|
|
316
|
+
const loadMSTeamsChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-fqvE_yLN.js"), "msTeamsChannelRuntime");
|
|
187
317
|
const resolveMSTeamsChannelConfig = (cfg) => ({
|
|
188
318
|
allowFrom: cfg.channels?.msteams?.allowFrom,
|
|
189
319
|
defaultTo: cfg.channels?.msteams?.defaultTo
|
|
@@ -965,7 +1095,7 @@ const msteamsPlugin = createChatChannelPlugin({
|
|
|
965
1095
|
})
|
|
966
1096
|
}),
|
|
967
1097
|
gateway: { startAccount: async (ctx) => {
|
|
968
|
-
const { monitorMSTeamsProvider } = await import("./src-
|
|
1098
|
+
const { monitorMSTeamsProvider } = await import("./src-CYZq-lQ4.js");
|
|
969
1099
|
const port = ctx.cfg.channels?.msteams?.webhook?.port ?? 3978;
|
|
970
1100
|
ctx.setStatus({
|
|
971
1101
|
accountId: ctx.accountId,
|
|
@@ -1006,4 +1136,4 @@ const msteamsPlugin = createChatChannelPlugin({
|
|
|
1006
1136
|
outbound: msteamsChannelOutbound
|
|
1007
1137
|
});
|
|
1008
1138
|
//#endregion
|
|
1009
|
-
export { msteamsPlugin as t };
|
|
1139
|
+
export { resolveMSTeamsRouteConfig as i, resolveMSTeamsAllowlistMatch as n, resolveMSTeamsReplyPolicy as r, msteamsPlugin as t };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as msteamsPlugin } from "./channel-
|
|
1
|
+
import { t as msteamsPlugin } from "./channel-C5CVTygn.js";
|
|
2
2
|
export { msteamsPlugin };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { s as chunkTextForOutbound } from "./runtime-api-C3EIaIpt.js";
|
|
2
|
-
import { a as fetchGraphJson, c as normalizeQuery, d as postGraphJson, f as resolveGraphToken, i as fetchGraphAbsoluteUrl, l as patchGraphJson, n as deleteGraphRequest, o as listChannelsForTeam, r as escapeOData, s as listTeamsByName, t as searchGraphUsers, u as postGraphBetaJson } from "./graph-users-
|
|
3
|
-
import { S as createMSTeamsConversationStoreFs, a as sendMessageMSTeams, b as createMSTeamsPollStoreFs, i as sendAdaptiveCardMSTeams, n as deleteMessageMSTeams, o as sendPollMSTeams, r as editMessageMSTeams, t as probeMSTeams } from "./probe-
|
|
2
|
+
import { a as fetchGraphJson, c as normalizeQuery, d as postGraphJson, f as resolveGraphToken, i as fetchGraphAbsoluteUrl, l as patchGraphJson, n as deleteGraphRequest, o as listChannelsForTeam, r as escapeOData, s as listTeamsByName, t as searchGraphUsers, u as postGraphBetaJson } from "./graph-users-ChPPxUzD.js";
|
|
3
|
+
import { S as createMSTeamsConversationStoreFs, a as sendMessageMSTeams, b as createMSTeamsPollStoreFs, i as sendAdaptiveCardMSTeams, n as deleteMessageMSTeams, o as sendPollMSTeams, r as editMessageMSTeams, t as probeMSTeams } from "./probe-I2DM0U-s.js";
|
|
4
4
|
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
5
|
import { createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
|
|
6
6
|
import { resolveOutboundSendDep } from "openclaw/plugin-sdk/outbound-send-deps";
|
package/dist/contract-api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-
|
|
1
|
+
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-DDPQm4fE.js";
|
|
2
2
|
export { collectRuntimeConfigAssignments, secretTargetRegistryEntries };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { M as getMSTeamsRuntime, h as fetchWithSsrFGuard$1 } from "./runtime-api-C3EIaIpt.js";
|
|
2
|
-
import { n as refreshMSTeamsDelegatedTokens } from "./oauth.token-
|
|
2
|
+
import { n as refreshMSTeamsDelegatedTokens } from "./oauth.token-mUfXUE0j.js";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { isRecord as isRecord$2, normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
5
|
import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
6
|
+
import { readProviderJsonResponse } from "openclaw/plugin-sdk/provider-http";
|
|
6
7
|
import { Buffer } from "node:buffer";
|
|
7
8
|
import { lookup } from "node:dns/promises";
|
|
8
9
|
import { buildHostnameAllowlistPolicyFromSuffixAllowlist, isHttpsUrlAllowedByHostnameSuffixAllowlist, isPrivateIpAddress, normalizeHostnameSuffixAllowlist } from "openclaw/plugin-sdk/ssrf-policy";
|
|
@@ -1195,6 +1196,12 @@ async function resolveDelegatedAccessToken(params) {
|
|
|
1195
1196
|
//#endregion
|
|
1196
1197
|
//#region extensions/msteams/src/graph.ts
|
|
1197
1198
|
const GRAPH_BETA = "https://graph.microsoft.com/beta";
|
|
1199
|
+
const NULL_BODY_STATUSES = new Set([
|
|
1200
|
+
101,
|
|
1201
|
+
204,
|
|
1202
|
+
205,
|
|
1203
|
+
304
|
|
1204
|
+
]);
|
|
1198
1205
|
function normalizeQuery(value) {
|
|
1199
1206
|
return value?.trim() ?? "";
|
|
1200
1207
|
}
|
|
@@ -1203,25 +1210,41 @@ function escapeOData(value) {
|
|
|
1203
1210
|
}
|
|
1204
1211
|
async function requestGraph(params) {
|
|
1205
1212
|
const hasBody = params.body !== void 0;
|
|
1206
|
-
const
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
+
const url = `${params.root ?? "https://graph.microsoft.com/v1.0"}${params.path}`;
|
|
1214
|
+
const currentFetch = globalThis.fetch;
|
|
1215
|
+
const { response, release } = await fetchWithSsrFGuard$1({
|
|
1216
|
+
url,
|
|
1217
|
+
fetchImpl: async (input, guardedInit) => await currentFetch(input, guardedInit),
|
|
1218
|
+
init: {
|
|
1219
|
+
method: params.method,
|
|
1220
|
+
headers: {
|
|
1221
|
+
"User-Agent": buildUserAgent(),
|
|
1222
|
+
Authorization: `Bearer ${params.token}`,
|
|
1223
|
+
...hasBody ? { "Content-Type": "application/json" } : {},
|
|
1224
|
+
...params.headers
|
|
1225
|
+
},
|
|
1226
|
+
body: hasBody ? JSON.stringify(params.body) : void 0
|
|
1213
1227
|
},
|
|
1214
|
-
|
|
1228
|
+
auditContext: "msteams.graph"
|
|
1215
1229
|
});
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1230
|
+
try {
|
|
1231
|
+
if (!response.ok) {
|
|
1232
|
+
const text = await response.text().catch(() => "");
|
|
1233
|
+
throw new Error(`${params.errorPrefix ?? "Graph"} ${params.path} failed (${response.status}): ${text || "unknown error"}`);
|
|
1234
|
+
}
|
|
1235
|
+
const body = NULL_BODY_STATUSES.has(response.status) ? null : await response.arrayBuffer();
|
|
1236
|
+
return new Response(body, {
|
|
1237
|
+
status: response.status,
|
|
1238
|
+
statusText: response.statusText,
|
|
1239
|
+
headers: new Headers(response.headers)
|
|
1240
|
+
});
|
|
1241
|
+
} finally {
|
|
1242
|
+
await release();
|
|
1219
1243
|
}
|
|
1220
|
-
return res;
|
|
1221
1244
|
}
|
|
1222
|
-
async function readOptionalGraphJson(res) {
|
|
1245
|
+
async function readOptionalGraphJson(res, label) {
|
|
1223
1246
|
if (res.status === 204 || res.headers?.get?.("content-length") === "0") return;
|
|
1224
|
-
return await res
|
|
1247
|
+
return await readProviderJsonResponse(res, label);
|
|
1225
1248
|
}
|
|
1226
1249
|
async function fetchGraphJson(params) {
|
|
1227
1250
|
return await readOptionalGraphJson(await requestGraph({
|
|
@@ -1230,7 +1253,7 @@ async function fetchGraphJson(params) {
|
|
|
1230
1253
|
method: params.method,
|
|
1231
1254
|
body: params.body,
|
|
1232
1255
|
headers: params.headers
|
|
1233
|
-
}));
|
|
1256
|
+
}), `Graph ${params.path} failed`);
|
|
1234
1257
|
}
|
|
1235
1258
|
/**
|
|
1236
1259
|
* Fetch JSON from an absolute Graph API URL (for example @odata.nextLink
|
|
@@ -1251,7 +1274,7 @@ async function fetchGraphAbsoluteUrl(params) {
|
|
|
1251
1274
|
const text = await response.text().catch(() => "");
|
|
1252
1275
|
throw new Error(`Graph ${params.url} failed (${response.status}): ${text || "unknown error"}`);
|
|
1253
1276
|
}
|
|
1254
|
-
return await response.
|
|
1277
|
+
return await readProviderJsonResponse(response, `Graph ${params.url} failed`);
|
|
1255
1278
|
} finally {
|
|
1256
1279
|
await release();
|
|
1257
1280
|
}
|
|
@@ -1325,7 +1348,7 @@ async function postGraphJson(params) {
|
|
|
1325
1348
|
method: "POST",
|
|
1326
1349
|
body: params.body,
|
|
1327
1350
|
errorPrefix: "Graph POST"
|
|
1328
|
-
}));
|
|
1351
|
+
}), `Graph POST ${params.path} failed`);
|
|
1329
1352
|
}
|
|
1330
1353
|
async function postGraphBetaJson(params) {
|
|
1331
1354
|
return readOptionalGraphJson(await requestGraph({
|
|
@@ -1335,7 +1358,7 @@ async function postGraphBetaJson(params) {
|
|
|
1335
1358
|
root: GRAPH_BETA,
|
|
1336
1359
|
body: params.body,
|
|
1337
1360
|
errorPrefix: "Graph beta POST"
|
|
1338
|
-
}));
|
|
1361
|
+
}), `Graph beta POST ${params.path} failed`);
|
|
1339
1362
|
}
|
|
1340
1363
|
async function deleteGraphRequest(params) {
|
|
1341
1364
|
await requestGraph({
|
|
@@ -1346,15 +1369,13 @@ async function deleteGraphRequest(params) {
|
|
|
1346
1369
|
});
|
|
1347
1370
|
}
|
|
1348
1371
|
async function patchGraphJson(params) {
|
|
1349
|
-
|
|
1372
|
+
return readOptionalGraphJson(await requestGraph({
|
|
1350
1373
|
token: params.token,
|
|
1351
1374
|
path: params.path,
|
|
1352
1375
|
method: "PATCH",
|
|
1353
1376
|
body: params.body,
|
|
1354
1377
|
errorPrefix: "Graph PATCH"
|
|
1355
|
-
});
|
|
1356
|
-
if (res.status === 204 || res.headers.get("content-length") === "0") return;
|
|
1357
|
-
return await res.json();
|
|
1378
|
+
}), `Graph PATCH ${params.path} failed`);
|
|
1358
1379
|
}
|
|
1359
1380
|
async function listChannelsForTeam(token, teamId) {
|
|
1360
1381
|
const { items } = await fetchAllGraphPages({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as MSTEAMS_OAUTH_CALLBACK_PORT, i as MSTEAMS_OAUTH_CALLBACK_PATH, o as MSTEAMS_OAUTH_REDIRECT_URI, r as MSTEAMS_DEFAULT_DELEGATED_SCOPES, s as buildMSTeamsAuthEndpoint, t as exchangeMSTeamsCodeForTokens } from "./oauth.token-
|
|
1
|
+
import { a as MSTEAMS_OAUTH_CALLBACK_PORT, i as MSTEAMS_OAUTH_CALLBACK_PATH, o as MSTEAMS_OAUTH_REDIRECT_URI, r as MSTEAMS_DEFAULT_DELEGATED_SCOPES, s as buildMSTeamsAuthEndpoint, t as exchangeMSTeamsCodeForTokens } from "./oauth.token-mUfXUE0j.js";
|
|
2
2
|
import { generateHexPkceVerifierChallenge } from "openclaw/plugin-sdk/provider-auth";
|
|
3
3
|
import { generateOAuthState, parseOAuthCallbackInput, waitForLocalOAuthCallback } from "openclaw/plugin-sdk/provider-auth-runtime";
|
|
4
4
|
import { isWSL2Sync } from "openclaw/plugin-sdk/runtime-env";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
2
|
+
import { readProviderJsonResponse } from "openclaw/plugin-sdk/provider-http";
|
|
2
3
|
//#region extensions/msteams/src/oauth.shared.ts
|
|
3
4
|
const MSTEAMS_OAUTH_REDIRECT_URI = "http://localhost:8086/oauth2callback";
|
|
4
5
|
const MSTEAMS_OAUTH_CALLBACK_PORT = 8086;
|
|
@@ -51,7 +52,7 @@ async function fetchMSTeamsTokens(params) {
|
|
|
51
52
|
const errorText = await response.text();
|
|
52
53
|
throw new Error(`MSTeams ${params.failureLabel} failed (${response.status}): ${errorText}`);
|
|
53
54
|
}
|
|
54
|
-
return await response.
|
|
55
|
+
return await readProviderJsonResponse(response, `MSTeams ${params.failureLabel} failed`);
|
|
55
56
|
} finally {
|
|
56
57
|
await release();
|
|
57
58
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { C as normalizeStringEntries, E as resolveChannelMediaMaxBytes, M as getMSTeamsRuntime, d as detectMime, g as getFileExtension, m as extractOriginalFilename, p as extensionForMime, y as loadOutboundMediaFromUrl } from "./runtime-api-C3EIaIpt.js";
|
|
2
|
-
import { C as loadMSTeamsSdkWithAuth, D as formatMSTeamsSendErrorHint, E as classifyMSTeamsSendError, O as formatUnknownError, S as createMSTeamsTokenProvider, _ as resolveMSTeamsStorePath, h as resolveMSTeamsCredentials, k as isRevokedProxyError, m as loadDelegatedTokens, w as buildUserAgent, x as createMSTeamsAdapter, y as readAccessToken } from "./graph-users-
|
|
3
|
-
import { i as resolveMSTeamsRouteConfig, r as resolveMSTeamsReplyPolicy } from "./
|
|
2
|
+
import { C as loadMSTeamsSdkWithAuth, D as formatMSTeamsSendErrorHint, E as classifyMSTeamsSendError, O as formatUnknownError, S as createMSTeamsTokenProvider, _ as resolveMSTeamsStorePath, h as resolveMSTeamsCredentials, k as isRevokedProxyError, m as loadDelegatedTokens, w as buildUserAgent, x as createMSTeamsAdapter, y as readAccessToken } from "./graph-users-ChPPxUzD.js";
|
|
3
|
+
import { i as resolveMSTeamsRouteConfig, r as resolveMSTeamsReplyPolicy } from "./channel-C5CVTygn.js";
|
|
4
4
|
import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-message";
|
|
5
5
|
import { isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
6
|
import { withFileLock } from "openclaw/plugin-sdk/file-lock";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-
|
|
1
|
+
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-DDPQm4fE.js";
|
|
2
2
|
export { channelSecrets, collectRuntimeConfigAssignments, secretTargetRegistryEntries };
|
package/dist/setup-plugin-api.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { h as resolveMSTeamsCredentials } from "./graph-users-
|
|
1
|
+
import { h as resolveMSTeamsCredentials } from "./graph-users-ChPPxUzD.js";
|
|
2
|
+
import { i as msteamsSetupAdapter, t as msteamsSetupWizard } from "./setup-surface-CQrMX-nJ.js";
|
|
2
3
|
import { t as MSTeamsChannelConfigSchema } from "./config-schema-DwOEthCC.js";
|
|
3
|
-
import { i as msteamsSetupAdapter, t as msteamsSetupWizard } from "./setup-surface-D9_2tf9Q.js";
|
|
4
4
|
import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
|
|
5
5
|
import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
|
|
6
6
|
import { createTopLevelChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
@@ -1,7 +1,223 @@
|
|
|
1
|
-
import { O as formatUnknownError, g as saveDelegatedTokens, h as resolveMSTeamsCredentials, p as hasConfiguredMSTeamsCredentials, v as normalizeSecretInputString } from "./graph-users-
|
|
2
|
-
import {
|
|
1
|
+
import { O as formatUnknownError, c as normalizeQuery, f as resolveGraphToken, g as saveDelegatedTokens, h as resolveMSTeamsCredentials, o as listChannelsForTeam, p as hasConfiguredMSTeamsCredentials, s as listTeamsByName, t as searchGraphUsers, v as normalizeSecretInputString } from "./graph-users-ChPPxUzD.js";
|
|
2
|
+
import { mapAllowlistResolutionInputs } from "openclaw/plugin-sdk/allow-from";
|
|
3
|
+
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
4
|
import { DEFAULT_ACCOUNT_ID, createStandardChannelSetupStatus, createTopLevelChannelAllowFromSetter, createTopLevelChannelDmPolicy, createTopLevelChannelGroupPolicySetter, mergeAllowFromEntries, splitSetupEntries } from "openclaw/plugin-sdk/setup";
|
|
4
5
|
import { formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
|
|
6
|
+
//#region extensions/msteams/src/resolve-allowlist.ts
|
|
7
|
+
function stripProviderPrefix(raw) {
|
|
8
|
+
return raw.replace(/^(msteams|teams):/i, "");
|
|
9
|
+
}
|
|
10
|
+
function normalizeMSTeamsMessagingTarget(raw) {
|
|
11
|
+
let trimmed = raw.trim();
|
|
12
|
+
if (!trimmed) return;
|
|
13
|
+
trimmed = stripProviderPrefix(trimmed).trim();
|
|
14
|
+
if (/^conversation:/i.test(trimmed)) {
|
|
15
|
+
const id = trimmed.slice(13).trim();
|
|
16
|
+
return id ? `conversation:${id}` : void 0;
|
|
17
|
+
}
|
|
18
|
+
if (/^user:/i.test(trimmed)) {
|
|
19
|
+
const id = trimmed.slice(5).trim();
|
|
20
|
+
return id ? `user:${id}` : void 0;
|
|
21
|
+
}
|
|
22
|
+
return trimmed || void 0;
|
|
23
|
+
}
|
|
24
|
+
function normalizeMSTeamsUserInput(raw) {
|
|
25
|
+
return stripProviderPrefix(raw).replace(/^(user|conversation):/i, "").trim();
|
|
26
|
+
}
|
|
27
|
+
function parseMSTeamsConversationId(raw) {
|
|
28
|
+
const trimmed = stripProviderPrefix(raw).trim();
|
|
29
|
+
if (!/^conversation:/i.test(trimmed)) return null;
|
|
30
|
+
return trimmed.slice(13).trim();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Detect whether a raw target string looks like a Microsoft Teams conversation
|
|
34
|
+
* or user id that cron announce delivery and other explicit-target paths can
|
|
35
|
+
* forward verbatim to the channel adapter.
|
|
36
|
+
*
|
|
37
|
+
* Accepts both prefixed and bare formats:
|
|
38
|
+
* - `conversation:<id>` — explicit conversation prefix
|
|
39
|
+
* - `user:<aad-guid>` — user id (16+ hex chars, UUID-like)
|
|
40
|
+
* - `19:abc@thread.tacv2` / `19:abc@thread.skype` — channel / legacy group
|
|
41
|
+
* - `19:{userId}_{appId}@unq.gbl.spaces` — Graph 1:1 chat thread format
|
|
42
|
+
* - `a:1xxx` — Bot Framework personal (1:1) chat id
|
|
43
|
+
* - `8:orgid:xxx` — Bot Framework org-scoped personal chat id
|
|
44
|
+
* - `29:xxx` — Bot Framework user id
|
|
45
|
+
*
|
|
46
|
+
* Display-name user targets such as `user:John Smith` intentionally return
|
|
47
|
+
* false so that the Graph API directory lookup still runs for them.
|
|
48
|
+
*/
|
|
49
|
+
function looksLikeMSTeamsTargetId(raw) {
|
|
50
|
+
const trimmed = raw.trim();
|
|
51
|
+
if (!trimmed) return false;
|
|
52
|
+
if (/^conversation:/i.test(trimmed)) return true;
|
|
53
|
+
if (/^user:/i.test(trimmed)) {
|
|
54
|
+
const id = trimmed.slice(5).trim();
|
|
55
|
+
return /^[0-9a-fA-F-]{16,}$/.test(id);
|
|
56
|
+
}
|
|
57
|
+
if (/^19:.+@thread\.(tacv2|skype)$/i.test(trimmed)) return true;
|
|
58
|
+
if (/^19:.+@unq\.gbl\.spaces$/i.test(trimmed)) return true;
|
|
59
|
+
if (/^a:1[A-Za-z0-9_-]+$/i.test(trimmed)) return true;
|
|
60
|
+
if (/^8:orgid:[A-Za-z0-9-]+$/i.test(trimmed)) return true;
|
|
61
|
+
if (/^29:[A-Za-z0-9_-]+$/i.test(trimmed)) return true;
|
|
62
|
+
return /@thread\b/i.test(trimmed);
|
|
63
|
+
}
|
|
64
|
+
function normalizeMSTeamsTeamKey(raw) {
|
|
65
|
+
return stripProviderPrefix(raw).replace(/^team:/i, "").trim() || void 0;
|
|
66
|
+
}
|
|
67
|
+
function normalizeMSTeamsChannelKey(raw) {
|
|
68
|
+
return (raw?.trim().replace(/^#/, "").trim() ?? "") || void 0;
|
|
69
|
+
}
|
|
70
|
+
function normalizeMSTeamsConversationTargetId(raw) {
|
|
71
|
+
const trimmed = stripProviderPrefix(raw).trim();
|
|
72
|
+
return parseMSTeamsConversationId(trimmed) ?? trimmed;
|
|
73
|
+
}
|
|
74
|
+
function looksLikeMSTeamsThreadConversationId(raw) {
|
|
75
|
+
const normalized = normalizeMSTeamsConversationTargetId(raw);
|
|
76
|
+
return /^19:.+@thread\./i.test(normalized);
|
|
77
|
+
}
|
|
78
|
+
function parseMSTeamsTeamChannelInput(raw) {
|
|
79
|
+
const trimmed = stripProviderPrefix(raw).trim();
|
|
80
|
+
if (!trimmed) return {};
|
|
81
|
+
const parts = trimmed.split("/");
|
|
82
|
+
const team = normalizeMSTeamsTeamKey(parts[0] ?? "");
|
|
83
|
+
const channel = parts.length > 1 ? normalizeMSTeamsChannelKey(parts.slice(1).join("/")) : void 0;
|
|
84
|
+
return {
|
|
85
|
+
...team ? { team } : {},
|
|
86
|
+
...channel ? { channel } : {}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function parseMSTeamsTeamEntry(raw) {
|
|
90
|
+
const { team, channel } = parseMSTeamsTeamChannelInput(raw);
|
|
91
|
+
if (!team) return null;
|
|
92
|
+
return {
|
|
93
|
+
teamKey: team,
|
|
94
|
+
...channel ? { channelKey: channel } : {}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
async function resolveMSTeamsChannelAllowlist(params) {
|
|
98
|
+
let tokenPromise;
|
|
99
|
+
const getToken = () => {
|
|
100
|
+
tokenPromise ??= resolveGraphToken(params.cfg);
|
|
101
|
+
return tokenPromise;
|
|
102
|
+
};
|
|
103
|
+
return await mapAllowlistResolutionInputs({
|
|
104
|
+
inputs: params.entries,
|
|
105
|
+
mapInput: async (input) => {
|
|
106
|
+
const { team, channel } = parseMSTeamsTeamChannelInput(input);
|
|
107
|
+
if (!team) return {
|
|
108
|
+
input,
|
|
109
|
+
resolved: false
|
|
110
|
+
};
|
|
111
|
+
if (looksLikeMSTeamsThreadConversationId(team)) {
|
|
112
|
+
const teamId = normalizeMSTeamsConversationTargetId(team);
|
|
113
|
+
if (!channel) return {
|
|
114
|
+
input,
|
|
115
|
+
resolved: true,
|
|
116
|
+
teamId,
|
|
117
|
+
teamName: teamId
|
|
118
|
+
};
|
|
119
|
+
if (!looksLikeMSTeamsThreadConversationId(channel)) return {
|
|
120
|
+
input,
|
|
121
|
+
resolved: false,
|
|
122
|
+
teamId,
|
|
123
|
+
teamName: teamId,
|
|
124
|
+
note: "channel id required for conversation-id team"
|
|
125
|
+
};
|
|
126
|
+
const channelId = normalizeMSTeamsConversationTargetId(channel);
|
|
127
|
+
return {
|
|
128
|
+
input,
|
|
129
|
+
resolved: true,
|
|
130
|
+
teamId,
|
|
131
|
+
teamName: teamId,
|
|
132
|
+
channelId,
|
|
133
|
+
channelName: channelId
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const token = await getToken();
|
|
137
|
+
const teams = /^[0-9a-fA-F-]{16,}$/.test(team) ? [{
|
|
138
|
+
id: team,
|
|
139
|
+
displayName: team
|
|
140
|
+
}] : await listTeamsByName(token, team);
|
|
141
|
+
if (teams.length === 0) return {
|
|
142
|
+
input,
|
|
143
|
+
resolved: false,
|
|
144
|
+
note: "team not found"
|
|
145
|
+
};
|
|
146
|
+
const teamMatch = teams[0];
|
|
147
|
+
const graphTeamId = teamMatch.id?.trim();
|
|
148
|
+
const teamName = teamMatch.displayName?.trim() || team;
|
|
149
|
+
if (!graphTeamId) return {
|
|
150
|
+
input,
|
|
151
|
+
resolved: false,
|
|
152
|
+
note: "team id missing"
|
|
153
|
+
};
|
|
154
|
+
let teamChannels = [];
|
|
155
|
+
try {
|
|
156
|
+
teamChannels = await listChannelsForTeam(token, graphTeamId);
|
|
157
|
+
} catch {}
|
|
158
|
+
const teamId = teamChannels.find((ch) => normalizeOptionalLowercaseString(ch.displayName) === "general")?.id?.trim() || graphTeamId;
|
|
159
|
+
if (!channel) return {
|
|
160
|
+
input,
|
|
161
|
+
resolved: true,
|
|
162
|
+
teamId,
|
|
163
|
+
teamName,
|
|
164
|
+
note: teams.length > 1 ? "multiple teams; chose first" : void 0
|
|
165
|
+
};
|
|
166
|
+
const normalizedChannel = normalizeOptionalLowercaseString(channel);
|
|
167
|
+
const channelMatch = teamChannels.find((item) => item.id === channel) ?? teamChannels.find((item) => normalizeOptionalLowercaseString(item.displayName) === normalizedChannel) ?? teamChannels.find((item) => normalizeLowercaseStringOrEmpty(item.displayName ?? "").includes(normalizedChannel ?? ""));
|
|
168
|
+
if (!channelMatch?.id) return {
|
|
169
|
+
input,
|
|
170
|
+
resolved: false,
|
|
171
|
+
note: "channel not found"
|
|
172
|
+
};
|
|
173
|
+
return {
|
|
174
|
+
input,
|
|
175
|
+
resolved: true,
|
|
176
|
+
teamId,
|
|
177
|
+
teamName,
|
|
178
|
+
channelId: channelMatch.id,
|
|
179
|
+
channelName: channelMatch.displayName ?? channel,
|
|
180
|
+
note: teamChannels.length > 1 ? "multiple channels; chose first" : void 0
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
async function resolveMSTeamsUserAllowlist(params) {
|
|
186
|
+
const token = await resolveGraphToken(params.cfg);
|
|
187
|
+
return await mapAllowlistResolutionInputs({
|
|
188
|
+
inputs: params.entries,
|
|
189
|
+
mapInput: async (input) => {
|
|
190
|
+
const query = normalizeQuery(normalizeMSTeamsUserInput(input));
|
|
191
|
+
if (!query) return {
|
|
192
|
+
input,
|
|
193
|
+
resolved: false
|
|
194
|
+
};
|
|
195
|
+
if (/^[0-9a-fA-F-]{16,}$/.test(query)) return {
|
|
196
|
+
input,
|
|
197
|
+
resolved: true,
|
|
198
|
+
id: query
|
|
199
|
+
};
|
|
200
|
+
const users = await searchGraphUsers({
|
|
201
|
+
token,
|
|
202
|
+
query,
|
|
203
|
+
top: 10
|
|
204
|
+
});
|
|
205
|
+
const match = users[0];
|
|
206
|
+
if (!match?.id) return {
|
|
207
|
+
input,
|
|
208
|
+
resolved: false
|
|
209
|
+
};
|
|
210
|
+
return {
|
|
211
|
+
input,
|
|
212
|
+
resolved: true,
|
|
213
|
+
id: match.id,
|
|
214
|
+
name: match.displayName ?? void 0,
|
|
215
|
+
note: users.length > 1 ? "multiple matches; chose first" : void 0
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
//#endregion
|
|
5
221
|
//#region extensions/msteams/src/setup-core.ts
|
|
6
222
|
const msteamsSetupAdapter = {
|
|
7
223
|
resolveAccountId: () => DEFAULT_ACCOUNT_ID,
|
|
@@ -271,7 +487,7 @@ const msteamsSetupWizard = {
|
|
|
271
487
|
}
|
|
272
488
|
};
|
|
273
489
|
try {
|
|
274
|
-
const { loginMSTeamsDelegated } = await import("./oauth-
|
|
490
|
+
const { loginMSTeamsDelegated } = await import("./oauth-DsVj42gA.js");
|
|
275
491
|
const progress = params.prompter.progress("MSTeams Delegated OAuth");
|
|
276
492
|
saveDelegatedTokens(await loginMSTeamsDelegated({
|
|
277
493
|
isRemote: true,
|
|
@@ -310,4 +526,4 @@ const msteamsSetupWizard = {
|
|
|
310
526
|
})
|
|
311
527
|
};
|
|
312
528
|
//#endregion
|
|
313
|
-
export { msteamsSetupAdapter as i, openDelegatedOAuthUrl as n, createMSTeamsSetupWizardBase as r, msteamsSetupWizard as t };
|
|
529
|
+
export { looksLikeMSTeamsTargetId as a, parseMSTeamsConversationId as c, resolveMSTeamsUserAllowlist as d, msteamsSetupAdapter as i, parseMSTeamsTeamChannelInput as l, openDelegatedOAuthUrl as n, normalizeMSTeamsMessagingTarget as o, createMSTeamsSetupWizardBase as r, normalizeMSTeamsUserInput as s, msteamsSetupWizard as t, resolveMSTeamsChannelAllowlist as u };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { A as summarizeMapping, D as resolveDefaultGroupPolicy, E as resolveChannelMediaMaxBytes, M as getMSTeamsRuntime, N as getOptionalMSTeamsRuntime, _ as isDangerousNameMatchingEnabled, a as buildMediaPayload, b as logTypingFailure, c as createChannelMessageReplyPipeline, f as dispatchReplyFromConfigWithSettledDispatcher$1, l as createChannelPairingController, n as DEFAULT_WEBHOOK_MAX_BODY_BYTES, t as DEFAULT_ACCOUNT_ID, v as keepHttpServerTaskAlive, x as mergeAllowlist } from "./runtime-api-C3EIaIpt.js";
|
|
2
|
-
import { A as ATTACHMENT_TAG_RE, B as isLikelyImageAttachment, C as loadMSTeamsSdkWithAuth, D as formatMSTeamsSendErrorHint, E as classifyMSTeamsSendError, F as estimateBase64DecodedBytes, G as resolveAttachmentFetchPolicy, H as isUrlAllowed, I as extractHtmlFromAttachment, J as safeFetchWithPolicy, K as resolveMediaSsrfPolicy, L as extractInlineImageCandidates, M as IMG_SRC_RE, N as applyAuthorizationHeaderForUrl, O as formatUnknownError, P as encodeGraphShareId, R as inferPlaceholder, S as createMSTeamsTokenProvider, T as ensureUserAgentHeader, U as normalizeContentType, V as isRecord$1, W as readNestedString, X as tryBuildGraphSharesUrlForSharedLink, Y as safeHostForUrl, _ as resolveMSTeamsStorePath, a as fetchGraphJson, b as createBotFrameworkJwtValidator, h as resolveMSTeamsCredentials, j as GRAPH_ROOT, q as resolveRequestUrl, w as buildUserAgent, x as createMSTeamsAdapter, z as isDownloadableAttachment } from "./graph-users-
|
|
3
|
-
import {
|
|
4
|
-
import { i as resolveMSTeamsRouteConfig,
|
|
5
|
-
import { C as readJsonFile, S as createMSTeamsConversationStoreFs, T as writeJsonFile, _ as buildFileInfoCard, b as createMSTeamsPollStoreFs, c as renderReplyPayloadsToMessages, d as withRevokedProxyFallback, f as resolveGraphChatId, g as removePendingUploadFs, h as getPendingUploadFs, l as sendMSTeamsMessages, m as removePendingUpload, p as getPendingUpload, s as buildConversationReference, u as AI_GENERATED_ENTITY, v as parseFileConsentInvoke, w as withFileLock, x as extractMSTeamsPollVote, y as uploadToConsentUrl } from "./probe-
|
|
2
|
+
import { A as ATTACHMENT_TAG_RE, B as isLikelyImageAttachment, C as loadMSTeamsSdkWithAuth, D as formatMSTeamsSendErrorHint, E as classifyMSTeamsSendError, F as estimateBase64DecodedBytes, G as resolveAttachmentFetchPolicy, H as isUrlAllowed, I as extractHtmlFromAttachment, J as safeFetchWithPolicy, K as resolveMediaSsrfPolicy, L as extractInlineImageCandidates, M as IMG_SRC_RE, N as applyAuthorizationHeaderForUrl, O as formatUnknownError, P as encodeGraphShareId, R as inferPlaceholder, S as createMSTeamsTokenProvider, T as ensureUserAgentHeader, U as normalizeContentType, V as isRecord$1, W as readNestedString, X as tryBuildGraphSharesUrlForSharedLink, Y as safeHostForUrl, _ as resolveMSTeamsStorePath, a as fetchGraphJson, b as createBotFrameworkJwtValidator, h as resolveMSTeamsCredentials, j as GRAPH_ROOT, q as resolveRequestUrl, w as buildUserAgent, x as createMSTeamsAdapter, z as isDownloadableAttachment } from "./graph-users-ChPPxUzD.js";
|
|
3
|
+
import { d as resolveMSTeamsUserAllowlist, u as resolveMSTeamsChannelAllowlist } from "./setup-surface-CQrMX-nJ.js";
|
|
4
|
+
import { i as resolveMSTeamsRouteConfig, n as resolveMSTeamsAllowlistMatch, r as resolveMSTeamsReplyPolicy } from "./channel-C5CVTygn.js";
|
|
5
|
+
import { C as readJsonFile, S as createMSTeamsConversationStoreFs, T as writeJsonFile, _ as buildFileInfoCard, b as createMSTeamsPollStoreFs, c as renderReplyPayloadsToMessages, d as withRevokedProxyFallback, f as resolveGraphChatId, g as removePendingUploadFs, h as getPendingUploadFs, l as sendMSTeamsMessages, m as removePendingUpload, p as getPendingUpload, s as buildConversationReference, u as AI_GENERATED_ENTITY, v as parseFileConsentInvoke, w as withFileLock, x as extractMSTeamsPollVote, y as uploadToConsentUrl } from "./probe-I2DM0U-s.js";
|
|
6
6
|
import { formatAllowlistMatchMeta } from "openclaw/plugin-sdk/allow-from";
|
|
7
7
|
import { createLiveMessageState, createPreviewMessageReceipt, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, markLiveMessageFinalized } from "openclaw/plugin-sdk/channel-message";
|
|
8
8
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime";
|
package/dist/test-api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as msteamsPlugin } from "./channel-
|
|
1
|
+
import { t as msteamsPlugin } from "./channel-C5CVTygn.js";
|
|
2
2
|
export { msteamsPlugin };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/msteams",
|
|
3
|
-
"version": "2026.5.14-beta.
|
|
3
|
+
"version": "2026.5.14-beta.2",
|
|
4
4
|
"description": "OpenClaw Microsoft Teams channel plugin",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"type": "module",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@azure/identity": "4.13.1",
|
|
12
|
-
"@microsoft/teams.api": "2.0.
|
|
13
|
-
"@microsoft/teams.apps": "2.0.
|
|
12
|
+
"@microsoft/teams.api": "2.0.11",
|
|
13
|
+
"@microsoft/teams.apps": "2.0.11",
|
|
14
14
|
"express": "5.2.1",
|
|
15
15
|
"jsonwebtoken": "9.0.3",
|
|
16
16
|
"jwks-rsa": "4.0.1",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"openclaw": "workspace:*"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
|
-
"openclaw": ">=2026.5.14-beta.
|
|
25
|
+
"openclaw": ">=2026.5.14-beta.2"
|
|
26
26
|
},
|
|
27
27
|
"peerDependenciesMeta": {
|
|
28
28
|
"openclaw": {
|
|
@@ -58,10 +58,10 @@
|
|
|
58
58
|
"minHostVersion": ">=2026.4.10"
|
|
59
59
|
},
|
|
60
60
|
"compat": {
|
|
61
|
-
"pluginApi": ">=2026.5.14-beta.
|
|
61
|
+
"pluginApi": ">=2026.5.14-beta.2"
|
|
62
62
|
},
|
|
63
63
|
"build": {
|
|
64
|
-
"openclawVersion": "2026.5.14-beta.
|
|
64
|
+
"openclawVersion": "2026.5.14-beta.2"
|
|
65
65
|
},
|
|
66
66
|
"release": {
|
|
67
67
|
"publishToClawHub": true,
|
package/dist/policy-bM71GXRd.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { O as resolveNestedAllowlistDecision, S as normalizeChannelSlug, T as resolveChannelEntryMatchWithFallback, _ as isDangerousNameMatchingEnabled, i as buildChannelKeyCandidates, k as resolveToolsBySender, w as resolveAllowlistMatchSimple } from "./runtime-api-C3EIaIpt.js";
|
|
2
|
-
//#region extensions/msteams/src/policy.ts
|
|
3
|
-
function resolveMSTeamsRouteConfig(params) {
|
|
4
|
-
const teamId = params.teamId?.trim();
|
|
5
|
-
const teamName = params.teamName?.trim();
|
|
6
|
-
const conversationId = params.conversationId?.trim();
|
|
7
|
-
const channelName = params.channelName?.trim();
|
|
8
|
-
const teams = params.cfg?.teams ?? {};
|
|
9
|
-
const allowlistConfigured = Object.keys(teams).length > 0;
|
|
10
|
-
const teamMatch = resolveChannelEntryMatchWithFallback({
|
|
11
|
-
entries: teams,
|
|
12
|
-
keys: buildChannelKeyCandidates(teamId, params.allowNameMatching ? teamName : void 0, params.allowNameMatching && teamName ? normalizeChannelSlug(teamName) : void 0),
|
|
13
|
-
wildcardKey: "*",
|
|
14
|
-
normalizeKey: normalizeChannelSlug
|
|
15
|
-
});
|
|
16
|
-
const teamConfig = teamMatch.entry;
|
|
17
|
-
const channels = teamConfig?.channels ?? {};
|
|
18
|
-
const channelAllowlistConfigured = Object.keys(channels).length > 0;
|
|
19
|
-
const channelMatch = resolveChannelEntryMatchWithFallback({
|
|
20
|
-
entries: channels,
|
|
21
|
-
keys: buildChannelKeyCandidates(conversationId, params.allowNameMatching ? channelName : void 0, params.allowNameMatching && channelName ? normalizeChannelSlug(channelName) : void 0),
|
|
22
|
-
wildcardKey: "*",
|
|
23
|
-
normalizeKey: normalizeChannelSlug
|
|
24
|
-
});
|
|
25
|
-
const channelConfig = channelMatch.entry;
|
|
26
|
-
return {
|
|
27
|
-
teamConfig,
|
|
28
|
-
channelConfig,
|
|
29
|
-
allowlistConfigured,
|
|
30
|
-
allowed: resolveNestedAllowlistDecision({
|
|
31
|
-
outerConfigured: allowlistConfigured,
|
|
32
|
-
outerMatched: Boolean(teamConfig),
|
|
33
|
-
innerConfigured: channelAllowlistConfigured,
|
|
34
|
-
innerMatched: Boolean(channelConfig)
|
|
35
|
-
}),
|
|
36
|
-
teamKey: teamMatch.matchKey ?? teamMatch.key,
|
|
37
|
-
channelKey: channelMatch.matchKey ?? channelMatch.key,
|
|
38
|
-
channelMatchKey: channelMatch.matchKey,
|
|
39
|
-
channelMatchSource: channelMatch.matchSource === "direct" || channelMatch.matchSource === "wildcard" ? channelMatch.matchSource : void 0
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
function resolveMSTeamsGroupToolPolicy(params) {
|
|
43
|
-
const cfg = params.cfg.channels?.msteams;
|
|
44
|
-
if (!cfg) return;
|
|
45
|
-
const groupId = params.groupId?.trim();
|
|
46
|
-
const groupChannel = params.groupChannel?.trim();
|
|
47
|
-
const groupSpace = params.groupSpace?.trim();
|
|
48
|
-
const allowNameMatching = isDangerousNameMatchingEnabled(cfg);
|
|
49
|
-
const resolved = resolveMSTeamsRouteConfig({
|
|
50
|
-
cfg,
|
|
51
|
-
teamId: groupSpace,
|
|
52
|
-
teamName: groupSpace,
|
|
53
|
-
conversationId: groupId,
|
|
54
|
-
channelName: groupChannel,
|
|
55
|
-
allowNameMatching
|
|
56
|
-
});
|
|
57
|
-
if (resolved.channelConfig) {
|
|
58
|
-
const senderPolicy = resolveToolsBySender({
|
|
59
|
-
toolsBySender: resolved.channelConfig.toolsBySender,
|
|
60
|
-
senderId: params.senderId,
|
|
61
|
-
senderName: params.senderName,
|
|
62
|
-
senderUsername: params.senderUsername,
|
|
63
|
-
senderE164: params.senderE164
|
|
64
|
-
});
|
|
65
|
-
if (senderPolicy) return senderPolicy;
|
|
66
|
-
if (resolved.channelConfig.tools) return resolved.channelConfig.tools;
|
|
67
|
-
const teamSenderPolicy = resolveToolsBySender({
|
|
68
|
-
toolsBySender: resolved.teamConfig?.toolsBySender,
|
|
69
|
-
senderId: params.senderId,
|
|
70
|
-
senderName: params.senderName,
|
|
71
|
-
senderUsername: params.senderUsername,
|
|
72
|
-
senderE164: params.senderE164
|
|
73
|
-
});
|
|
74
|
-
if (teamSenderPolicy) return teamSenderPolicy;
|
|
75
|
-
return resolved.teamConfig?.tools;
|
|
76
|
-
}
|
|
77
|
-
if (resolved.teamConfig) {
|
|
78
|
-
const teamSenderPolicy = resolveToolsBySender({
|
|
79
|
-
toolsBySender: resolved.teamConfig.toolsBySender,
|
|
80
|
-
senderId: params.senderId,
|
|
81
|
-
senderName: params.senderName,
|
|
82
|
-
senderUsername: params.senderUsername,
|
|
83
|
-
senderE164: params.senderE164
|
|
84
|
-
});
|
|
85
|
-
if (teamSenderPolicy) return teamSenderPolicy;
|
|
86
|
-
if (resolved.teamConfig.tools) return resolved.teamConfig.tools;
|
|
87
|
-
}
|
|
88
|
-
if (!groupId) return;
|
|
89
|
-
const channelCandidates = buildChannelKeyCandidates(groupId, allowNameMatching ? groupChannel : void 0, allowNameMatching && groupChannel ? normalizeChannelSlug(groupChannel) : void 0);
|
|
90
|
-
for (const teamConfig of Object.values(cfg.teams ?? {})) {
|
|
91
|
-
const match = resolveChannelEntryMatchWithFallback({
|
|
92
|
-
entries: teamConfig?.channels ?? {},
|
|
93
|
-
keys: channelCandidates,
|
|
94
|
-
wildcardKey: "*",
|
|
95
|
-
normalizeKey: normalizeChannelSlug
|
|
96
|
-
});
|
|
97
|
-
if (match.entry) {
|
|
98
|
-
const senderPolicy = resolveToolsBySender({
|
|
99
|
-
toolsBySender: match.entry.toolsBySender,
|
|
100
|
-
senderId: params.senderId,
|
|
101
|
-
senderName: params.senderName,
|
|
102
|
-
senderUsername: params.senderUsername,
|
|
103
|
-
senderE164: params.senderE164
|
|
104
|
-
});
|
|
105
|
-
if (senderPolicy) return senderPolicy;
|
|
106
|
-
if (match.entry.tools) return match.entry.tools;
|
|
107
|
-
const teamSenderPolicy = resolveToolsBySender({
|
|
108
|
-
toolsBySender: teamConfig?.toolsBySender,
|
|
109
|
-
senderId: params.senderId,
|
|
110
|
-
senderName: params.senderName,
|
|
111
|
-
senderUsername: params.senderUsername,
|
|
112
|
-
senderE164: params.senderE164
|
|
113
|
-
});
|
|
114
|
-
if (teamSenderPolicy) return teamSenderPolicy;
|
|
115
|
-
return teamConfig?.tools;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
function resolveMSTeamsAllowlistMatch(params) {
|
|
120
|
-
return resolveAllowlistMatchSimple(params);
|
|
121
|
-
}
|
|
122
|
-
function resolveMSTeamsReplyPolicy(params) {
|
|
123
|
-
if (params.isDirectMessage) return {
|
|
124
|
-
requireMention: false,
|
|
125
|
-
replyStyle: "thread"
|
|
126
|
-
};
|
|
127
|
-
const requireMention = params.channelConfig?.requireMention ?? params.teamConfig?.requireMention ?? params.globalConfig?.requireMention ?? true;
|
|
128
|
-
return {
|
|
129
|
-
requireMention,
|
|
130
|
-
replyStyle: params.channelConfig?.replyStyle ?? params.teamConfig?.replyStyle ?? params.globalConfig?.replyStyle ?? (requireMention ? "thread" : "top-level")
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
//#endregion
|
|
134
|
-
export { resolveMSTeamsRouteConfig as i, resolveMSTeamsGroupToolPolicy as n, resolveMSTeamsReplyPolicy as r, resolveMSTeamsAllowlistMatch as t };
|
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import { c as normalizeQuery, f as resolveGraphToken, o as listChannelsForTeam, s as listTeamsByName, t as searchGraphUsers } from "./graph-users-OieoCBxW.js";
|
|
2
|
-
import { mapAllowlistResolutionInputs } from "openclaw/plugin-sdk/allow-from";
|
|
3
|
-
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
|
-
//#region extensions/msteams/src/resolve-allowlist.ts
|
|
5
|
-
function stripProviderPrefix(raw) {
|
|
6
|
-
return raw.replace(/^(msteams|teams):/i, "");
|
|
7
|
-
}
|
|
8
|
-
function normalizeMSTeamsMessagingTarget(raw) {
|
|
9
|
-
let trimmed = raw.trim();
|
|
10
|
-
if (!trimmed) return;
|
|
11
|
-
trimmed = stripProviderPrefix(trimmed).trim();
|
|
12
|
-
if (/^conversation:/i.test(trimmed)) {
|
|
13
|
-
const id = trimmed.slice(13).trim();
|
|
14
|
-
return id ? `conversation:${id}` : void 0;
|
|
15
|
-
}
|
|
16
|
-
if (/^user:/i.test(trimmed)) {
|
|
17
|
-
const id = trimmed.slice(5).trim();
|
|
18
|
-
return id ? `user:${id}` : void 0;
|
|
19
|
-
}
|
|
20
|
-
return trimmed || void 0;
|
|
21
|
-
}
|
|
22
|
-
function normalizeMSTeamsUserInput(raw) {
|
|
23
|
-
return stripProviderPrefix(raw).replace(/^(user|conversation):/i, "").trim();
|
|
24
|
-
}
|
|
25
|
-
function parseMSTeamsConversationId(raw) {
|
|
26
|
-
const trimmed = stripProviderPrefix(raw).trim();
|
|
27
|
-
if (!/^conversation:/i.test(trimmed)) return null;
|
|
28
|
-
return trimmed.slice(13).trim();
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Detect whether a raw target string looks like a Microsoft Teams conversation
|
|
32
|
-
* or user id that cron announce delivery and other explicit-target paths can
|
|
33
|
-
* forward verbatim to the channel adapter.
|
|
34
|
-
*
|
|
35
|
-
* Accepts both prefixed and bare formats:
|
|
36
|
-
* - `conversation:<id>` — explicit conversation prefix
|
|
37
|
-
* - `user:<aad-guid>` — user id (16+ hex chars, UUID-like)
|
|
38
|
-
* - `19:abc@thread.tacv2` / `19:abc@thread.skype` — channel / legacy group
|
|
39
|
-
* - `19:{userId}_{appId}@unq.gbl.spaces` — Graph 1:1 chat thread format
|
|
40
|
-
* - `a:1xxx` — Bot Framework personal (1:1) chat id
|
|
41
|
-
* - `8:orgid:xxx` — Bot Framework org-scoped personal chat id
|
|
42
|
-
* - `29:xxx` — Bot Framework user id
|
|
43
|
-
*
|
|
44
|
-
* Display-name user targets such as `user:John Smith` intentionally return
|
|
45
|
-
* false so that the Graph API directory lookup still runs for them.
|
|
46
|
-
*/
|
|
47
|
-
function looksLikeMSTeamsTargetId(raw) {
|
|
48
|
-
const trimmed = raw.trim();
|
|
49
|
-
if (!trimmed) return false;
|
|
50
|
-
if (/^conversation:/i.test(trimmed)) return true;
|
|
51
|
-
if (/^user:/i.test(trimmed)) {
|
|
52
|
-
const id = trimmed.slice(5).trim();
|
|
53
|
-
return /^[0-9a-fA-F-]{16,}$/.test(id);
|
|
54
|
-
}
|
|
55
|
-
if (/^19:.+@thread\.(tacv2|skype)$/i.test(trimmed)) return true;
|
|
56
|
-
if (/^19:.+@unq\.gbl\.spaces$/i.test(trimmed)) return true;
|
|
57
|
-
if (/^a:1[A-Za-z0-9_-]+$/i.test(trimmed)) return true;
|
|
58
|
-
if (/^8:orgid:[A-Za-z0-9-]+$/i.test(trimmed)) return true;
|
|
59
|
-
if (/^29:[A-Za-z0-9_-]+$/i.test(trimmed)) return true;
|
|
60
|
-
return /@thread\b/i.test(trimmed);
|
|
61
|
-
}
|
|
62
|
-
function normalizeMSTeamsTeamKey(raw) {
|
|
63
|
-
return stripProviderPrefix(raw).replace(/^team:/i, "").trim() || void 0;
|
|
64
|
-
}
|
|
65
|
-
function normalizeMSTeamsChannelKey(raw) {
|
|
66
|
-
return (raw?.trim().replace(/^#/, "").trim() ?? "") || void 0;
|
|
67
|
-
}
|
|
68
|
-
function normalizeMSTeamsConversationTargetId(raw) {
|
|
69
|
-
const trimmed = stripProviderPrefix(raw).trim();
|
|
70
|
-
return parseMSTeamsConversationId(trimmed) ?? trimmed;
|
|
71
|
-
}
|
|
72
|
-
function looksLikeMSTeamsThreadConversationId(raw) {
|
|
73
|
-
const normalized = normalizeMSTeamsConversationTargetId(raw);
|
|
74
|
-
return /^19:.+@thread\./i.test(normalized);
|
|
75
|
-
}
|
|
76
|
-
function parseMSTeamsTeamChannelInput(raw) {
|
|
77
|
-
const trimmed = stripProviderPrefix(raw).trim();
|
|
78
|
-
if (!trimmed) return {};
|
|
79
|
-
const parts = trimmed.split("/");
|
|
80
|
-
const team = normalizeMSTeamsTeamKey(parts[0] ?? "");
|
|
81
|
-
const channel = parts.length > 1 ? normalizeMSTeamsChannelKey(parts.slice(1).join("/")) : void 0;
|
|
82
|
-
return {
|
|
83
|
-
...team ? { team } : {},
|
|
84
|
-
...channel ? { channel } : {}
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
function parseMSTeamsTeamEntry(raw) {
|
|
88
|
-
const { team, channel } = parseMSTeamsTeamChannelInput(raw);
|
|
89
|
-
if (!team) return null;
|
|
90
|
-
return {
|
|
91
|
-
teamKey: team,
|
|
92
|
-
...channel ? { channelKey: channel } : {}
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
async function resolveMSTeamsChannelAllowlist(params) {
|
|
96
|
-
let tokenPromise;
|
|
97
|
-
const getToken = () => {
|
|
98
|
-
tokenPromise ??= resolveGraphToken(params.cfg);
|
|
99
|
-
return tokenPromise;
|
|
100
|
-
};
|
|
101
|
-
return await mapAllowlistResolutionInputs({
|
|
102
|
-
inputs: params.entries,
|
|
103
|
-
mapInput: async (input) => {
|
|
104
|
-
const { team, channel } = parseMSTeamsTeamChannelInput(input);
|
|
105
|
-
if (!team) return {
|
|
106
|
-
input,
|
|
107
|
-
resolved: false
|
|
108
|
-
};
|
|
109
|
-
if (looksLikeMSTeamsThreadConversationId(team)) {
|
|
110
|
-
const teamId = normalizeMSTeamsConversationTargetId(team);
|
|
111
|
-
if (!channel) return {
|
|
112
|
-
input,
|
|
113
|
-
resolved: true,
|
|
114
|
-
teamId,
|
|
115
|
-
teamName: teamId
|
|
116
|
-
};
|
|
117
|
-
if (!looksLikeMSTeamsThreadConversationId(channel)) return {
|
|
118
|
-
input,
|
|
119
|
-
resolved: false,
|
|
120
|
-
teamId,
|
|
121
|
-
teamName: teamId,
|
|
122
|
-
note: "channel id required for conversation-id team"
|
|
123
|
-
};
|
|
124
|
-
const channelId = normalizeMSTeamsConversationTargetId(channel);
|
|
125
|
-
return {
|
|
126
|
-
input,
|
|
127
|
-
resolved: true,
|
|
128
|
-
teamId,
|
|
129
|
-
teamName: teamId,
|
|
130
|
-
channelId,
|
|
131
|
-
channelName: channelId
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
const token = await getToken();
|
|
135
|
-
const teams = /^[0-9a-fA-F-]{16,}$/.test(team) ? [{
|
|
136
|
-
id: team,
|
|
137
|
-
displayName: team
|
|
138
|
-
}] : await listTeamsByName(token, team);
|
|
139
|
-
if (teams.length === 0) return {
|
|
140
|
-
input,
|
|
141
|
-
resolved: false,
|
|
142
|
-
note: "team not found"
|
|
143
|
-
};
|
|
144
|
-
const teamMatch = teams[0];
|
|
145
|
-
const graphTeamId = teamMatch.id?.trim();
|
|
146
|
-
const teamName = teamMatch.displayName?.trim() || team;
|
|
147
|
-
if (!graphTeamId) return {
|
|
148
|
-
input,
|
|
149
|
-
resolved: false,
|
|
150
|
-
note: "team id missing"
|
|
151
|
-
};
|
|
152
|
-
let teamChannels = [];
|
|
153
|
-
try {
|
|
154
|
-
teamChannels = await listChannelsForTeam(token, graphTeamId);
|
|
155
|
-
} catch {}
|
|
156
|
-
const teamId = teamChannels.find((ch) => normalizeOptionalLowercaseString(ch.displayName) === "general")?.id?.trim() || graphTeamId;
|
|
157
|
-
if (!channel) return {
|
|
158
|
-
input,
|
|
159
|
-
resolved: true,
|
|
160
|
-
teamId,
|
|
161
|
-
teamName,
|
|
162
|
-
note: teams.length > 1 ? "multiple teams; chose first" : void 0
|
|
163
|
-
};
|
|
164
|
-
const normalizedChannel = normalizeOptionalLowercaseString(channel);
|
|
165
|
-
const channelMatch = teamChannels.find((item) => item.id === channel) ?? teamChannels.find((item) => normalizeOptionalLowercaseString(item.displayName) === normalizedChannel) ?? teamChannels.find((item) => normalizeLowercaseStringOrEmpty(item.displayName ?? "").includes(normalizedChannel ?? ""));
|
|
166
|
-
if (!channelMatch?.id) return {
|
|
167
|
-
input,
|
|
168
|
-
resolved: false,
|
|
169
|
-
note: "channel not found"
|
|
170
|
-
};
|
|
171
|
-
return {
|
|
172
|
-
input,
|
|
173
|
-
resolved: true,
|
|
174
|
-
teamId,
|
|
175
|
-
teamName,
|
|
176
|
-
channelId: channelMatch.id,
|
|
177
|
-
channelName: channelMatch.displayName ?? channel,
|
|
178
|
-
note: teamChannels.length > 1 ? "multiple channels; chose first" : void 0
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
async function resolveMSTeamsUserAllowlist(params) {
|
|
184
|
-
const token = await resolveGraphToken(params.cfg);
|
|
185
|
-
return await mapAllowlistResolutionInputs({
|
|
186
|
-
inputs: params.entries,
|
|
187
|
-
mapInput: async (input) => {
|
|
188
|
-
const query = normalizeQuery(normalizeMSTeamsUserInput(input));
|
|
189
|
-
if (!query) return {
|
|
190
|
-
input,
|
|
191
|
-
resolved: false
|
|
192
|
-
};
|
|
193
|
-
if (/^[0-9a-fA-F-]{16,}$/.test(query)) return {
|
|
194
|
-
input,
|
|
195
|
-
resolved: true,
|
|
196
|
-
id: query
|
|
197
|
-
};
|
|
198
|
-
const users = await searchGraphUsers({
|
|
199
|
-
token,
|
|
200
|
-
query,
|
|
201
|
-
top: 10
|
|
202
|
-
});
|
|
203
|
-
const match = users[0];
|
|
204
|
-
if (!match?.id) return {
|
|
205
|
-
input,
|
|
206
|
-
resolved: false
|
|
207
|
-
};
|
|
208
|
-
return {
|
|
209
|
-
input,
|
|
210
|
-
resolved: true,
|
|
211
|
-
id: match.id,
|
|
212
|
-
name: match.displayName ?? void 0,
|
|
213
|
-
note: users.length > 1 ? "multiple matches; chose first" : void 0
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
//#endregion
|
|
219
|
-
export { parseMSTeamsTeamChannelInput as a, resolveMSTeamsUserAllowlist as c, parseMSTeamsConversationId as i, normalizeMSTeamsMessagingTarget as n, parseMSTeamsTeamEntry as o, normalizeMSTeamsUserInput as r, resolveMSTeamsChannelAllowlist as s, looksLikeMSTeamsTargetId as t };
|
|
File without changes
|