@openclaw/msteams 2026.10.5-beta.4 → 2026.10.10-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/.setup/{adapter.runtime-JoPydWqP.cjs → adapter.runtime-B-6Q3nMI.cjs} +6 -4
- package/dist/.setup/{approval-handler.runtime-bUN9icMr.cjs → approval-handler.runtime-DccVf5AY.cjs} +16 -6
- package/dist/.setup/{bot-framework-service-url-CPp4d-Q6.cjs → bot-framework-service-url-B3FWn2SV.cjs} +13 -0
- package/dist/.setup/{channel-Cifn9fsv.cjs → channel-B7Gy3QUW.cjs} +261 -175
- package/dist/.setup/{channel.runtime-DWRAolil.cjs → channel.runtime-DzKeQAqd.cjs} +84 -49
- package/dist/.setup/channel.setup-B5ClEcNI.cjs +990 -0
- package/dist/.setup/config-schema-CkKdphSp.cjs +293 -0
- package/dist/.setup/{conversation-store-state-DprmOfl7.cjs → conversation-store-state-C3__T9mK.cjs} +79 -91
- package/dist/.setup/delegated-state-Bv5cWuec.cjs +110 -0
- package/dist/.setup/{monitor-C9x_CJhY.cjs → monitor-CzRI-Hsc.cjs} +283 -240
- package/dist/.setup/{oauth-CWJ85AMw.cjs → oauth-D9u8sPCD.cjs} +1 -1
- package/dist/.setup/{reaction-types-Ig9sQJuR.cjs → reaction-types-DSQWVA4Z.cjs} +15 -9
- package/dist/.setup/{resolve-allowlist-DdDBVCzl.cjs → resolve-allowlist-tYgAHx0t.cjs} +252 -38
- package/dist/.setup/{secret-contract-api-ChQdBeU1.cjs → secret-contract-api-YY3v6MP8.cjs} +1 -1
- package/dist/.setup/secret-contract-api-wAyY5UHv.cjs +85 -0
- package/dist/.setup/{send-rJpcVtRp.cjs → send-Bgm8RYUa.cjs} +45 -24
- package/dist/.setup/{setup-plugin-api-DfoVOqMJ.cjs → setup-plugin-api-BACfeF7_.cjs} +1 -1
- package/dist/.setup/{thread-session-B74FC1Id.cjs → thread-session-C7KTMwLU.cjs} +11 -4
- package/dist/.setup/token-config-bEpua_Q7.cjs +93 -0
- package/dist/api.cjs +2 -2
- package/dist/channel-config-api.cjs +1 -1
- package/dist/channel-plugin-api.cjs +1 -1
- package/dist/directory-contract-api.cjs +30 -22
- package/dist/doctor-contract-api.cjs +11 -10
- package/dist/qa-runner-api.cjs +1 -1
- package/dist/runtime-api.cjs +2 -2
- package/dist/secret-contract-api.cjs +1 -1
- package/dist/setup-entry.cjs +2 -2
- package/dist/setup-plugin-api.cjs +1 -1
- package/openclaw.plugin.json +715 -0
- package/package.json +57 -6
- package/dist/.setup/channel.setup-BjbHugkL.cjs +0 -632
- package/dist/.setup/config-schema-Dk0mRIam.cjs +0 -160
- package/dist/.setup/secret-contract-api-ipiUsANg.cjs +0 -28
- package/dist/.setup/token-config-CqIh8z7Q.cjs +0 -138
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
1
|
+
const require_resolve_allowlist = require("./resolve-allowlist-tYgAHx0t.cjs");
|
|
2
2
|
let openclaw_plugin_sdk_provider_auth = require("openclaw/plugin-sdk/provider-auth");
|
|
3
3
|
let openclaw_plugin_sdk_provider_auth_runtime = require("openclaw/plugin-sdk/provider-auth-runtime");
|
|
4
4
|
//#region extensions/msteams/src/oauth.flow.ts
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
1
|
+
const require_resolve_allowlist = require("./resolve-allowlist-tYgAHx0t.cjs");
|
|
2
2
|
//#region extensions/msteams/src/graph-thread.ts
|
|
3
|
+
/** Keep inbound thread enrichment bounded while still reaching recent replies. */
|
|
4
|
+
const MAX_REPLY_PAGES = 50;
|
|
5
|
+
function compareThreadMessagesChronologically(a, b) {
|
|
6
|
+
return Date.parse(a.createdDateTime ?? "") - Date.parse(b.createdDateTime ?? "") || (a.id ?? "").localeCompare(b.id ?? "");
|
|
7
|
+
}
|
|
3
8
|
/**
|
|
4
9
|
* Strip HTML tags from Teams message content, preserving @mention display names.
|
|
5
10
|
* Teams wraps mentions in <at>Name</at> tags.
|
|
@@ -50,20 +55,21 @@ async function fetchChatMessageText(token, chatId, messageId, deadline) {
|
|
|
50
55
|
/**
|
|
51
56
|
* Fetch thread replies for a channel message, ordered chronologically.
|
|
52
57
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* Combined with the `$top` cap of 50, this means only the **oldest 50 replies** are
|
|
56
|
-
* returned for long threads — newer replies are silently omitted. There is currently no
|
|
57
|
-
* Graph API workaround for this; pagination via `@odata.nextLink` can retrieve more
|
|
58
|
-
* replies but still in ascending order only.
|
|
58
|
+
* Graph caps each replies page at 50 and does not support `$orderby`. Follow
|
|
59
|
+
* `@odata.nextLink`, then return the newest bounded window in chronological order.
|
|
59
60
|
*/
|
|
60
61
|
async function fetchThreadReplies(token, groupId, channelId, messageId, deadline) {
|
|
61
62
|
const path = `/teams/${encodeURIComponent(groupId)}/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}/replies?$top=50`;
|
|
62
|
-
|
|
63
|
+
const { items, truncated } = await require_resolve_allowlist.fetchAllGraphPages({
|
|
63
64
|
token,
|
|
64
65
|
path,
|
|
66
|
+
maxPages: MAX_REPLY_PAGES,
|
|
65
67
|
...deadline ? { deadline } : {}
|
|
66
|
-
})
|
|
68
|
+
});
|
|
69
|
+
if (truncated) throw new Error("MS Teams thread replies pagination did not reach the newest replies");
|
|
70
|
+
if (items.length <= 50) return items;
|
|
71
|
+
if (!items.every((item) => Number.isFinite(Date.parse(item.createdDateTime ?? "")))) throw new Error("MS Teams thread replies have incomplete timestamps");
|
|
72
|
+
return items.toSorted(compareThreadMessagesChronologically).slice(-50);
|
|
67
73
|
}
|
|
68
74
|
function buildThreadContext(messages, currentMessageId) {
|
|
69
75
|
const context = [];
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
const require_bot_framework_service_url = require("./bot-framework-service-url-B3FWn2SV.cjs");
|
|
2
|
+
const require_token_config = require("./token-config-bEpua_Q7.cjs");
|
|
1
3
|
const require_runtime = require("./runtime-gZTAuFux.cjs");
|
|
2
4
|
require("../runtime-api.cjs");
|
|
3
|
-
const
|
|
4
|
-
const require_token_config = require("./token-config-CqIh8z7Q.cjs");
|
|
5
|
+
const require_delegated_state = require("./delegated-state-Bv5cWuec.cjs");
|
|
5
6
|
let openclaw_plugin_sdk_lazy_runtime = require("openclaw/plugin-sdk/lazy-runtime");
|
|
6
7
|
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
8
|
+
let openclaw_plugin_sdk_account_helpers = require("openclaw/plugin-sdk/account-helpers");
|
|
9
|
+
let openclaw_plugin_sdk_account_id = require("openclaw/plugin-sdk/account-id");
|
|
10
|
+
let openclaw_plugin_sdk_secret_file_runtime = require("openclaw/plugin-sdk/secret-file-runtime");
|
|
7
11
|
let openclaw_plugin_sdk_allow_from = require("openclaw/plugin-sdk/allow-from");
|
|
8
12
|
let node_async_hooks = require("node:async_hooks");
|
|
9
13
|
let openclaw_plugin_sdk_fetch_runtime = require("openclaw/plugin-sdk/fetch-runtime");
|
|
@@ -18,21 +22,177 @@ let openclaw_plugin_sdk_secret_file = require("openclaw/plugin-sdk/secret-file")
|
|
|
18
22
|
let openclaw_plugin_sdk_error_runtime = require("openclaw/plugin-sdk/error-runtime");
|
|
19
23
|
let node_module = require("node:module");
|
|
20
24
|
let openclaw_plugin_sdk_html_entity_runtime = require("openclaw/plugin-sdk/html-entity-runtime");
|
|
25
|
+
//#region extensions/msteams/src/accounts.ts
|
|
26
|
+
const { listAccountIds, resolveDefaultAccountId } = (0, openclaw_plugin_sdk_account_helpers.createAccountListHelpers)("msteams", {
|
|
27
|
+
normalizeAccountId: openclaw_plugin_sdk_account_id.normalizeAccountId,
|
|
28
|
+
hasImplicitDefaultAccount: (cfg) => require_token_config.hasConfiguredMSTeamsCredentials(cfg.channels?.msteams)
|
|
29
|
+
});
|
|
30
|
+
const listMSTeamsAccountIds = listAccountIds;
|
|
31
|
+
const resolveDefaultMSTeamsAccountId = resolveDefaultAccountId;
|
|
32
|
+
function withAccountScopedMSTeamsConfig(params) {
|
|
33
|
+
return {
|
|
34
|
+
...params.cfg,
|
|
35
|
+
channels: {
|
|
36
|
+
...params.cfg.channels,
|
|
37
|
+
msteams: params.accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID ? params.accountConfig : {
|
|
38
|
+
...params.accountConfig,
|
|
39
|
+
defaultAccount: params.accountId
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function accountDefinesIdentity(account) {
|
|
45
|
+
return Boolean(account?.appId || account?.appPassword);
|
|
46
|
+
}
|
|
47
|
+
function resolveMSTeamsAccountEntry(accounts, accountId) {
|
|
48
|
+
const key = resolveMSTeamsAccountEntryKey(accounts, accountId);
|
|
49
|
+
return key ? accounts?.[key] : void 0;
|
|
50
|
+
}
|
|
51
|
+
function resolveMSTeamsAccountEntryKey(accounts, accountId) {
|
|
52
|
+
if (!accounts) return;
|
|
53
|
+
for (const key of Object.keys(accounts)) if ((0, openclaw_plugin_sdk_account_id.normalizeAccountId)(key) === accountId) return key;
|
|
54
|
+
}
|
|
55
|
+
function resolveMSTeamsAccountConfigPath(cfg, accountId) {
|
|
56
|
+
const normalized = (0, openclaw_plugin_sdk_account_id.normalizeAccountId)(accountId);
|
|
57
|
+
const rawAccountKey = resolveMSTeamsAccountEntryKey(cfg.channels?.msteams?.accounts, normalized);
|
|
58
|
+
if (rawAccountKey) return `channels.msteams.accounts.${rawAccountKey}`;
|
|
59
|
+
return normalized === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID ? "channels.msteams" : `channels.msteams.accounts.${normalized}`;
|
|
60
|
+
}
|
|
61
|
+
function isAccountScopedChannelConfig(channelConfig, accountId) {
|
|
62
|
+
if (!channelConfig) return false;
|
|
63
|
+
const accounts = channelConfig.accounts;
|
|
64
|
+
return (0, openclaw_plugin_sdk_account_id.normalizeAccountId)(channelConfig.defaultAccount) === accountId && (!accounts || Object.keys(accounts).length === 0) && accountDefinesIdentity(channelConfig);
|
|
65
|
+
}
|
|
66
|
+
function clearNamedAccountInheritedIdentity(merged, account) {
|
|
67
|
+
const next = { ...merged };
|
|
68
|
+
if (account?.appId === void 0) delete next.appId;
|
|
69
|
+
if (account?.appPassword === void 0) delete next.appPassword;
|
|
70
|
+
if (account?.legacyWebhook === void 0) delete next.legacyWebhook;
|
|
71
|
+
return next;
|
|
72
|
+
}
|
|
73
|
+
function resolveMSTeamsAccountConfig(cfg, accountId) {
|
|
74
|
+
const resolvedAccountId = (0, openclaw_plugin_sdk_account_id.normalizeAccountId)(accountId ?? resolveDefaultMSTeamsAccountId(cfg));
|
|
75
|
+
const channelConfig = cfg.channels?.msteams;
|
|
76
|
+
const account = resolveMSTeamsAccountEntry(channelConfig?.accounts, resolvedAccountId);
|
|
77
|
+
const merged = (0, openclaw_plugin_sdk_account_helpers.resolveMergedAccountConfig)({
|
|
78
|
+
channelConfig,
|
|
79
|
+
accounts: channelConfig?.accounts,
|
|
80
|
+
accountId: resolvedAccountId,
|
|
81
|
+
normalizeAccountId: openclaw_plugin_sdk_account_id.normalizeAccountId,
|
|
82
|
+
omitKeys: ["defaultAccount"],
|
|
83
|
+
nestedObjectKeys: [
|
|
84
|
+
"webhook",
|
|
85
|
+
"markdown",
|
|
86
|
+
"streaming",
|
|
87
|
+
"blockStreamingCoalesce",
|
|
88
|
+
"dms",
|
|
89
|
+
"teams",
|
|
90
|
+
"heartbeat",
|
|
91
|
+
"healthMonitor",
|
|
92
|
+
"delegatedAuth",
|
|
93
|
+
"sso"
|
|
94
|
+
]
|
|
95
|
+
});
|
|
96
|
+
if (resolvedAccountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID || !account && isAccountScopedChannelConfig(channelConfig, resolvedAccountId)) return merged;
|
|
97
|
+
const config = clearNamedAccountInheritedIdentity(merged, account);
|
|
98
|
+
return {
|
|
99
|
+
...config,
|
|
100
|
+
webhook: {
|
|
101
|
+
...config.webhook,
|
|
102
|
+
path: require_bot_framework_service_url.resolveMSTeamsWebhookPath(channelConfig, resolvedAccountId, account)
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function resolveMSTeamsRuntimeAccount(params) {
|
|
107
|
+
const accountId = (0, openclaw_plugin_sdk_account_id.normalizeAccountId)(params.accountId ?? resolveDefaultMSTeamsAccountId(params.cfg));
|
|
108
|
+
const config = params.msteamsCfg ?? resolveMSTeamsAccountConfig(params.cfg, accountId);
|
|
109
|
+
return {
|
|
110
|
+
accountId,
|
|
111
|
+
config,
|
|
112
|
+
credentials: require_token_config.resolveMSTeamsCredentials(config, {
|
|
113
|
+
allowEnvFallback: accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID,
|
|
114
|
+
pathPrefix: resolveMSTeamsAccountConfigPath(params.cfg, accountId)
|
|
115
|
+
})
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function resolveMSTeamsAccountWithMode(params) {
|
|
119
|
+
const accountId = (0, openclaw_plugin_sdk_account_id.normalizeAccountId)(params.accountId ?? resolveDefaultMSTeamsAccountId(params.cfg));
|
|
120
|
+
const channelEnabled = params.cfg.channels?.msteams?.enabled !== false;
|
|
121
|
+
const config = resolveMSTeamsAccountConfig(params.cfg, accountId);
|
|
122
|
+
const accountEnabled = config.enabled !== false;
|
|
123
|
+
const pathPrefix = resolveMSTeamsAccountConfigPath(params.cfg, accountId);
|
|
124
|
+
const credentialResolution = params.mode === "inspect" ? require_token_config.inspectMSTeamsCredentials(config, { allowEnvFallback: accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID }) : (() => {
|
|
125
|
+
const credentials = require_token_config.resolveMSTeamsCredentials(config, {
|
|
126
|
+
allowEnvFallback: accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID,
|
|
127
|
+
pathPrefix
|
|
128
|
+
});
|
|
129
|
+
return {
|
|
130
|
+
credentials,
|
|
131
|
+
status: credentials ? "available" : "missing"
|
|
132
|
+
};
|
|
133
|
+
})();
|
|
134
|
+
const credentials = credentialResolution.credentials;
|
|
135
|
+
const certificatePath = credentials?.type === "federated" && !credentials.useManagedIdentity ? credentials.certificatePath : void 0;
|
|
136
|
+
const channelConfig = params.cfg.channels?.msteams;
|
|
137
|
+
const rawAccountKey = resolveMSTeamsAccountEntryKey(channelConfig?.accounts, accountId);
|
|
138
|
+
const certificateConfigPath = (rawAccountKey ? channelConfig?.accounts?.[rawAccountKey] : void 0)?.certificatePath?.trim() ? `channels.msteams.accounts.${rawAccountKey}.certificatePath` : channelConfig?.certificatePath?.trim() ? "channels.msteams.certificatePath" : "env.MSTEAMS_CERTIFICATE_PATH";
|
|
139
|
+
const certificate = certificatePath ? (0, openclaw_plugin_sdk_secret_file_runtime.tryReadSecretFileSync)(certificatePath, "Microsoft Teams certificate", void 0, { configPath: certificateConfigPath }) : void 0;
|
|
140
|
+
const unavailable = credentialResolution.status === "configured_unavailable" || certificate?.status === "configured_unavailable";
|
|
141
|
+
const credentialDiagnostics = certificate?.status === "configured_unavailable" ? [certificate.diagnostic] : void 0;
|
|
142
|
+
return {
|
|
143
|
+
accountId,
|
|
144
|
+
enabled: channelEnabled && accountEnabled,
|
|
145
|
+
configured: credentialResolution.status !== "missing",
|
|
146
|
+
tokenStatus: credentialResolution.status === "missing" ? "missing" : unavailable ? "configured_unavailable" : "available",
|
|
147
|
+
...credentialDiagnostics ? { credentialDiagnostics } : {},
|
|
148
|
+
config
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function resolveMSTeamsAccount(params) {
|
|
152
|
+
return resolveMSTeamsAccountWithMode({
|
|
153
|
+
...params,
|
|
154
|
+
mode: "runtime"
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
function inspectMSTeamsAccount(params) {
|
|
158
|
+
const account = resolveMSTeamsAccountWithMode({
|
|
159
|
+
...params,
|
|
160
|
+
mode: "inspect"
|
|
161
|
+
});
|
|
162
|
+
return {
|
|
163
|
+
accountId: account.accountId,
|
|
164
|
+
enabled: account.enabled,
|
|
165
|
+
configured: account.configured,
|
|
166
|
+
tokenStatus: account.tokenStatus,
|
|
167
|
+
...account.credentialDiagnostics ? { credentialDiagnostics: account.credentialDiagnostics } : {},
|
|
168
|
+
hasIdentity: account.accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID || accountDefinesIdentity(resolveMSTeamsAccountEntry(params.cfg.channels?.msteams?.accounts, account.accountId)),
|
|
169
|
+
path: account.config.webhook?.path ?? "/api/messages"
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
//#endregion
|
|
21
173
|
//#region extensions/msteams/src/request-timeout.ts
|
|
22
174
|
const MSTEAMS_REQUEST_TIMEOUT_MS = 3e4;
|
|
23
175
|
const MSTEAMS_SHAREPOINT_UPLOAD_BASE_TIMEOUT_MS = 3e5;
|
|
24
176
|
const MSTEAMS_SHAREPOINT_UPLOAD_MIN_BYTES_PER_SECOND = 262144;
|
|
25
|
-
const
|
|
26
|
-
|
|
177
|
+
const MSTEAMS_INBOUND_ENRICHMENT_TIMEOUT_MS = 1e4;
|
|
178
|
+
const MSTEAMS_INBOUND_MEDIA_TIMEOUT_MS = 12e4;
|
|
179
|
+
function createMSTeamsInboundEnrichmentDeadline() {
|
|
27
180
|
return (0, openclaw_plugin_sdk_provider_http.createProviderOperationDeadline)({
|
|
28
181
|
label: "MS Teams inbound preprocessing",
|
|
29
|
-
timeoutMs:
|
|
182
|
+
timeoutMs: MSTEAMS_INBOUND_ENRICHMENT_TIMEOUT_MS
|
|
30
183
|
});
|
|
31
184
|
}
|
|
185
|
+
function createMSTeamsInboundMediaDeadline() {
|
|
186
|
+
return (0, openclaw_plugin_sdk_provider_http.createProviderOperationDeadline)({
|
|
187
|
+
label: "MS Teams inbound media",
|
|
188
|
+
timeoutMs: MSTEAMS_INBOUND_MEDIA_TIMEOUT_MS
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/** Per-request timeout: the operation deadline's remaining budget, else the default request cap. */
|
|
32
192
|
function resolveMSTeamsRequestTimeoutMs(deadline) {
|
|
33
193
|
return deadline ? (0, openclaw_plugin_sdk_provider_http.resolveProviderOperationTimeoutMs)({
|
|
34
194
|
deadline,
|
|
35
|
-
defaultTimeoutMs:
|
|
195
|
+
defaultTimeoutMs: deadline.timeoutMs ?? 3e4
|
|
36
196
|
}) : MSTEAMS_REQUEST_TIMEOUT_MS;
|
|
37
197
|
}
|
|
38
198
|
/** Bound non-abortable SDK and credential work to the same operation deadline as fetches. */
|
|
@@ -41,7 +201,7 @@ async function withMSTeamsRequestDeadline(params) {
|
|
|
41
201
|
return await (0, openclaw_plugin_sdk_text_utility_runtime.withTimeout)(params.work(), timeoutMs, params.label);
|
|
42
202
|
}
|
|
43
203
|
function resolveMSTeamsSharePointUploadTimeoutMs(sizeInBytes) {
|
|
44
|
-
const transferBudgetMs = Math.ceil(
|
|
204
|
+
const transferBudgetMs = Math.ceil(sizeInBytes / MSTEAMS_SHAREPOINT_UPLOAD_MIN_BYTES_PER_SECOND * 1e3);
|
|
45
205
|
return (0, openclaw_plugin_sdk_number_runtime.resolveTimerTimeoutMs)(MSTEAMS_SHAREPOINT_UPLOAD_BASE_TIMEOUT_MS + transferBudgetMs, MSTEAMS_SHAREPOINT_UPLOAD_BASE_TIMEOUT_MS, 1);
|
|
46
206
|
}
|
|
47
207
|
function createMSTeamsRequestTimeoutError(label, timeoutMs) {
|
|
@@ -689,7 +849,7 @@ async function refreshMSTeamsDelegatedTokens(params) {
|
|
|
689
849
|
//#endregion
|
|
690
850
|
//#region extensions/msteams/src/token.ts
|
|
691
851
|
async function resolveDelegatedAccessToken(params) {
|
|
692
|
-
const tokens = await
|
|
852
|
+
const tokens = await require_delegated_state.loadMSTeamsDelegatedTokens(params.accountId);
|
|
693
853
|
if (!tokens) return;
|
|
694
854
|
if ((0, openclaw_plugin_sdk_number_runtime.isFutureDateTimestampMs)(tokens.expiresAt)) return tokens.accessToken;
|
|
695
855
|
try {
|
|
@@ -700,7 +860,7 @@ async function resolveDelegatedAccessToken(params) {
|
|
|
700
860
|
refreshToken: tokens.refreshToken,
|
|
701
861
|
scopes: tokens.scopes
|
|
702
862
|
});
|
|
703
|
-
await
|
|
863
|
+
await require_delegated_state.saveMSTeamsDelegatedTokens(refreshed, params.accountId);
|
|
704
864
|
return refreshed.accessToken;
|
|
705
865
|
} catch {
|
|
706
866
|
return;
|
|
@@ -733,7 +893,7 @@ async function requestGraph(params) {
|
|
|
733
893
|
const assertRequestCurrent = captureGraphRequestCurrentness(assertReadAuthority);
|
|
734
894
|
assertRequestCurrent?.();
|
|
735
895
|
const hasBody = params.body !== void 0;
|
|
736
|
-
const url = `${params.root ?? "https://graph.microsoft.com/v1.0"}${params.path}`;
|
|
896
|
+
const url = params.absoluteUrl ?? `${params.root ?? "https://graph.microsoft.com/v1.0"}${params.path}`;
|
|
737
897
|
const { response, release } = await (0, openclaw_plugin_sdk_ssrf_runtime.fetchWithSsrFGuard)({
|
|
738
898
|
url,
|
|
739
899
|
init: {
|
|
@@ -746,7 +906,7 @@ async function requestGraph(params) {
|
|
|
746
906
|
},
|
|
747
907
|
body: hasBody ? JSON.stringify(params.body) : void 0
|
|
748
908
|
},
|
|
749
|
-
auditContext: "msteams.graph",
|
|
909
|
+
auditContext: params.absoluteUrl ? "msteams.graph.absolute" : "msteams.graph",
|
|
750
910
|
timeoutMs: resolveMSTeamsRequestTimeoutMs(params.deadline),
|
|
751
911
|
beforeRequest: assertRequestCurrent
|
|
752
912
|
});
|
|
@@ -794,28 +954,15 @@ async function fetchGraphJson(params) {
|
|
|
794
954
|
*/
|
|
795
955
|
async function fetchGraphAbsoluteUrl(params) {
|
|
796
956
|
const assertReadAuthority = (0, openclaw_plugin_sdk_fetch_runtime.captureChannelReadAuthority)();
|
|
797
|
-
const assertRequestCurrent = captureGraphRequestCurrentness(assertReadAuthority);
|
|
798
|
-
assertRequestCurrent?.();
|
|
799
|
-
const { response, release } = await (0, openclaw_plugin_sdk_ssrf_runtime.fetchWithSsrFGuard)({
|
|
800
|
-
url: params.url,
|
|
801
|
-
init: { headers: {
|
|
802
|
-
"User-Agent": buildUserAgent(),
|
|
803
|
-
Authorization: `Bearer ${params.token}`
|
|
804
|
-
} },
|
|
805
|
-
auditContext: "msteams.graph.absolute",
|
|
806
|
-
timeoutMs: MSTEAMS_REQUEST_TIMEOUT_MS,
|
|
807
|
-
beforeRequest: assertRequestCurrent
|
|
808
|
-
});
|
|
809
957
|
try {
|
|
810
|
-
|
|
811
|
-
|
|
958
|
+
const response = await requestGraph({
|
|
959
|
+
token: params.token,
|
|
960
|
+
path: params.url,
|
|
961
|
+
absoluteUrl: params.url
|
|
962
|
+
});
|
|
812
963
|
return await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(response, `Graph ${params.url} failed`);
|
|
813
964
|
} finally {
|
|
814
|
-
|
|
815
|
-
await release();
|
|
816
|
-
} finally {
|
|
817
|
-
assertReadAuthority?.();
|
|
818
|
-
}
|
|
965
|
+
assertReadAuthority?.();
|
|
819
966
|
}
|
|
820
967
|
}
|
|
821
968
|
async function fetchAllGraphPages(params) {
|
|
@@ -826,7 +973,8 @@ async function fetchAllGraphPages(params) {
|
|
|
826
973
|
const res = await fetchGraphJson({
|
|
827
974
|
token: params.token,
|
|
828
975
|
path: nextPath,
|
|
829
|
-
headers: params.headers
|
|
976
|
+
headers: params.headers,
|
|
977
|
+
...params.deadline ? { deadline: params.deadline } : {}
|
|
830
978
|
});
|
|
831
979
|
const pageItems = res.value ?? [];
|
|
832
980
|
const match = params.findOne ? pageItems.find(params.findOne) : void 0;
|
|
@@ -848,15 +996,20 @@ async function fetchAllGraphPages(params) {
|
|
|
848
996
|
async function resolveGraphToken(cfg, options) {
|
|
849
997
|
const assertRequestCurrent = captureGraphRequestCurrentness((0, openclaw_plugin_sdk_fetch_runtime.captureChannelReadAuthority)());
|
|
850
998
|
assertRequestCurrent?.();
|
|
851
|
-
const
|
|
852
|
-
const creds =
|
|
999
|
+
const openClawCfg = cfg;
|
|
1000
|
+
const { accountId, config: msteamsCfg, credentials: creds } = resolveMSTeamsRuntimeAccount({
|
|
1001
|
+
cfg: openClawCfg,
|
|
1002
|
+
accountId: options?.accountId
|
|
1003
|
+
});
|
|
1004
|
+
if (openClawCfg.channels?.msteams?.enabled === false || msteamsCfg.enabled === false) throw new Error("MS Teams account disabled: " + accountId);
|
|
853
1005
|
if (!creds) throw new Error("MS Teams credentials missing");
|
|
854
1006
|
if (msteamsCfg?.cloud === "China") throw new Error("Microsoft Teams Graph operations are not supported for channels.msteams.cloud=China until Graph requests are routed through the Azure China Graph endpoint.");
|
|
855
1007
|
if (options?.preferDelegated && msteamsCfg?.delegatedAuth?.enabled && creds.type === "secret") {
|
|
856
1008
|
const delegated = await resolveDelegatedAccessToken({
|
|
857
1009
|
tenantId: creds.tenantId,
|
|
858
1010
|
clientId: creds.appId,
|
|
859
|
-
clientSecret: creds.appPassword
|
|
1011
|
+
clientSecret: creds.appPassword,
|
|
1012
|
+
accountId
|
|
860
1013
|
});
|
|
861
1014
|
assertRequestCurrent?.();
|
|
862
1015
|
if (delegated) return delegated;
|
|
@@ -1145,7 +1298,7 @@ function parseMSTeamsTeamEntry(raw) {
|
|
|
1145
1298
|
async function resolveMSTeamsChannelAllowlist(params) {
|
|
1146
1299
|
let tokenPromise;
|
|
1147
1300
|
const getToken = () => {
|
|
1148
|
-
tokenPromise ??= resolveGraphToken(params.cfg);
|
|
1301
|
+
tokenPromise ??= resolveGraphToken(params.cfg, { accountId: params.accountId });
|
|
1149
1302
|
return tokenPromise;
|
|
1150
1303
|
};
|
|
1151
1304
|
return await (0, openclaw_plugin_sdk_allow_from.mapAllowlistResolutionInputs)({
|
|
@@ -1313,6 +1466,7 @@ async function resolveMSTeamsTeamsConfig(params) {
|
|
|
1313
1466
|
};
|
|
1314
1467
|
const resolved = await resolveMSTeamsChannelAllowlist({
|
|
1315
1468
|
cfg: params.cfg,
|
|
1469
|
+
accountId: params.accountId,
|
|
1316
1470
|
entries: entries.map((entry) => entry.input),
|
|
1317
1471
|
teamIdMode: params.teamIdMode
|
|
1318
1472
|
});
|
|
@@ -1363,7 +1517,7 @@ async function resolveMSTeamsTeamsConfig(params) {
|
|
|
1363
1517
|
async function resolveMSTeamsUserAllowlist(params) {
|
|
1364
1518
|
let tokenPromise;
|
|
1365
1519
|
const getToken = () => {
|
|
1366
|
-
tokenPromise ??= resolveGraphToken(params.cfg);
|
|
1520
|
+
tokenPromise ??= resolveGraphToken(params.cfg, { accountId: params.accountId });
|
|
1367
1521
|
return tokenPromise;
|
|
1368
1522
|
};
|
|
1369
1523
|
return await (0, openclaw_plugin_sdk_allow_from.mapAllowlistResolutionInputs)({
|
|
@@ -1480,10 +1634,16 @@ Object.defineProperty(exports, "createMSTeamsExpressAdapter", {
|
|
|
1480
1634
|
return createMSTeamsExpressAdapter;
|
|
1481
1635
|
}
|
|
1482
1636
|
});
|
|
1483
|
-
Object.defineProperty(exports, "
|
|
1637
|
+
Object.defineProperty(exports, "createMSTeamsInboundEnrichmentDeadline", {
|
|
1638
|
+
enumerable: true,
|
|
1639
|
+
get: function() {
|
|
1640
|
+
return createMSTeamsInboundEnrichmentDeadline;
|
|
1641
|
+
}
|
|
1642
|
+
});
|
|
1643
|
+
Object.defineProperty(exports, "createMSTeamsInboundMediaDeadline", {
|
|
1484
1644
|
enumerable: true,
|
|
1485
1645
|
get: function() {
|
|
1486
|
-
return
|
|
1646
|
+
return createMSTeamsInboundMediaDeadline;
|
|
1487
1647
|
}
|
|
1488
1648
|
});
|
|
1489
1649
|
Object.defineProperty(exports, "createMSTeamsTokenProvider", {
|
|
@@ -1570,6 +1730,12 @@ Object.defineProperty(exports, "htmlToPlainText", {
|
|
|
1570
1730
|
return htmlToPlainText;
|
|
1571
1731
|
}
|
|
1572
1732
|
});
|
|
1733
|
+
Object.defineProperty(exports, "inspectMSTeamsAccount", {
|
|
1734
|
+
enumerable: true,
|
|
1735
|
+
get: function() {
|
|
1736
|
+
return inspectMSTeamsAccount;
|
|
1737
|
+
}
|
|
1738
|
+
});
|
|
1573
1739
|
Object.defineProperty(exports, "isAdvertisedFileAttachment", {
|
|
1574
1740
|
enumerable: true,
|
|
1575
1741
|
get: function() {
|
|
@@ -1606,6 +1772,12 @@ Object.defineProperty(exports, "listChannelsForTeamWithPageInfo", {
|
|
|
1606
1772
|
return listChannelsForTeamWithPageInfo;
|
|
1607
1773
|
}
|
|
1608
1774
|
});
|
|
1775
|
+
Object.defineProperty(exports, "listMSTeamsAccountIds", {
|
|
1776
|
+
enumerable: true,
|
|
1777
|
+
get: function() {
|
|
1778
|
+
return listMSTeamsAccountIds;
|
|
1779
|
+
}
|
|
1780
|
+
});
|
|
1609
1781
|
Object.defineProperty(exports, "listTeamsByName", {
|
|
1610
1782
|
enumerable: true,
|
|
1611
1783
|
get: function() {
|
|
@@ -1714,12 +1886,42 @@ Object.defineProperty(exports, "resolveAttachmentFetchPolicy", {
|
|
|
1714
1886
|
return resolveAttachmentFetchPolicy;
|
|
1715
1887
|
}
|
|
1716
1888
|
});
|
|
1889
|
+
Object.defineProperty(exports, "resolveDefaultMSTeamsAccountId", {
|
|
1890
|
+
enumerable: true,
|
|
1891
|
+
get: function() {
|
|
1892
|
+
return resolveDefaultMSTeamsAccountId;
|
|
1893
|
+
}
|
|
1894
|
+
});
|
|
1717
1895
|
Object.defineProperty(exports, "resolveGraphToken", {
|
|
1718
1896
|
enumerable: true,
|
|
1719
1897
|
get: function() {
|
|
1720
1898
|
return resolveGraphToken;
|
|
1721
1899
|
}
|
|
1722
1900
|
});
|
|
1901
|
+
Object.defineProperty(exports, "resolveMSTeamsAccount", {
|
|
1902
|
+
enumerable: true,
|
|
1903
|
+
get: function() {
|
|
1904
|
+
return resolveMSTeamsAccount;
|
|
1905
|
+
}
|
|
1906
|
+
});
|
|
1907
|
+
Object.defineProperty(exports, "resolveMSTeamsAccountConfig", {
|
|
1908
|
+
enumerable: true,
|
|
1909
|
+
get: function() {
|
|
1910
|
+
return resolveMSTeamsAccountConfig;
|
|
1911
|
+
}
|
|
1912
|
+
});
|
|
1913
|
+
Object.defineProperty(exports, "resolveMSTeamsAccountConfigPath", {
|
|
1914
|
+
enumerable: true,
|
|
1915
|
+
get: function() {
|
|
1916
|
+
return resolveMSTeamsAccountConfigPath;
|
|
1917
|
+
}
|
|
1918
|
+
});
|
|
1919
|
+
Object.defineProperty(exports, "resolveMSTeamsAccountEntryKey", {
|
|
1920
|
+
enumerable: true,
|
|
1921
|
+
get: function() {
|
|
1922
|
+
return resolveMSTeamsAccountEntryKey;
|
|
1923
|
+
}
|
|
1924
|
+
});
|
|
1723
1925
|
Object.defineProperty(exports, "resolveMSTeamsChannelAllowlist", {
|
|
1724
1926
|
enumerable: true,
|
|
1725
1927
|
get: function() {
|
|
@@ -1744,6 +1946,12 @@ Object.defineProperty(exports, "resolveMSTeamsRequestTimeoutMs", {
|
|
|
1744
1946
|
return resolveMSTeamsRequestTimeoutMs;
|
|
1745
1947
|
}
|
|
1746
1948
|
});
|
|
1949
|
+
Object.defineProperty(exports, "resolveMSTeamsRuntimeAccount", {
|
|
1950
|
+
enumerable: true,
|
|
1951
|
+
get: function() {
|
|
1952
|
+
return resolveMSTeamsRuntimeAccount;
|
|
1953
|
+
}
|
|
1954
|
+
});
|
|
1747
1955
|
Object.defineProperty(exports, "resolveMSTeamsSdkCloudOptions", {
|
|
1748
1956
|
enumerable: true,
|
|
1749
1957
|
get: function() {
|
|
@@ -1816,6 +2024,12 @@ Object.defineProperty(exports, "wasMSTeamsBotMentioned", {
|
|
|
1816
2024
|
return wasMSTeamsBotMentioned;
|
|
1817
2025
|
}
|
|
1818
2026
|
});
|
|
2027
|
+
Object.defineProperty(exports, "withAccountScopedMSTeamsConfig", {
|
|
2028
|
+
enumerable: true,
|
|
2029
|
+
get: function() {
|
|
2030
|
+
return withAccountScopedMSTeamsConfig;
|
|
2031
|
+
}
|
|
2032
|
+
});
|
|
1819
2033
|
Object.defineProperty(exports, "withMSTeamsAbortableRequestTimeout", {
|
|
1820
2034
|
enumerable: true,
|
|
1821
2035
|
get: function() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_secret_contract_api = require("./secret-contract-api-
|
|
1
|
+
const require_secret_contract_api = require("./secret-contract-api-wAyY5UHv.cjs");
|
|
2
2
|
exports.channelSecrets = require_secret_contract_api.channelSecrets;
|
|
3
3
|
exports.collectRuntimeConfigAssignments = require_secret_contract_api.collectRuntimeConfigAssignments;
|
|
4
4
|
exports.secretTargetRegistryEntries = require_secret_contract_api.secretTargetRegistryEntries;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
let openclaw_plugin_sdk_setup = require("openclaw/plugin-sdk/setup");
|
|
2
|
+
let openclaw_plugin_sdk_channel_secret_basic_runtime = require("openclaw/plugin-sdk/channel-secret-basic-runtime");
|
|
3
|
+
//#region extensions/msteams/src/secret-contract.ts
|
|
4
|
+
const secretTargetRegistryEntries = (0, openclaw_plugin_sdk_channel_secret_basic_runtime.createChannelSecretTargetRegistryEntries)({
|
|
5
|
+
channelKey: "msteams",
|
|
6
|
+
account: ["appPassword"],
|
|
7
|
+
channel: ["appPassword"]
|
|
8
|
+
});
|
|
9
|
+
function collectRuntimeConfigAssignments(params) {
|
|
10
|
+
const resolved = (0, openclaw_plugin_sdk_channel_secret_basic_runtime.getChannelSurface)(params.config, "msteams");
|
|
11
|
+
if (!resolved) return;
|
|
12
|
+
const { channel: msteams, surface } = resolved;
|
|
13
|
+
(0, openclaw_plugin_sdk_channel_secret_basic_runtime.collectSecretInputAssignment)({
|
|
14
|
+
value: msteams.appPassword,
|
|
15
|
+
path: "channels.msteams.appPassword",
|
|
16
|
+
expected: "string",
|
|
17
|
+
defaults: params.defaults,
|
|
18
|
+
context: params.context,
|
|
19
|
+
active: isRootDefaultIdentityActive(msteams, surface),
|
|
20
|
+
inactiveReason: "no enabled account inherits this top-level Microsoft Teams appPassword.",
|
|
21
|
+
owner: {
|
|
22
|
+
ownerKind: "account",
|
|
23
|
+
ownerId: "msteams:default",
|
|
24
|
+
requiredForGateway: false,
|
|
25
|
+
disposition: "isolate",
|
|
26
|
+
contract: msteams
|
|
27
|
+
},
|
|
28
|
+
apply: (value) => {
|
|
29
|
+
msteams.appPassword = value;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
if (!surface.hasExplicitAccounts) return;
|
|
33
|
+
for (const { accountId, account, enabled } of surface.accounts) {
|
|
34
|
+
if (!(0, openclaw_plugin_sdk_channel_secret_basic_runtime.hasOwnProperty)(account, "appPassword")) continue;
|
|
35
|
+
(0, openclaw_plugin_sdk_channel_secret_basic_runtime.collectSecretInputAssignment)({
|
|
36
|
+
value: account.appPassword,
|
|
37
|
+
path: `channels.msteams.accounts.${accountId}.appPassword`,
|
|
38
|
+
expected: "string",
|
|
39
|
+
defaults: params.defaults,
|
|
40
|
+
context: params.context,
|
|
41
|
+
active: enabled,
|
|
42
|
+
inactiveReason: "Microsoft Teams account is disabled.",
|
|
43
|
+
owner: {
|
|
44
|
+
ownerKind: "account",
|
|
45
|
+
ownerId: `msteams:${(0, openclaw_plugin_sdk_setup.normalizeAccountId)(accountId)}`,
|
|
46
|
+
requiredForGateway: false,
|
|
47
|
+
disposition: "isolate",
|
|
48
|
+
contract: account
|
|
49
|
+
},
|
|
50
|
+
apply: (value) => {
|
|
51
|
+
account.appPassword = value;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function isConfiguredIdentityField(value) {
|
|
57
|
+
if (typeof value === "string") return value.trim().length > 0;
|
|
58
|
+
return value !== void 0 && value !== null;
|
|
59
|
+
}
|
|
60
|
+
function isRootDefaultIdentityActive(channel, surface) {
|
|
61
|
+
return ((surface.hasExplicitAccounts ? surface.accounts.find(({ accountId }) => (0, openclaw_plugin_sdk_setup.normalizeAccountId)(accountId) === openclaw_plugin_sdk_setup.DEFAULT_ACCOUNT_ID) : void 0)?.enabled ?? surface.channelEnabled) && (isConfiguredIdentityField(channel.appId) || isConfiguredIdentityField(channel.appPassword));
|
|
62
|
+
}
|
|
63
|
+
const channelSecrets = {
|
|
64
|
+
secretTargetRegistryEntries,
|
|
65
|
+
collectRuntimeConfigAssignments
|
|
66
|
+
};
|
|
67
|
+
//#endregion
|
|
68
|
+
Object.defineProperty(exports, "channelSecrets", {
|
|
69
|
+
enumerable: true,
|
|
70
|
+
get: function() {
|
|
71
|
+
return channelSecrets;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
Object.defineProperty(exports, "collectRuntimeConfigAssignments", {
|
|
75
|
+
enumerable: true,
|
|
76
|
+
get: function() {
|
|
77
|
+
return collectRuntimeConfigAssignments;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
Object.defineProperty(exports, "secretTargetRegistryEntries", {
|
|
81
|
+
enumerable: true,
|
|
82
|
+
get: function() {
|
|
83
|
+
return secretTargetRegistryEntries;
|
|
84
|
+
}
|
|
85
|
+
});
|