@openclaw/msteams 2026.8.1-beta.2 → 2026.8.1

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.
@@ -1,78 +1,22 @@
1
1
  const require_runtime = require("./runtime-gZTAuFux.cjs");
2
2
  require("./runtime-api.cjs");
3
3
  const require_delegated_state = require("./delegated-state-DiEz9JIa.cjs");
4
+ require("./secret-input-C65t6kjM.cjs");
4
5
  let openclaw_plugin_sdk_lazy_runtime = require("openclaw/plugin-sdk/lazy-runtime");
5
6
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
6
7
  let openclaw_plugin_sdk_allow_from = require("openclaw/plugin-sdk/allow-from");
7
- let openclaw_plugin_sdk_ssrf_runtime = require("openclaw/plugin-sdk/ssrf-runtime");
8
- let openclaw_plugin_sdk_html_entity_runtime = require("openclaw/plugin-sdk/html-entity-runtime");
9
8
  let openclaw_plugin_sdk_fetch_runtime = require("openclaw/plugin-sdk/fetch-runtime");
10
9
  let openclaw_plugin_sdk_provider_http = require("openclaw/plugin-sdk/provider-http");
10
+ let openclaw_plugin_sdk_ssrf_runtime = require("openclaw/plugin-sdk/ssrf-runtime");
11
11
  let node_buffer = require("node:buffer");
12
12
  let node_dns_promises = require("node:dns/promises");
13
13
  let openclaw_plugin_sdk_ssrf_policy = require("openclaw/plugin-sdk/ssrf-policy");
14
14
  let openclaw_plugin_sdk_number_runtime = require("openclaw/plugin-sdk/number-runtime");
15
15
  let openclaw_plugin_sdk_text_utility_runtime = require("openclaw/plugin-sdk/text-utility-runtime");
16
- let openclaw_plugin_sdk_error_runtime = require("openclaw/plugin-sdk/error-runtime");
17
16
  let openclaw_plugin_sdk_secret_file = require("openclaw/plugin-sdk/secret-file");
18
17
  let node_module = require("node:module");
18
+ let openclaw_plugin_sdk_html_entity_runtime = require("openclaw/plugin-sdk/html-entity-runtime");
19
19
  let openclaw_plugin_sdk_secret_input = require("openclaw/plugin-sdk/secret-input");
