@openclaw/msteams 2026.7.2-beta.7 → 2026.8.1-beta.3
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/adapter.runtime-8g-MOPfb.cjs +311 -0
- package/dist/api.cjs +6 -6
- package/dist/{channel-C7QxRjBW.cjs → channel-KpWENcgK.cjs} +222 -265
- package/dist/channel-plugin-api.cjs +1 -1
- package/dist/{channel.runtime-DjY6d_hd.cjs → channel.runtime-Bkzj8jZ0.cjs} +131 -88
- package/dist/{setup-surface-ByWjaXEn.cjs → channel.setup-mOFtsfYz.cjs} +91 -50
- package/dist/directory-contract-api.cjs +1 -1
- package/dist/doctor-contract-api.cjs +18 -17
- package/dist/{messenger-DTiaLTDO.cjs → messenger-IISPSOvj.cjs} +61 -46
- package/dist/{oauth-CW6jVGp8.cjs → oauth-C9So7uld.cjs} +13 -26
- package/dist/{polls-BWKNpBSg.cjs → polls-DvuJvaDG.cjs} +6 -39
- package/dist/qa-runner-api.cjs +36 -0
- package/dist/{resolve-allowlist-CEj9sABO.cjs → resolve-allowlist-CIfWUwuc.cjs} +182 -118
- package/dist/rolldown-runtime-D6vf50IK.cjs +28 -0
- package/dist/runtime-api.cjs +1 -1
- package/dist/secret-contract-api.cjs +6 -30
- package/dist/setup-plugin-api.cjs +2 -37
- package/dist/{src-B_BdEvcr.cjs → src-C127-DcQ.cjs} +439 -269
- package/dist/{sso-token-store-TKYk_Ms7.cjs → sso-token-store-ChhO1f4i.cjs} +1 -1
- package/openclaw.plugin.json +34 -8
- package/package.json +4 -5
|
@@ -1,43 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __copyProps = (to, from, except, desc) => {
|
|
9
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
-
key = keys[i];
|
|
11
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
-
get: ((k) => from[k]).bind(null, key),
|
|
13
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
-
value: mod,
|
|
20
|
-
enumerable: true
|
|
21
|
-
}) : target, mod));
|
|
22
|
-
//#endregion
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-D6vf50IK.cjs");
|
|
23
2
|
const require_runtime = require("./runtime-gZTAuFux.cjs");
|
|
24
3
|
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
25
4
|
let openclaw_plugin_sdk_file_lock = require("openclaw/plugin-sdk/file-lock");
|
|
26
5
|
let openclaw_plugin_sdk_number_runtime = require("openclaw/plugin-sdk/number-runtime");
|
|
27
6
|
let node_crypto = require("node:crypto");
|
|
28
|
-
node_crypto = __toESM(node_crypto, 1);
|
|
7
|
+
node_crypto = require_rolldown_runtime.__toESM(node_crypto, 1);
|
|
29
8
|
let node_path = require("node:path");
|
|
30
|
-
node_path = __toESM(node_path, 1);
|
|
9
|
+
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
31
10
|
let openclaw_plugin_sdk_keyed_async_queue = require("openclaw/plugin-sdk/keyed-async-queue");
|
|
32
11
|
//#region extensions/msteams/src/conversation-store-helpers.ts
|
|
33
12
|
function normalizeStoredConversationId(raw) {
|
|
34
13
|
return raw.split(";")[0] ?? raw;
|
|
35
14
|
}
|
|
36
15
|
function parseStoredConversationTimestamp(value) {
|
|
37
|
-
|
|
38
|
-
const parsed = Date.parse(value);
|
|
39
|
-
if (!Number.isFinite(parsed)) return null;
|
|
40
|
-
return parsed;
|
|
16
|
+
return (0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(value) ?? null;
|
|
41
17
|
}
|
|
42
18
|
function toConversationStoreEntries(entries) {
|
|
43
19
|
return Array.from(entries, ([conversationId, reference]) => ({
|
|
@@ -384,9 +360,7 @@ function createPollVoteBucketStateStore(params) {
|
|
|
384
360
|
});
|
|
385
361
|
}
|
|
386
362
|
function parseTimestamp(value) {
|
|
387
|
-
|
|
388
|
-
const parsed = Date.parse(value);
|
|
389
|
-
return Number.isFinite(parsed) ? parsed : null;
|
|
363
|
+
return (0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(value) ?? null;
|
|
390
364
|
}
|
|
391
365
|
function pruneExpired(polls) {
|
|
392
366
|
const cutoff = Date.now() - MSTEAMS_POLL_TTL_MS;
|
|
@@ -405,8 +379,7 @@ function selectRetainedMSTeamsPolls(polls) {
|
|
|
405
379
|
}
|
|
406
380
|
function normalizeMSTeamsPollSelections(poll, selections) {
|
|
407
381
|
const maxSelections = Math.max(1, poll.maxSelections);
|
|
408
|
-
|
|
409
|
-
return (0, openclaw_plugin_sdk_string_coerce_runtime.uniqueStrings)(maxSelections > 1 ? mapped.slice(0, maxSelections) : mapped.slice(0, 1));
|
|
382
|
+
return (0, openclaw_plugin_sdk_string_coerce_runtime.uniqueStrings)(selections.map((entry) => (0, openclaw_plugin_sdk_number_runtime.parseStrictNonNegativeInteger)(entry)).filter((value) => value !== void 0).filter((value) => value >= 0 && value < poll.options.length).map((value) => String(value))).slice(0, maxSelections);
|
|
410
383
|
}
|
|
411
384
|
function splitMSTeamsPoll(poll) {
|
|
412
385
|
const { votes, ...metadata } = poll;
|
|
@@ -589,12 +562,6 @@ Object.defineProperty(exports, "MSTEAMS_SQLITE_MAX_POLL_ROWS", {
|
|
|
589
562
|
return MSTEAMS_SQLITE_MAX_POLL_ROWS;
|
|
590
563
|
}
|
|
591
564
|
});
|
|
592
|
-
Object.defineProperty(exports, "__toESM", {
|
|
593
|
-
enumerable: true,
|
|
594
|
-
get: function() {
|
|
595
|
-
return __toESM;
|
|
596
|
-
}
|
|
597
|
-
});
|
|
598
565
|
Object.defineProperty(exports, "buildMSTeamsConversationStateKey", {
|
|
599
566
|
enumerable: true,
|
|
600
567
|
get: function() {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let openclaw_plugin_sdk_qa_runner_runtime = require("openclaw/plugin-sdk/qa-runner-runtime");
|
|
3
|
+
//#region extensions/msteams/src/qa/cli.ts
|
|
4
|
+
const DEFAULT_MSTEAMS_QA_SCENARIOS = ["channel-canary"];
|
|
5
|
+
const loadMSTeamsQaAdapterRuntime = (0, openclaw_plugin_sdk_qa_runner_runtime.createLazyCliRuntimeLoader)(() => Promise.resolve().then(() => require("./adapter.runtime-8g-MOPfb.cjs")));
|
|
6
|
+
async function runQaMSTeams(options) {
|
|
7
|
+
await (0, openclaw_plugin_sdk_qa_runner_runtime.runLiveTransportQaSuiteCommand)({
|
|
8
|
+
channelId: "msteams",
|
|
9
|
+
defaultProviderMode: "mock-openai",
|
|
10
|
+
options,
|
|
11
|
+
selectScenarioIds: ({ scenarioIds }) => scenarioIds?.length ? [...scenarioIds] : [...DEFAULT_MSTEAMS_QA_SCENARIOS]
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region extensions/msteams/qa-runner-api.ts
|
|
16
|
+
const qaRunnerCliRegistrations = [(0, openclaw_plugin_sdk_qa_runner_runtime.createLiveTransportQaCliRegistration)({
|
|
17
|
+
commandName: "msteams",
|
|
18
|
+
adapterFactory: {
|
|
19
|
+
id: "msteams",
|
|
20
|
+
isolatesInstances: true,
|
|
21
|
+
matches: ({ channelId, driver }) => channelId === "msteams" && driver === "live",
|
|
22
|
+
async create(context) {
|
|
23
|
+
return await (await loadMSTeamsQaAdapterRuntime()).createMSTeamsQaTransportAdapter(context);
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
defaultProviderMode: "mock-openai",
|
|
27
|
+
description: "Run Microsoft Teams Gateway QA against a local Bot Framework mock",
|
|
28
|
+
providerModeHelp: "Provider mode: mock-openai, aimock, or live-frontier",
|
|
29
|
+
outputDirHelp: "Microsoft Teams QA artifact directory",
|
|
30
|
+
allowFailuresHelp: "Write artifacts without setting a failing exit code when scenarios fail",
|
|
31
|
+
scenarioHelp: "Run only the named Microsoft Teams QA scenario (repeatable)",
|
|
32
|
+
sutAccountHelp: "Normalized Microsoft Teams SUT account id in QA artifacts",
|
|
33
|
+
run: runQaMSTeams
|
|
34
|
+
})];
|
|
35
|
+
//#endregion
|
|
36
|
+
exports.qaRunnerCliRegistrations = qaRunnerCliRegistrations;
|
|
@@ -4,8 +4,9 @@ const require_delegated_state = require("./delegated-state-DiEz9JIa.cjs");
|
|
|
4
4
|
let openclaw_plugin_sdk_lazy_runtime = require("openclaw/plugin-sdk/lazy-runtime");
|
|
5
5
|
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
6
6
|
let openclaw_plugin_sdk_allow_from = require("openclaw/plugin-sdk/allow-from");
|
|
7
|
-
let
|
|
7
|
+
let openclaw_plugin_sdk_fetch_runtime = require("openclaw/plugin-sdk/fetch-runtime");
|
|
8
8
|
let openclaw_plugin_sdk_provider_http = require("openclaw/plugin-sdk/provider-http");
|
|
9
|
+
let openclaw_plugin_sdk_ssrf_runtime = require("openclaw/plugin-sdk/ssrf-runtime");
|
|
9
10
|
let node_buffer = require("node:buffer");
|
|
10
11
|
let node_dns_promises = require("node:dns/promises");
|
|
11
12
|
let openclaw_plugin_sdk_ssrf_policy = require("openclaw/plugin-sdk/ssrf-policy");
|
|
@@ -58,52 +59,6 @@ async function withMSTeamsAbortableRequestTimeout(params) {
|
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
//#endregion
|
|
61
|
-
//#region extensions/msteams/src/response-with-release.ts
|
|
62
|
-
const NULL_BODY_STATUSES = /* @__PURE__ */ new Set([
|
|
63
|
-
101,
|
|
64
|
-
204,
|
|
65
|
-
205,
|
|
66
|
-
304
|
|
67
|
-
]);
|
|
68
|
-
function responseWithRelease(response, release) {
|
|
69
|
-
let released = false;
|
|
70
|
-
const releaseOnce = async () => {
|
|
71
|
-
if (released) return;
|
|
72
|
-
released = true;
|
|
73
|
-
await release();
|
|
74
|
-
};
|
|
75
|
-
if (!response.body || NULL_BODY_STATUSES.has(response.status)) {
|
|
76
|
-
releaseOnce();
|
|
77
|
-
return response;
|
|
78
|
-
}
|
|
79
|
-
const reader = response.body.getReader();
|
|
80
|
-
const body = new ReadableStream({
|
|
81
|
-
async pull(controller) {
|
|
82
|
-
try {
|
|
83
|
-
const next = await reader.read();
|
|
84
|
-
if (next.done) {
|
|
85
|
-
controller.close();
|
|
86
|
-
await releaseOnce();
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
controller.enqueue(next.value);
|
|
90
|
-
} catch (error) {
|
|
91
|
-
await releaseOnce();
|
|
92
|
-
throw error;
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
async cancel(reason) {
|
|
96
|
-
reader.cancel(reason).catch(() => void 0);
|
|
97
|
-
await releaseOnce();
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
return new Response(body, {
|
|
101
|
-
status: response.status,
|
|
102
|
-
statusText: response.statusText,
|
|
103
|
-
headers: response.headers
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
//#endregion
|
|
107
62
|
//#region extensions/msteams/src/attachments/shared.ts
|
|
108
63
|
const IMAGE_EXT_RE = /\.(avif|bmp|gif|heic|heif|jpe?g|png|tiff?|webp)$/i;
|
|
109
64
|
const IMG_SRC_RE = /<img[^>]+src=["']([^"']+)["'][^>]*>/gi;
|
|
@@ -198,14 +153,15 @@ const GRAPH_SHARED_LINK_HOST_SUFFIXES = [
|
|
|
198
153
|
* than directly.
|
|
199
154
|
*/
|
|
200
155
|
function isGraphSharedLinkUrl(url) {
|
|
201
|
-
let
|
|
156
|
+
let parsed;
|
|
202
157
|
try {
|
|
203
|
-
|
|
158
|
+
parsed = new URL(url);
|
|
204
159
|
} catch {
|
|
205
160
|
return false;
|
|
206
161
|
}
|
|
207
|
-
|
|
208
|
-
|
|
162
|
+
const host = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(parsed.hostname);
|
|
163
|
+
if (parsed.protocol !== "https:" || !host) return false;
|
|
164
|
+
return GRAPH_SHARED_LINK_HOST_SUFFIXES.some((suffix) => host === suffix || host.endsWith(suffix.startsWith(".") ? suffix : `.${suffix}`));
|
|
209
165
|
}
|
|
210
166
|
/**
|
|
211
167
|
* Encode a SharePoint/OneDrive URL as a Graph shareId using the documented
|
|
@@ -477,6 +433,9 @@ async function resolveAndValidateIP(hostname, resolveFn) {
|
|
|
477
433
|
}
|
|
478
434
|
/** Maximum number of redirects to follow in safeFetch. */
|
|
479
435
|
const MAX_SAFE_REDIRECTS = 5;
|
|
436
|
+
function isRedirectStatus(status) {
|
|
437
|
+
return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
|
|
438
|
+
}
|
|
480
439
|
/**
|
|
481
440
|
* Fetch a URL with redirect: "manual", validating each redirect target
|
|
482
441
|
* against the hostname allowlist and optional DNS-resolved IP (anti-SSRF).
|
|
@@ -493,6 +452,13 @@ async function safeFetch(params) {
|
|
|
493
452
|
if (!isUrlAllowed(currentUrl, params.allowHosts)) throw new Error(`Initial download URL blocked: ${currentUrl}`);
|
|
494
453
|
if (currentHeaders.has("authorization") && params.authorizationAllowHosts && !isUrlAllowed(currentUrl, params.authorizationAllowHosts)) currentHeaders.delete("authorization");
|
|
495
454
|
if (!hasDispatcher) {
|
|
455
|
+
const lookupFn = async (hostname) => {
|
|
456
|
+
const resolved = await resolveFn(hostname);
|
|
457
|
+
return [{
|
|
458
|
+
...resolved,
|
|
459
|
+
family: resolved.address.includes(":") ? 6 : 4
|
|
460
|
+
}];
|
|
461
|
+
};
|
|
496
462
|
const guarded = await (0, openclaw_plugin_sdk_ssrf_runtime.fetchWithSsrFGuard)({
|
|
497
463
|
url: currentUrl,
|
|
498
464
|
fetchImpl: resolveGuardedFetchImpl({
|
|
@@ -506,12 +472,12 @@ async function safeFetch(params) {
|
|
|
506
472
|
maxRedirects: MAX_SAFE_REDIRECTS,
|
|
507
473
|
requireHttps: true,
|
|
508
474
|
policy: resolveMediaSsrfPolicy(params.allowHosts),
|
|
509
|
-
lookupFn
|
|
475
|
+
lookupFn,
|
|
510
476
|
retainAuthorizationRedirectHostnameAllowlist: resolveRetainedAuthorizationRedirectHostnameAllowlist(params.authorizationAllowHosts),
|
|
511
477
|
auditContext: "msteams.attachment",
|
|
512
478
|
timeoutMs: params.timeoutMs ?? 3e4
|
|
513
479
|
});
|
|
514
|
-
return responseWithRelease(guarded.response, guarded.release);
|
|
480
|
+
return (0, openclaw_plugin_sdk_fetch_runtime.responseWithRelease)(guarded.response, guarded.release);
|
|
515
481
|
}
|
|
516
482
|
if (resolveFn) try {
|
|
517
483
|
const initialHost = new URL(currentUrl).hostname;
|
|
@@ -525,13 +491,7 @@ async function safeFetch(params) {
|
|
|
525
491
|
headers: currentHeaders,
|
|
526
492
|
redirect: "manual"
|
|
527
493
|
});
|
|
528
|
-
if (!
|
|
529
|
-
301,
|
|
530
|
-
302,
|
|
531
|
-
303,
|
|
532
|
-
307,
|
|
533
|
-
308
|
|
534
|
-
].includes(res.status)) return res;
|
|
494
|
+
if (!isRedirectStatus(res.status)) return res;
|
|
535
495
|
const location = res.headers.get("location");
|
|
536
496
|
if (!location) return res;
|
|
537
497
|
let redirectUrl;
|
|
@@ -656,6 +616,117 @@ function normalizeBotFrameworkServiceUrl(serviceUrl) {
|
|
|
656
616
|
throw new Error(`Blocked Microsoft Teams serviceUrl host: ${describeBotFrameworkServiceUrlHost(serviceUrl)}`);
|
|
657
617
|
}
|
|
658
618
|
//#endregion
|
|
619
|
+
//#region extensions/msteams/src/qa/private-runtime.ts
|
|
620
|
+
const PRIVATE_QA_BUILD_ENV = "OPENCLAW_BUILD_PRIVATE_QA";
|
|
621
|
+
const PRIVATE_QA_NONCE_HEADER = "x-openclaw-msteams-qa-nonce";
|
|
622
|
+
const PRIVATE_QA_RUNTIME_SYMBOL = Symbol.for("openclaw.msteams.privateQaRuntime");
|
|
623
|
+
var PrivateQaHttpClient = class PrivateQaHttpClient {
|
|
624
|
+
constructor(connectorUrl, nonce, options = {}) {
|
|
625
|
+
this.connectorUrl = connectorUrl;
|
|
626
|
+
this.nonce = nonce;
|
|
627
|
+
this.options = options;
|
|
628
|
+
}
|
|
629
|
+
clone(options = {}) {
|
|
630
|
+
return new PrivateQaHttpClient(this.connectorUrl, this.nonce, {
|
|
631
|
+
...this.options,
|
|
632
|
+
...options,
|
|
633
|
+
headers: {
|
|
634
|
+
...this.options.headers,
|
|
635
|
+
...options.headers
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
async request(config) {
|
|
640
|
+
const sourceUrl = new URL(config.url ?? "", "https://smba.trafficmanager.net");
|
|
641
|
+
const targetUrl = new URL(`${sourceUrl.pathname}${sourceUrl.search}`, this.connectorUrl);
|
|
642
|
+
const headers = new Headers(this.options.headers);
|
|
643
|
+
for (const [key, value] of Object.entries(config.headers ?? {})) if (value != null) headers.set(key, String(value));
|
|
644
|
+
headers.set(PRIVATE_QA_NONCE_HEADER, this.nonce);
|
|
645
|
+
const token = typeof this.options.token === "function" ? await this.options.token() : this.options.token;
|
|
646
|
+
if (token) headers.set("authorization", `Bearer ${token}`);
|
|
647
|
+
const method = String(config.method ?? "GET").toUpperCase();
|
|
648
|
+
const { response, release } = await (0, openclaw_plugin_sdk_ssrf_runtime.fetchWithSsrFGuard)({
|
|
649
|
+
url: targetUrl.toString(),
|
|
650
|
+
init: {
|
|
651
|
+
method,
|
|
652
|
+
headers,
|
|
653
|
+
body: method === "GET" || method === "HEAD" || config.data == null ? void 0 : typeof config.data === "string" ? config.data : JSON.stringify(config.data)
|
|
654
|
+
},
|
|
655
|
+
policy: (0, openclaw_plugin_sdk_ssrf_runtime.ssrfPolicyFromHttpBaseUrlAllowedOrigin)(targetUrl.toString()),
|
|
656
|
+
maxRedirects: 0,
|
|
657
|
+
auditContext: "msteams-private-qa-connector"
|
|
658
|
+
});
|
|
659
|
+
try {
|
|
660
|
+
const text = await response.text();
|
|
661
|
+
const data = text ? JSON.parse(text) : void 0;
|
|
662
|
+
if (!response.ok) throw Object.assign(/* @__PURE__ */ new Error(`Microsoft Teams private QA connector returned HTTP ${response.status}`), { statusCode: response.status });
|
|
663
|
+
return {
|
|
664
|
+
data,
|
|
665
|
+
status: response.status,
|
|
666
|
+
statusText: response.statusText,
|
|
667
|
+
headers: Object.fromEntries(response.headers),
|
|
668
|
+
config
|
|
669
|
+
};
|
|
670
|
+
} finally {
|
|
671
|
+
await release();
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
get(url, config = {}) {
|
|
675
|
+
return this.request({
|
|
676
|
+
...config,
|
|
677
|
+
method: "GET",
|
|
678
|
+
url
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
post(url, data, config = {}) {
|
|
682
|
+
return this.request({
|
|
683
|
+
...config,
|
|
684
|
+
data,
|
|
685
|
+
method: "POST",
|
|
686
|
+
url
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
put(url, data, config = {}) {
|
|
690
|
+
return this.request({
|
|
691
|
+
...config,
|
|
692
|
+
data,
|
|
693
|
+
method: "PUT",
|
|
694
|
+
url
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
patch(url, data, config = {}) {
|
|
698
|
+
return this.request({
|
|
699
|
+
...config,
|
|
700
|
+
data,
|
|
701
|
+
method: "PATCH",
|
|
702
|
+
url
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
delete(url, config = {}) {
|
|
706
|
+
return this.request({
|
|
707
|
+
...config,
|
|
708
|
+
method: "DELETE",
|
|
709
|
+
url
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
};
|
|
713
|
+
function resolveMSTeamsPrivateQaRuntime(env = process.env, bootstrap = globalThis[PRIVATE_QA_RUNTIME_SYMBOL]) {
|
|
714
|
+
if (!bootstrap) return;
|
|
715
|
+
if (env[PRIVATE_QA_BUILD_ENV] !== "1") throw new Error("Microsoft Teams private QA runtime requires OPENCLAW_BUILD_PRIVATE_QA=1");
|
|
716
|
+
const connectorUrl = bootstrap.connectorUrl?.trim();
|
|
717
|
+
const nonce = bootstrap.nonce?.trim();
|
|
718
|
+
const botToken = bootstrap.botToken?.trim();
|
|
719
|
+
if (!connectorUrl || !nonce || !botToken) throw new Error("Microsoft Teams private QA bootstrap requires connector URL, nonce, and bot token");
|
|
720
|
+
const parsedConnectorUrl = new URL(connectorUrl);
|
|
721
|
+
if (parsedConnectorUrl.protocol !== "http:" || parsedConnectorUrl.hostname !== "127.0.0.1" && parsedConnectorUrl.hostname !== "localhost") throw new Error("Microsoft Teams private QA connector must use loopback HTTP");
|
|
722
|
+
return {
|
|
723
|
+
client: new PrivateQaHttpClient(parsedConnectorUrl.toString(), nonce),
|
|
724
|
+
listenHost: "127.0.0.1",
|
|
725
|
+
skipAuth: true,
|
|
726
|
+
token: async () => botToken
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
//#endregion
|
|
659
730
|
//#region extensions/msteams/src/user-agent.ts
|
|
660
731
|
let cachedUserAgent;
|
|
661
732
|
function resolveTeamsSdkVersion() {
|
|
@@ -733,20 +804,29 @@ async function createMSTeamsExpressAdapter(serverOrApp) {
|
|
|
733
804
|
*/
|
|
734
805
|
async function createMSTeamsApp(creds, options) {
|
|
735
806
|
const { App, cloudFromName } = await loadSdkModules();
|
|
807
|
+
const privateQaRuntime = resolveMSTeamsPrivateQaRuntime();
|
|
736
808
|
const cloud = options?.cloud ?? "Public";
|
|
737
809
|
const serviceUrl = options?.serviceUrl ? normalizeBotFrameworkServiceUrl(options.serviceUrl) : void 0;
|
|
738
810
|
const appOptions = {
|
|
739
|
-
client: options?.httpClient ?? {
|
|
811
|
+
client: privateQaRuntime?.client ?? options?.httpClient ?? {
|
|
740
812
|
headers: { "User-Agent": buildOpenClawUserAgentFragment() },
|
|
741
813
|
timeout: 3e4
|
|
742
814
|
},
|
|
815
|
+
...privateQaRuntime ? {
|
|
816
|
+
clientSecret: "",
|
|
817
|
+
skipAuth: privateQaRuntime.skipAuth,
|
|
818
|
+
token: privateQaRuntime.token
|
|
819
|
+
} : {},
|
|
743
820
|
...options?.httpServerAdapter ? { httpServerAdapter: options.httpServerAdapter } : {},
|
|
744
821
|
...options?.messagingEndpoint ? { messagingEndpoint: options.messagingEndpoint } : {},
|
|
745
822
|
cloud: cloudFromName(cloud),
|
|
746
823
|
...serviceUrl ? { serviceUrl } : {},
|
|
747
824
|
...options?.oauthDefaultConnectionName ? { oauth: { defaultConnectionName: options.oauthDefaultConnectionName } } : {}
|
|
748
825
|
};
|
|
749
|
-
if (creds.type === "federated") return await createFederatedApp(creds, App,
|
|
826
|
+
if (creds.type === "federated") return await createFederatedApp(creds, App, {
|
|
827
|
+
clientSecret: "",
|
|
828
|
+
...appOptions
|
|
829
|
+
});
|
|
750
830
|
return new App({
|
|
751
831
|
clientId: creds.appId,
|
|
752
832
|
clientSecret: creds.appPassword,
|
|
@@ -765,9 +845,8 @@ async function createFederatedApp(creds, App, appOptions) {
|
|
|
765
845
|
let privateKey;
|
|
766
846
|
try {
|
|
767
847
|
privateKey = await (0, openclaw_plugin_sdk_secret_file.readSecretFile)(creds.certificatePath, "Microsoft Teams certificate");
|
|
768
|
-
} catch
|
|
769
|
-
|
|
770
|
-
throw new Error(`Failed to read certificate file at '${creds.certificatePath}': ${msg}`, { cause: err });
|
|
848
|
+
} catch {
|
|
849
|
+
throw new Error("Failed to read certificate file: the configured credential is unavailable.");
|
|
771
850
|
}
|
|
772
851
|
return createCertificateApp(creds, privateKey, App, appOptions);
|
|
773
852
|
}
|
|
@@ -854,6 +933,10 @@ function createMSTeamsTokenBody(params) {
|
|
|
854
933
|
function resolveMSTeamsTokenExpiresAt(value) {
|
|
855
934
|
return (0, openclaw_plugin_sdk_number_runtime.resolveExpiresAtMsFromDurationSeconds)(value, { bufferMs: EXPIRY_BUFFER_MS });
|
|
856
935
|
}
|
|
936
|
+
function assertMSTeamsTokenResponseObject(data, failureLabel) {
|
|
937
|
+
if (!(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(data)) throw new Error(`MSTeams ${failureLabel} failed: invalid token response fields`);
|
|
938
|
+
return data;
|
|
939
|
+
}
|
|
857
940
|
function parseMSTeamsTokenResponse(data, failureLabel) {
|
|
858
941
|
const expiresAt = resolveMSTeamsTokenExpiresAt(data.expires_in);
|
|
859
942
|
if (typeof data.access_token !== "string" || !data.access_token || expiresAt === void 0 || data.refresh_token !== void 0 && typeof data.refresh_token !== "string" || data.scope !== void 0 && typeof data.scope !== "string") throw new Error(`MSTeams ${failureLabel} failed: invalid token response fields`);
|
|
@@ -880,7 +963,7 @@ async function fetchMSTeamsTokens(params) {
|
|
|
880
963
|
});
|
|
881
964
|
try {
|
|
882
965
|
if (!response.ok) throw await createMSTeamsHttpError(response, `MSTeams ${params.failureLabel} failed`);
|
|
883
|
-
return parseMSTeamsTokenResponse(await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(response, `MSTeams ${params.failureLabel} failed`), params.failureLabel);
|
|
966
|
+
return parseMSTeamsTokenResponse(assertMSTeamsTokenResponseObject(await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(response, `MSTeams ${params.failureLabel} failed`), params.failureLabel), params.failureLabel);
|
|
884
967
|
} finally {
|
|
885
968
|
await release();
|
|
886
969
|
}
|
|
@@ -1050,21 +1133,30 @@ async function requestGraph(params) {
|
|
|
1050
1133
|
try {
|
|
1051
1134
|
if (!response.ok) throw await createMSTeamsHttpError(response, `${params.errorPrefix ?? "Graph"} ${params.path} failed`);
|
|
1052
1135
|
releaseInFinally = false;
|
|
1053
|
-
return responseWithRelease(response, release);
|
|
1136
|
+
return (0, openclaw_plugin_sdk_fetch_runtime.responseWithRelease)(response, release);
|
|
1054
1137
|
} finally {
|
|
1055
1138
|
if (releaseInFinally) await release();
|
|
1056
1139
|
}
|
|
1057
1140
|
}
|
|
1058
1141
|
async function readOptionalGraphJson(res, label) {
|
|
1059
|
-
if (res.status === 204 || res.headers
|
|
1142
|
+
if (res.status === 204 || res.headers.get("content-length") === "0") return;
|
|
1060
1143
|
return await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(res, label);
|
|
1061
1144
|
}
|
|
1062
|
-
async function
|
|
1063
|
-
|
|
1145
|
+
async function mutateGraphJson(params) {
|
|
1146
|
+
const errorPrefix = `Graph${params.beta ? " beta" : ""} ${params.method}`;
|
|
1147
|
+
return readOptionalGraphJson(await requestGraph({
|
|
1064
1148
|
token: params.token,
|
|
1065
1149
|
path: params.path,
|
|
1066
1150
|
method: params.method,
|
|
1067
1151
|
body: params.body,
|
|
1152
|
+
root: params.beta ? GRAPH_BETA : void 0,
|
|
1153
|
+
errorPrefix
|
|
1154
|
+
}), `${errorPrefix} ${params.path} failed`);
|
|
1155
|
+
}
|
|
1156
|
+
async function fetchGraphJson(params) {
|
|
1157
|
+
return await readOptionalGraphJson(await requestGraph({
|
|
1158
|
+
token: params.token,
|
|
1159
|
+
path: params.path,
|
|
1068
1160
|
headers: params.headers,
|
|
1069
1161
|
deadline: params.deadline
|
|
1070
1162
|
}), `Graph ${params.path} failed`);
|
|
@@ -1159,41 +1251,13 @@ async function listTeamsByNameWithPageInfo(token, query) {
|
|
|
1159
1251
|
path: `/groups?$filter=${encodeURIComponent(filter)}&$select=id,displayName`
|
|
1160
1252
|
});
|
|
1161
1253
|
}
|
|
1162
|
-
async function postGraphJson(params) {
|
|
1163
|
-
return readOptionalGraphJson(await requestGraph({
|
|
1164
|
-
token: params.token,
|
|
1165
|
-
path: params.path,
|
|
1166
|
-
method: "POST",
|
|
1167
|
-
body: params.body,
|
|
1168
|
-
errorPrefix: "Graph POST"
|
|
1169
|
-
}), `Graph POST ${params.path} failed`);
|
|
1170
|
-
}
|
|
1171
|
-
async function postGraphBetaJson(params) {
|
|
1172
|
-
return readOptionalGraphJson(await requestGraph({
|
|
1173
|
-
token: params.token,
|
|
1174
|
-
path: params.path,
|
|
1175
|
-
method: "POST",
|
|
1176
|
-
root: GRAPH_BETA,
|
|
1177
|
-
body: params.body,
|
|
1178
|
-
errorPrefix: "Graph beta POST"
|
|
1179
|
-
}), `Graph beta POST ${params.path} failed`);
|
|
1180
|
-
}
|
|
1181
1254
|
async function deleteGraphRequest(params) {
|
|
1182
|
-
await requestGraph({
|
|
1255
|
+
await (await requestGraph({
|
|
1183
1256
|
token: params.token,
|
|
1184
1257
|
path: params.path,
|
|
1185
1258
|
method: "DELETE",
|
|
1186
1259
|
errorPrefix: "Graph DELETE"
|
|
1187
|
-
});
|
|
1188
|
-
}
|
|
1189
|
-
async function patchGraphJson(params) {
|
|
1190
|
-
return readOptionalGraphJson(await requestGraph({
|
|
1191
|
-
token: params.token,
|
|
1192
|
-
path: params.path,
|
|
1193
|
-
method: "PATCH",
|
|
1194
|
-
body: params.body,
|
|
1195
|
-
errorPrefix: "Graph PATCH"
|
|
1196
|
-
}), `Graph PATCH ${params.path} failed`);
|
|
1260
|
+
})).body?.cancel().catch(() => void 0);
|
|
1197
1261
|
}
|
|
1198
1262
|
async function listChannelsForTeam(token, teamId) {
|
|
1199
1263
|
return (await listChannelsForTeamWithPageInfo(token, teamId)).items;
|
|
@@ -1930,6 +1994,12 @@ Object.defineProperty(exports, "isLikelyImageAttachment", {
|
|
|
1930
1994
|
return isLikelyImageAttachment;
|
|
1931
1995
|
}
|
|
1932
1996
|
});
|
|
1997
|
+
Object.defineProperty(exports, "isRedirectStatus", {
|
|
1998
|
+
enumerable: true,
|
|
1999
|
+
get: function() {
|
|
2000
|
+
return isRedirectStatus;
|
|
2001
|
+
}
|
|
2002
|
+
});
|
|
1933
2003
|
Object.defineProperty(exports, "isUrlAllowed", {
|
|
1934
2004
|
enumerable: true,
|
|
1935
2005
|
get: function() {
|
|
@@ -1978,6 +2048,12 @@ Object.defineProperty(exports, "looksLikeMSTeamsTargetId", {
|
|
|
1978
2048
|
return looksLikeMSTeamsTargetId;
|
|
1979
2049
|
}
|
|
1980
2050
|
});
|
|
2051
|
+
Object.defineProperty(exports, "mutateGraphJson", {
|
|
2052
|
+
enumerable: true,
|
|
2053
|
+
get: function() {
|
|
2054
|
+
return mutateGraphJson;
|
|
2055
|
+
}
|
|
2056
|
+
});
|
|
1981
2057
|
Object.defineProperty(exports, "normalizeBotFrameworkServiceUrl", {
|
|
1982
2058
|
enumerable: true,
|
|
1983
2059
|
get: function() {
|
|
@@ -2038,24 +2114,6 @@ Object.defineProperty(exports, "parseMSTeamsTeamEntry", {
|
|
|
2038
2114
|
return parseMSTeamsTeamEntry;
|
|
2039
2115
|
}
|
|
2040
2116
|
});
|
|
2041
|
-
Object.defineProperty(exports, "patchGraphJson", {
|
|
2042
|
-
enumerable: true,
|
|
2043
|
-
get: function() {
|
|
2044
|
-
return patchGraphJson;
|
|
2045
|
-
}
|
|
2046
|
-
});
|
|
2047
|
-
Object.defineProperty(exports, "postGraphBetaJson", {
|
|
2048
|
-
enumerable: true,
|
|
2049
|
-
get: function() {
|
|
2050
|
-
return postGraphBetaJson;
|
|
2051
|
-
}
|
|
2052
|
-
});
|
|
2053
|
-
Object.defineProperty(exports, "postGraphJson", {
|
|
2054
|
-
enumerable: true,
|
|
2055
|
-
get: function() {
|
|
2056
|
-
return postGraphJson;
|
|
2057
|
-
}
|
|
2058
|
-
});
|
|
2059
2117
|
Object.defineProperty(exports, "projectStableMSTeamsGroupAllowlist", {
|
|
2060
2118
|
enumerable: true,
|
|
2061
2119
|
get: function() {
|
|
@@ -2110,6 +2168,12 @@ Object.defineProperty(exports, "resolveMSTeamsMediaKind", {
|
|
|
2110
2168
|
return resolveMSTeamsMediaKind;
|
|
2111
2169
|
}
|
|
2112
2170
|
});
|
|
2171
|
+
Object.defineProperty(exports, "resolveMSTeamsPrivateQaRuntime", {
|
|
2172
|
+
enumerable: true,
|
|
2173
|
+
get: function() {
|
|
2174
|
+
return resolveMSTeamsPrivateQaRuntime;
|
|
2175
|
+
}
|
|
2176
|
+
});
|
|
2113
2177
|
Object.defineProperty(exports, "resolveMSTeamsRequestTimeoutMs", {
|
|
2114
2178
|
enumerable: true,
|
|
2115
2179
|
get: function() {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
//#endregion
|
|
23
|
+
Object.defineProperty(exports, "__toESM", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: function() {
|
|
26
|
+
return __toESM;
|
|
27
|
+
}
|
|
28
|
+
});
|
package/dist/runtime-api.cjs
CHANGED
|
@@ -3,8 +3,8 @@ 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");
|
|
@@ -1,37 +1,13 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
let openclaw_plugin_sdk_channel_secret_basic_runtime = require("openclaw/plugin-sdk/channel-secret-basic-runtime");
|
|
3
2
|
//#region extensions/msteams/src/secret-contract.ts
|
|
4
|
-
const
|
|
3
|
+
const channelSecrets = (0, require("openclaw/plugin-sdk/channel-secret-basic-runtime").createSimpleChannelSecretContract)({
|
|
5
4
|
channelKey: "msteams",
|
|
6
|
-
|
|
5
|
+
label: "Microsoft Teams",
|
|
6
|
+
accountFields: [],
|
|
7
|
+
channelFields: ["appPassword"],
|
|
8
|
+
mode: "channel-only"
|
|
7
9
|
});
|
|
8
|
-
|
|
9
|
-
const msteams = (0, openclaw_plugin_sdk_channel_secret_basic_runtime.getChannelRecord)(params.config, "msteams");
|
|
10
|
-
if (!msteams) return;
|
|
11
|
-
(0, openclaw_plugin_sdk_channel_secret_basic_runtime.collectSecretInputAssignment)({
|
|
12
|
-
value: msteams.appPassword,
|
|
13
|
-
path: "channels.msteams.appPassword",
|
|
14
|
-
expected: "string",
|
|
15
|
-
defaults: params.defaults,
|
|
16
|
-
context: params.context,
|
|
17
|
-
active: msteams.enabled !== false,
|
|
18
|
-
inactiveReason: "Microsoft Teams channel is disabled.",
|
|
19
|
-
owner: {
|
|
20
|
-
ownerKind: "account",
|
|
21
|
-
ownerId: "msteams:default",
|
|
22
|
-
requiredForGateway: false,
|
|
23
|
-
disposition: "isolate",
|
|
24
|
-
contract: msteams
|
|
25
|
-
},
|
|
26
|
-
apply: (value) => {
|
|
27
|
-
msteams.appPassword = value;
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
const channelSecrets = {
|
|
32
|
-
secretTargetRegistryEntries,
|
|
33
|
-
collectRuntimeConfigAssignments
|
|
34
|
-
};
|
|
10
|
+
const { secretTargetRegistryEntries, collectRuntimeConfigAssignments } = channelSecrets;
|
|
35
11
|
//#endregion
|
|
36
12
|
exports.channelSecrets = channelSecrets;
|
|
37
13
|
exports.collectRuntimeConfigAssignments = collectRuntimeConfigAssignments;
|