20
- //#region extensions/msteams/src/inbound.ts
21
- /**
22
- * Strip HTML tags, preserving text content.
23
- */
24
- function htmlToPlainText(html) {
25
- return (0, openclaw_plugin_sdk_html_entity_runtime.decodeHtmlEntities)(html.replace(/<[^>]*>/g, " ")).replaceAll("\xA0", " ").replace(/\s+/g, " ").trim();
26
- }
27
- /**
28
- * Extract quote info from MS Teams HTML reply attachments.
29
- * Teams wraps quoted content in a blockquote with itemtype="http://schema.skype.com/Reply".
30
- */
31
- function extractMSTeamsQuoteInfo(attachments) {
32
- for (const att of attachments) {
33
- let content = "";
34
- if (typeof att.content === "string") content = att.content;
35
- else if (typeof att.content === "object" && att.content !== null) {
36
- const record = att.content;
37
- content = typeof record.text === "string" ? record.text : typeof record.body === "string" ? record.body : "";
38
- }
39
- if (!content) continue;
40
- if (!content.includes("http://schema.skype.com/Reply")) continue;
41
- const senderMatch = /<strong[^>]*itemprop=["']mri["'][^>]*>(.*?)<\/strong>/i.exec(content);
42
- const sender = senderMatch?.[1] ? htmlToPlainText(senderMatch[1]) : void 0;
43
- const bodyMatch = /<p[^>]*itemprop=["']copy["'][^>]*>(.*?)<\/p>/is.exec(content) ?? /<p[^>]*itemprop=["']preview["'][^>]*>(.*?)<\/p>/is.exec(content);
44
- const body = bodyMatch?.[1] ? htmlToPlainText(bodyMatch[1]) : void 0;
45
- const id = /<blockquote[^>]*\bitemid=["']([^"']+)["'][^>]*>/is.exec(content)?.[1]?.trim() || void 0;
46
- if (body) return {
47
- sender: sender ?? "unknown",
48
- body,
49
- ...id ? { id } : {}
50
- };
51
- }
52
- }
53
- function normalizeMSTeamsConversationId(raw) {
54
- return raw.split(";")[0] ?? raw;
55
- }
56
- function extractMSTeamsConversationMessageId(raw) {
57
- if (!raw) return;
58
- return (/(?:^|;)messageid=([^;]+)/i.exec(raw)?.[1]?.trim() ?? "") || void 0;
59
- }
60
- function parseMSTeamsActivityTimestamp(value) {
61
- if (!value) return;
62
- if (value instanceof Date) return value;
63
- if (typeof value !== "string") return;
64
- const date = new Date(value);
65
- return Number.isNaN(date.getTime()) ? void 0 : date;
66
- }
67
- function stripMSTeamsMentionTags(text) {
68
- return text.replace(/<at[^>]*>.*?<\/at>/gi, "").trim();
69
- }
70
- function wasMSTeamsBotMentioned(activity) {
71
- const botId = activity.recipient?.id;
72
- if (!botId) return false;
73
- return (activity.entities ?? []).some((e) => e.type === "mention" && e.mentioned?.id === botId);
74
- }
75
- //#endregion
76
20
  //#region extensions/msteams/src/request-timeout.ts
77
21
  const MSTEAMS_REQUEST_TIMEOUT_MS = 3e4;
78
22
  const MSTEAMS_SHAREPOINT_UPLOAD_BASE_TIMEOUT_MS = 5 * 6e4;
@@ -167,25 +111,6 @@ const DEFAULT_MEDIA_AUTH_HOST_ALLOWLIST = [
167
111
  "graph.microsoft.cn"
168
112
  ];
169
113
  const GRAPH_ROOT = "https://graph.microsoft.com/v1.0";
170
- function estimateBase64DecodedBytes(base64) {
171
- let effectiveLen = 0;
172
- for (let i = 0; i < base64.length; i += 1) {
173
- if (base64.charCodeAt(i) <= 32) continue;
174
- effectiveLen += 1;
175
- }
176
- if (effectiveLen === 0) return 0;
177
- let padding = 0;
178
- let end = base64.length - 1;
179
- while (end >= 0 && base64.charCodeAt(end) <= 32) end -= 1;
180
- if (end >= 0 && base64[end] === "=") {
181
- padding = 1;
182
- end -= 1;
183
- while (end >= 0 && base64.charCodeAt(end) <= 32) end -= 1;
184
- if (end >= 0 && base64[end] === "=") padding = 2;
185
- }
186
- const estimated = Math.floor(effectiveLen * 3 / 4) - padding;
187
- return Math.max(0, estimated);
188
- }
189
114
  /**
190
115
  * Host suffixes for SharePoint/OneDrive shared links that must be fetched via
191
116
  * the Graph `/shares/{shareId}/driveItem/content` endpoint instead of directly.
@@ -210,14 +135,15 @@ const GRAPH_SHARED_LINK_HOST_SUFFIXES = [
210
135
  * than directly.
211
136
  */
212
137
  function isGraphSharedLinkUrl(url) {
213
- let host;
138
+ let parsed;
214
139
  try {
215
- host = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(new URL(url).hostname);
140
+ parsed = new URL(url);
216
141
  } catch {
217
142
  return false;
218
143
  }
219
- if (!host) return false;
220
- return GRAPH_SHARED_LINK_HOST_SUFFIXES.some((suffix) => host === suffix || host.endsWith(suffix));
144
+ const host = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(parsed.hostname);
145
+ if (parsed.protocol !== "https:" || !host) return false;
146
+ return GRAPH_SHARED_LINK_HOST_SUFFIXES.some((suffix) => host === suffix || host.endsWith(suffix.startsWith(".") ? suffix : `.${suffix}`));
221
147
  }
222
148
  /**
223
149
  * Encode a SharePoint/OneDrive URL as a Graph shareId using the documented
@@ -331,7 +257,7 @@ function decodeDataImageWithLimits(src, opts) {
331
257
  candidate: null,
332
258
  estimatedBytes: 0
333
259
  };
334
- const estimatedBytes = estimateBase64DecodedBytes(canonicalPayload);
260
+ const estimatedBytes = node_buffer.Buffer.byteLength(canonicalPayload, "base64");
335
261
  if (estimatedBytes <= 0) return {
336
262
  candidate: null,
337
263
  estimatedBytes: 0
@@ -504,7 +430,7 @@ async function safeFetch(params) {
504
430
  const resolveFn = params.resolveFn ?? node_dns_promises.lookup;
505
431
  const hasDispatcher = Boolean(params.requestInit && typeof params.requestInit === "object" && "dispatcher" in params.requestInit);
506
432
  const currentHeaders = new Headers(params.requestInit?.headers);
507
- let currentUrl = params.url;
433
+ const currentUrl = params.url;
508
434
  if (!isUrlAllowed(currentUrl, params.allowHosts)) throw new Error(`Initial download URL blocked: ${currentUrl}`);
509
435
  if (currentHeaders.has("authorization") && params.authorizationAllowHosts && !isUrlAllowed(currentUrl, params.authorizationAllowHosts)) currentHeaders.delete("authorization");
510
436
  if (!hasDispatcher) {
@@ -535,37 +461,29 @@ async function safeFetch(params) {
535
461
  });
536
462
  return (0, openclaw_plugin_sdk_fetch_runtime.responseWithRelease)(guarded.response, guarded.release);
537
463
  }
538
- if (resolveFn) try {
464
+ try {
539
465
  const initialHost = new URL(currentUrl).hostname;
540
466
  await resolveAndValidateIP(initialHost, resolveFn);
541
467
  } catch {
542
468
  throw new Error(`Initial download URL blocked: ${currentUrl}`);
543
469
  }
544
- for (let i = 0; i <= MAX_SAFE_REDIRECTS; i++) {
545
- const res = await (params.fetchFn ?? fetch)(currentUrl, {
546
- ...params.requestInit,
547
- headers: currentHeaders,
548
- redirect: "manual"
549
- });
550
- if (!isRedirectStatus(res.status)) return res;
551
- const location = res.headers.get("location");
552
- if (!location) return res;
553
- let redirectUrl;
554
- try {
555
- redirectUrl = new URL(location, currentUrl).toString();
556
- } catch {
557
- throw new Error(`Invalid redirect URL: ${location}`);
558
- }
559
- if (!isUrlAllowed(redirectUrl, params.allowHosts)) throw new Error(`Media redirect target blocked by allowlist: ${redirectUrl}`);
560
- if (currentHeaders.has("authorization") && params.authorizationAllowHosts && !isUrlAllowed(redirectUrl, params.authorizationAllowHosts)) currentHeaders.delete("authorization");
561
- if (hasDispatcher) return res;
562
- if (resolveFn) {
563
- const redirectHost = new URL(redirectUrl).hostname;
564
- await resolveAndValidateIP(redirectHost, resolveFn);
565
- }
566
- currentUrl = redirectUrl;
470
+ const res = await (params.fetchFn ?? fetch)(currentUrl, {
471
+ ...params.requestInit,
472
+ headers: currentHeaders,
473
+ redirect: "manual"
474
+ });
475
+ if (!isRedirectStatus(res.status)) return res;
476
+ const location = res.headers.get("location");
477
+ if (!location) return res;
478
+ let redirectUrl;
479
+ try {
480
+ redirectUrl = new URL(location, currentUrl).toString();
481
+ } catch {
482
+ throw new Error(`Invalid redirect URL: ${location}`);
567
483
  }
568
- throw new Error(`Too many redirects (>${MAX_SAFE_REDIRECTS})`);
484
+ if (!isUrlAllowed(redirectUrl, params.allowHosts)) throw new Error(`Media redirect target blocked by allowlist: ${redirectUrl}`);
485
+ if (currentHeaders.has("authorization") && params.authorizationAllowHosts && !isUrlAllowed(redirectUrl, params.authorizationAllowHosts)) currentHeaders.delete("authorization");
486
+ return res;
569
487
  }
570
488
  async function safeFetchWithPolicy(params) {
571
489
  return await safeFetch({
@@ -715,7 +633,7 @@ var PrivateQaHttpClient = class PrivateQaHttpClient {
715
633
  try {
716
634
  const text = await response.text();
717
635
  const data = text ? JSON.parse(text) : void 0;
718
- if (!response.ok) throw new Error(`Microsoft Teams private QA connector returned HTTP ${response.status}`);
636
+ if (!response.ok) throw Object.assign(/* @__PURE__ */ new Error(`Microsoft Teams private QA connector returned HTTP ${response.status}`), { statusCode: response.status });
719
637
  return {
720
638
  data,
721
639
  status: response.status,
@@ -879,7 +797,10 @@ async function createMSTeamsApp(creds, options) {
879
797
  ...serviceUrl ? { serviceUrl } : {},
880
798
  ...options?.oauthDefaultConnectionName ? { oauth: { defaultConnectionName: options.oauthDefaultConnectionName } } : {}
881
799
  };
882
- if (creds.type === "federated") return await createFederatedApp(creds, App, appOptions);
800
+ if (creds.type === "federated") return await createFederatedApp(creds, App, {
801
+ clientSecret: "",
802
+ ...appOptions
803
+ });
883
804
  return new App({
884
805
  clientId: creds.appId,
885
806
  clientSecret: creds.appPassword,
@@ -898,9 +819,8 @@ async function createFederatedApp(creds, App, appOptions) {
898
819
  let privateKey;
899
820
  try {
900
821
  privateKey = await (0, openclaw_plugin_sdk_secret_file.readSecretFile)(creds.certificatePath, "Microsoft Teams certificate");
901
- } catch (err) {
902
- const msg = (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err);
903
- throw new Error(`Failed to read certificate file at '${creds.certificatePath}': ${msg}`, { cause: err });
822
+ } catch {
823
+ throw new Error("Failed to read certificate file: the configured credential is unavailable.");
904
824
  }
905
825
  return createCertificateApp(creds, privateKey, App, appOptions);
906
826
  }
@@ -1359,6 +1279,62 @@ async function findGraphUsersByExactIdentity(params) {
1359
1279
  });
1360
1280
  }
1361
1281
  //#endregion
1282
+ //#region extensions/msteams/src/inbound.ts
1283
+ /**
1284
+ * Strip HTML tags, preserving text content.
1285
+ */
1286
+ function htmlToPlainText(html) {
1287
+ return (0, openclaw_plugin_sdk_html_entity_runtime.decodeHtmlEntities)(html.replace(/<[^>]*>/g, " ")).replaceAll("\xA0", " ").replace(/\s+/g, " ").trim();
1288
+ }
1289
+ /**
1290
+ * Extract quote info from MS Teams HTML reply attachments.
1291
+ * Teams wraps quoted content in a blockquote with itemtype="http://schema.skype.com/Reply".
1292
+ */
1293
+ function extractMSTeamsQuoteInfo(attachments) {
1294
+ for (const att of attachments) {
1295
+ let content = "";
1296
+ if (typeof att.content === "string") content = att.content;
1297
+ else if (typeof att.content === "object" && att.content !== null) {
1298
+ const record = att.content;
1299
+ content = typeof record.text === "string" ? record.text : typeof record.body === "string" ? record.body : "";
1300
+ }
1301
+ if (!content) continue;
1302
+ if (!content.includes("http://schema.skype.com/Reply")) continue;
1303
+ const senderMatch = /<strong[^>]*itemprop=["']mri["'][^>]*>(.*?)<\/strong>/i.exec(content);
1304
+ const sender = senderMatch?.[1] ? htmlToPlainText(senderMatch[1]) : void 0;
1305
+ const bodyMatch = /<p[^>]*itemprop=["']copy["'][^>]*>(.*?)<\/p>/is.exec(content) ?? /<p[^>]*itemprop=["']preview["'][^>]*>(.*?)<\/p>/is.exec(content);
1306
+ const body = bodyMatch?.[1] ? htmlToPlainText(bodyMatch[1]) : void 0;
1307
+ const id = /<blockquote[^>]*\bitemid=["']([^"']+)["'][^>]*>/is.exec(content)?.[1]?.trim() || void 0;
1308
+ if (body) return {
1309
+ sender: sender ?? "unknown",
1310
+ body,
1311
+ ...id ? { id } : {}
1312
+ };
1313
+ }
1314
+ }
1315
+ function normalizeMSTeamsConversationId(raw) {
1316
+ return raw.split(";")[0] ?? raw;
1317
+ }
1318
+ function extractMSTeamsConversationMessageId(raw) {
1319
+ if (!raw) return;
1320
+ return (/(?:^|;)messageid=([^;]+)/i.exec(raw)?.[1]?.trim() ?? "") || void 0;
1321
+ }
1322
+ function parseMSTeamsActivityTimestamp(value) {
1323
+ if (!value) return;
1324
+ if (value instanceof Date) return value;
1325
+ if (typeof value !== "string") return;
1326
+ const date = new Date(value);
1327
+ return Number.isNaN(date.getTime()) ? void 0 : date;
1328
+ }
1329
+ function stripMSTeamsMentionTags(text) {
1330
+ return text.replace(/<at[^>]*>.*?<\/at>/gi, "").trim();
1331
+ }
1332
+ function wasMSTeamsBotMentioned(activity) {
1333
+ const botId = activity.recipient?.id;
1334
+ if (!botId) return false;
1335
+ return (activity.entities ?? []).some((e) => e.type === "mention" && e.mentioned?.id === botId);
1336
+ }
1337
+ //#endregion
1362
1338
  //#region extensions/msteams/src/resolve-allowlist.ts
1363
1339
  const MSTEAMS_GROUP_CONVERSATION_ID = /^19:.+@thread\.(?:tacv2|skype|v2)$/i;
1364
1340
  function normalizeExactMatch(value) {
@@ -3,14 +3,15 @@ const require_runtime = require("./runtime-gZTAuFux.cjs");
3
3
  let openclaw_plugin_sdk_channel_outbound = require("openclaw/plugin-sdk/channel-outbound");
4
4
  let openclaw_plugin_sdk_channel_pairing = require("openclaw/plugin-sdk/channel-pairing");
5
5
  let openclaw_plugin_sdk_channel_policy = require("openclaw/plugin-sdk/channel-policy");
6
- let openclaw_plugin_sdk_account_id = require("openclaw/plugin-sdk/account-id");
7
6
  let openclaw_plugin_sdk_allow_from = require("openclaw/plugin-sdk/allow-from");
7
+ let openclaw_plugin_sdk_account_id = require("openclaw/plugin-sdk/account-id");
8
8
  let openclaw_plugin_sdk_channel_status = require("openclaw/plugin-sdk/channel-status");
9
9
  let openclaw_plugin_sdk_channel_targets = require("openclaw/plugin-sdk/channel-targets");
10
10
  let openclaw_plugin_sdk_dangerous_name_runtime = require("openclaw/plugin-sdk/dangerous-name-runtime");
11
11
  let openclaw_plugin_sdk_runtime_group_policy = require("openclaw/plugin-sdk/runtime-group-policy");
12
12
  let openclaw_plugin_sdk_file_lock = require("openclaw/plugin-sdk/file-lock");
13
13
  let openclaw_plugin_sdk_media_runtime = require("openclaw/plugin-sdk/media-runtime");
14
+ let openclaw_plugin_sdk_account_helpers = require("openclaw/plugin-sdk/account-helpers");
14
15
  let openclaw_plugin_sdk_outbound_media = require("openclaw/plugin-sdk/outbound-media");
15
16
  let openclaw_plugin_sdk_reply_payload = require("openclaw/plugin-sdk/reply-payload");
16
17
  let openclaw_plugin_sdk_ssrf_runtime = require("openclaw/plugin-sdk/ssrf-runtime");
@@ -164,7 +165,7 @@ Object.defineProperty(exports, "resolveChannelEntryMatchWithFallback", {
164
165
  Object.defineProperty(exports, "resolveChannelMediaMaxBytes", {
165
166
  enumerable: true,
166
167
  get: function() {
167
- return openclaw_plugin_sdk_media_runtime.resolveChannelMediaMaxBytes;
168
+ return openclaw_plugin_sdk_account_helpers.resolveChannelMediaMaxBytes;
168
169
  }
169
170
  });
170
171
  Object.defineProperty(exports, "resolveDefaultGroupPolicy", {
@@ -0,0 +1 @@
1
+ require("openclaw/plugin-sdk/secret-input");