@openclaw/msteams 2026.5.2 → 2026.5.3-beta.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.
- package/dist/api.js +3 -0
- package/dist/channel-D7hdreTh.js +984 -0
- package/dist/channel-config-api.js +2 -0
- package/dist/channel-plugin-api.js +2 -0
- package/dist/channel.runtime-BC1ruIfN.js +573 -0
- package/dist/config-schema-B8QezH6t.js +15 -0
- package/dist/contract-api.js +2 -0
- package/dist/graph-users-9uQJepqr.js +1354 -0
- package/dist/index.js +22 -0
- package/dist/oauth-BWJyilR1.js +114 -0
- package/dist/oauth.token-xxpoLWy5.js +115 -0
- package/dist/policy-DTnU2GR7.js +142 -0
- package/dist/probe-D_H8yFps.js +2194 -0
- package/dist/resolve-allowlist-D41JSziq.js +219 -0
- package/dist/runtime-api-DV1iVMn1.js +28 -0
- package/dist/runtime-api.js +2 -0
- package/dist/secret-contract-BuoEXmPS.js +35 -0
- package/dist/secret-contract-api.js +2 -0
- package/dist/setup-entry.js +15 -0
- package/dist/setup-plugin-api.js +64 -0
- package/dist/setup-surface-BLkFQYIQ.js +313 -0
- package/dist/src-CFp1QpFd.js +4064 -0
- package/dist/test-api.js +2 -0
- package/package.json +14 -6
- package/api.ts +0 -3
- package/channel-config-api.ts +0 -1
- package/channel-plugin-api.ts +0 -2
- package/config-api.ts +0 -4
- package/contract-api.ts +0 -4
- package/index.ts +0 -20
- package/runtime-api.ts +0 -73
- package/secret-contract-api.ts +0 -5
- package/setup-entry.ts +0 -13
- package/setup-plugin-api.ts +0 -3
- package/src/ai-entity.ts +0 -7
- package/src/approval-auth.ts +0 -44
- package/src/attachments/bot-framework.test.ts +0 -461
- package/src/attachments/bot-framework.ts +0 -362
- package/src/attachments/download.ts +0 -311
- package/src/attachments/graph.test.ts +0 -416
- package/src/attachments/graph.ts +0 -484
- package/src/attachments/html.ts +0 -122
- package/src/attachments/payload.ts +0 -14
- package/src/attachments/remote-media.test.ts +0 -137
- package/src/attachments/remote-media.ts +0 -112
- package/src/attachments/shared.test.ts +0 -530
- package/src/attachments/shared.ts +0 -626
- package/src/attachments/types.ts +0 -47
- package/src/attachments.graph.test.ts +0 -342
- package/src/attachments.helpers.test.ts +0 -246
- package/src/attachments.test-helpers.ts +0 -17
- package/src/attachments.test.ts +0 -687
- package/src/attachments.ts +0 -18
- package/src/block-streaming-config.test.ts +0 -61
- package/src/channel-api.ts +0 -1
- package/src/channel.actions.test.ts +0 -742
- package/src/channel.directory.test.ts +0 -200
- package/src/channel.runtime.ts +0 -56
- package/src/channel.setup.ts +0 -77
- package/src/channel.test.ts +0 -128
- package/src/channel.ts +0 -1136
- package/src/config-schema.ts +0 -6
- package/src/config-ui-hints.ts +0 -12
- package/src/conversation-store-fs.test.ts +0 -74
- package/src/conversation-store-fs.ts +0 -149
- package/src/conversation-store-helpers.test.ts +0 -202
- package/src/conversation-store-helpers.ts +0 -105
- package/src/conversation-store-memory.ts +0 -51
- package/src/conversation-store.shared.test.ts +0 -225
- package/src/conversation-store.ts +0 -71
- package/src/directory-live.test.ts +0 -156
- package/src/directory-live.ts +0 -111
- package/src/doctor.ts +0 -27
- package/src/errors.test.ts +0 -133
- package/src/errors.ts +0 -246
- package/src/feedback-reflection-prompt.ts +0 -117
- package/src/feedback-reflection-store.ts +0 -114
- package/src/feedback-reflection.test.ts +0 -237
- package/src/feedback-reflection.ts +0 -283
- package/src/file-consent-helpers.test.ts +0 -326
- package/src/file-consent-helpers.ts +0 -126
- package/src/file-consent-invoke.ts +0 -150
- package/src/file-consent.test.ts +0 -363
- package/src/file-consent.ts +0 -287
- package/src/graph-chat.ts +0 -55
- package/src/graph-group-management.test.ts +0 -318
- package/src/graph-group-management.ts +0 -168
- package/src/graph-members.test.ts +0 -89
- package/src/graph-members.ts +0 -48
- package/src/graph-messages.actions.test.ts +0 -243
- package/src/graph-messages.read.test.ts +0 -391
- package/src/graph-messages.search.test.ts +0 -213
- package/src/graph-messages.test-helpers.ts +0 -50
- package/src/graph-messages.ts +0 -534
- package/src/graph-teams.test.ts +0 -215
- package/src/graph-teams.ts +0 -114
- package/src/graph-thread.test.ts +0 -246
- package/src/graph-thread.ts +0 -146
- package/src/graph-upload.test.ts +0 -258
- package/src/graph-upload.ts +0 -531
- package/src/graph-users.ts +0 -29
- package/src/graph.test.ts +0 -516
- package/src/graph.ts +0 -293
- package/src/inbound.test.ts +0 -221
- package/src/inbound.ts +0 -148
- package/src/index.ts +0 -4
- package/src/media-helpers.test.ts +0 -202
- package/src/media-helpers.ts +0 -105
- package/src/mentions.test.ts +0 -244
- package/src/mentions.ts +0 -114
- package/src/messenger.test.ts +0 -865
- package/src/messenger.ts +0 -605
- package/src/monitor-handler/access.ts +0 -125
- package/src/monitor-handler/inbound-media.test.ts +0 -289
- package/src/monitor-handler/inbound-media.ts +0 -180
- package/src/monitor-handler/message-handler-mock-support.test-support.ts +0 -28
- package/src/monitor-handler/message-handler.authz.test.ts +0 -669
- package/src/monitor-handler/message-handler.dm-media.test.ts +0 -54
- package/src/monitor-handler/message-handler.test-support.ts +0 -100
- package/src/monitor-handler/message-handler.thread-parent.test.ts +0 -223
- package/src/monitor-handler/message-handler.thread-session.test.ts +0 -77
- package/src/monitor-handler/message-handler.ts +0 -1000
- package/src/monitor-handler/reaction-handler.test.ts +0 -267
- package/src/monitor-handler/reaction-handler.ts +0 -210
- package/src/monitor-handler/thread-session.ts +0 -17
- package/src/monitor-handler.adaptive-card.test.ts +0 -162
- package/src/monitor-handler.feedback-authz.test.ts +0 -314
- package/src/monitor-handler.file-consent.test.ts +0 -423
- package/src/monitor-handler.sso.test.ts +0 -563
- package/src/monitor-handler.test-helpers.ts +0 -180
- package/src/monitor-handler.ts +0 -534
- package/src/monitor-handler.types.ts +0 -27
- package/src/monitor-types.ts +0 -6
- package/src/monitor.lifecycle.test.ts +0 -278
- package/src/monitor.test.ts +0 -119
- package/src/monitor.ts +0 -442
- package/src/oauth.flow.ts +0 -77
- package/src/oauth.shared.ts +0 -37
- package/src/oauth.test.ts +0 -305
- package/src/oauth.token.ts +0 -158
- package/src/oauth.ts +0 -130
- package/src/outbound.test.ts +0 -130
- package/src/outbound.ts +0 -71
- package/src/pending-uploads-fs.test.ts +0 -246
- package/src/pending-uploads-fs.ts +0 -235
- package/src/pending-uploads.test.ts +0 -173
- package/src/pending-uploads.ts +0 -121
- package/src/policy.test.ts +0 -240
- package/src/policy.ts +0 -262
- package/src/polls-store-memory.ts +0 -32
- package/src/polls.test.ts +0 -160
- package/src/polls.ts +0 -323
- package/src/presentation.ts +0 -68
- package/src/probe.test.ts +0 -77
- package/src/probe.ts +0 -132
- package/src/reply-dispatcher.test.ts +0 -437
- package/src/reply-dispatcher.ts +0 -346
- package/src/reply-stream-controller.test.ts +0 -235
- package/src/reply-stream-controller.ts +0 -147
- package/src/resolve-allowlist.test.ts +0 -250
- package/src/resolve-allowlist.ts +0 -309
- package/src/revoked-context.ts +0 -17
- package/src/runtime.ts +0 -9
- package/src/sdk-types.ts +0 -59
- package/src/sdk.test.ts +0 -666
- package/src/sdk.ts +0 -884
- package/src/secret-contract.ts +0 -49
- package/src/secret-input.ts +0 -7
- package/src/send-context.ts +0 -231
- package/src/send.test.ts +0 -493
- package/src/send.ts +0 -637
- package/src/sent-message-cache.test.ts +0 -15
- package/src/sent-message-cache.ts +0 -56
- package/src/session-route.ts +0 -40
- package/src/setup-core.ts +0 -160
- package/src/setup-surface.test.ts +0 -202
- package/src/setup-surface.ts +0 -320
- package/src/sso-token-store.test.ts +0 -72
- package/src/sso-token-store.ts +0 -166
- package/src/sso.ts +0 -300
- package/src/storage.ts +0 -25
- package/src/store-fs.ts +0 -44
- package/src/streaming-message.test.ts +0 -262
- package/src/streaming-message.ts +0 -297
- package/src/test-runtime.ts +0 -16
- package/src/thread-parent-context.test.ts +0 -224
- package/src/thread-parent-context.ts +0 -159
- package/src/token-response.ts +0 -11
- package/src/token.test.ts +0 -259
- package/src/token.ts +0 -195
- package/src/user-agent.test.ts +0 -86
- package/src/user-agent.ts +0 -53
- package/src/webhook-timeouts.ts +0 -27
- package/src/welcome-card.test.ts +0 -81
- package/src/welcome-card.ts +0 -57
- package/test-api.ts +0 -1
- package/tsconfig.json +0 -16
package/src/session-route.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
buildChannelOutboundSessionRoute,
|
|
3
|
-
stripChannelTargetPrefix,
|
|
4
|
-
stripTargetKindPrefix,
|
|
5
|
-
type ChannelOutboundSessionRouteParams,
|
|
6
|
-
} from "openclaw/plugin-sdk/channel-core";
|
|
7
|
-
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
|
8
|
-
|
|
9
|
-
export function resolveMSTeamsOutboundSessionRoute(params: ChannelOutboundSessionRouteParams) {
|
|
10
|
-
let trimmed = stripChannelTargetPrefix(params.target, "msteams", "teams");
|
|
11
|
-
if (!trimmed) {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const lower = normalizeLowercaseStringOrEmpty(trimmed);
|
|
16
|
-
const isUser = lower.startsWith("user:");
|
|
17
|
-
const rawId = stripTargetKindPrefix(trimmed);
|
|
18
|
-
if (!rawId) {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
const conversationId = rawId.split(";")[0] ?? rawId;
|
|
22
|
-
const isChannel = !isUser && /@thread\.tacv2/i.test(conversationId);
|
|
23
|
-
return buildChannelOutboundSessionRoute({
|
|
24
|
-
cfg: params.cfg,
|
|
25
|
-
agentId: params.agentId,
|
|
26
|
-
channel: "msteams",
|
|
27
|
-
accountId: params.accountId,
|
|
28
|
-
peer: {
|
|
29
|
-
kind: isUser ? "direct" : isChannel ? "channel" : "group",
|
|
30
|
-
id: conversationId,
|
|
31
|
-
},
|
|
32
|
-
chatType: isUser ? "direct" : isChannel ? "channel" : "group",
|
|
33
|
-
from: isUser
|
|
34
|
-
? `msteams:${conversationId}`
|
|
35
|
-
: isChannel
|
|
36
|
-
? `msteams:channel:${conversationId}`
|
|
37
|
-
: `msteams:group:${conversationId}`,
|
|
38
|
-
to: isUser ? `user:${conversationId}` : `conversation:${conversationId}`,
|
|
39
|
-
});
|
|
40
|
-
}
|
package/src/setup-core.ts
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";
|
|
2
|
-
import {
|
|
3
|
-
createStandardChannelSetupStatus,
|
|
4
|
-
DEFAULT_ACCOUNT_ID,
|
|
5
|
-
type ChannelSetupAdapter,
|
|
6
|
-
type ChannelSetupWizard,
|
|
7
|
-
type WizardPrompter,
|
|
8
|
-
} from "openclaw/plugin-sdk/setup";
|
|
9
|
-
import { formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
|
|
10
|
-
import { normalizeSecretInputString } from "./secret-input.js";
|
|
11
|
-
import { hasConfiguredMSTeamsCredentials, resolveMSTeamsCredentials } from "./token.js";
|
|
12
|
-
|
|
13
|
-
export const msteamsSetupAdapter: ChannelSetupAdapter = {
|
|
14
|
-
resolveAccountId: () => DEFAULT_ACCOUNT_ID,
|
|
15
|
-
applyAccountConfig: ({ cfg }) => ({
|
|
16
|
-
...cfg,
|
|
17
|
-
channels: {
|
|
18
|
-
...cfg.channels,
|
|
19
|
-
msteams: {
|
|
20
|
-
...cfg.channels?.msteams,
|
|
21
|
-
enabled: true,
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
}),
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const channel = "msteams" as const;
|
|
28
|
-
|
|
29
|
-
async function promptMSTeamsCredentials(prompter: WizardPrompter): Promise<{
|
|
30
|
-
appId: string;
|
|
31
|
-
appPassword: string;
|
|
32
|
-
tenantId: string;
|
|
33
|
-
}> {
|
|
34
|
-
const appId = (
|
|
35
|
-
await prompter.text({
|
|
36
|
-
message: "Enter MS Teams App ID",
|
|
37
|
-
validate: (value) => (value?.trim() ? undefined : "Required"),
|
|
38
|
-
})
|
|
39
|
-
).trim();
|
|
40
|
-
const appPassword = (
|
|
41
|
-
await prompter.text({
|
|
42
|
-
message: "Enter MS Teams App Password",
|
|
43
|
-
validate: (value) => (value?.trim() ? undefined : "Required"),
|
|
44
|
-
})
|
|
45
|
-
).trim();
|
|
46
|
-
const tenantId = (
|
|
47
|
-
await prompter.text({
|
|
48
|
-
message: "Enter MS Teams Tenant ID",
|
|
49
|
-
validate: (value) => (value?.trim() ? undefined : "Required"),
|
|
50
|
-
})
|
|
51
|
-
).trim();
|
|
52
|
-
return { appId, appPassword, tenantId };
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
async function noteMSTeamsCredentialHelp(prompter: WizardPrompter): Promise<void> {
|
|
56
|
-
await prompter.note(
|
|
57
|
-
[
|
|
58
|
-
"1) Azure Bot registration -> get App ID + Tenant ID",
|
|
59
|
-
"2) Add a client secret (App Password)",
|
|
60
|
-
"3) Set webhook URL + messaging endpoint",
|
|
61
|
-
"Tip: you can also set MSTEAMS_APP_ID / MSTEAMS_APP_PASSWORD / MSTEAMS_TENANT_ID.",
|
|
62
|
-
`Docs: ${formatDocsLink("/channels/msteams", "msteams")}`,
|
|
63
|
-
].join("\n"),
|
|
64
|
-
"MS Teams credentials",
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export function createMSTeamsSetupWizardBase(): Pick<
|
|
69
|
-
ChannelSetupWizard,
|
|
70
|
-
| "channel"
|
|
71
|
-
| "resolveAccountIdForConfigure"
|
|
72
|
-
| "resolveShouldPromptAccountIds"
|
|
73
|
-
| "status"
|
|
74
|
-
| "credentials"
|
|
75
|
-
| "finalize"
|
|
76
|
-
> {
|
|
77
|
-
return {
|
|
78
|
-
channel,
|
|
79
|
-
resolveAccountIdForConfigure: () => DEFAULT_ACCOUNT_ID,
|
|
80
|
-
resolveShouldPromptAccountIds: () => false,
|
|
81
|
-
status: createStandardChannelSetupStatus({
|
|
82
|
-
channelLabel: "MS Teams",
|
|
83
|
-
configuredLabel: "configured",
|
|
84
|
-
unconfiguredLabel: "needs app credentials",
|
|
85
|
-
configuredHint: "configured",
|
|
86
|
-
unconfiguredHint: "needs app creds",
|
|
87
|
-
configuredScore: 2,
|
|
88
|
-
unconfiguredScore: 0,
|
|
89
|
-
includeStatusLine: true,
|
|
90
|
-
resolveConfigured: ({ cfg }) =>
|
|
91
|
-
Boolean(resolveMSTeamsCredentials(cfg.channels?.msteams)) ||
|
|
92
|
-
hasConfiguredMSTeamsCredentials(cfg.channels?.msteams),
|
|
93
|
-
}),
|
|
94
|
-
credentials: [],
|
|
95
|
-
finalize: async ({ cfg, prompter }) => {
|
|
96
|
-
const resolved = resolveMSTeamsCredentials(cfg.channels?.msteams);
|
|
97
|
-
const hasConfigCreds = hasConfiguredMSTeamsCredentials(cfg.channels?.msteams);
|
|
98
|
-
const canUseEnv = Boolean(
|
|
99
|
-
!hasConfigCreds &&
|
|
100
|
-
normalizeSecretInputString(process.env.MSTEAMS_APP_ID) &&
|
|
101
|
-
normalizeSecretInputString(process.env.MSTEAMS_APP_PASSWORD) &&
|
|
102
|
-
normalizeSecretInputString(process.env.MSTEAMS_TENANT_ID),
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
let next: OpenClawConfig = cfg;
|
|
106
|
-
let appId: string | null = null;
|
|
107
|
-
let appPassword: string | null = null;
|
|
108
|
-
let tenantId: string | null = null;
|
|
109
|
-
|
|
110
|
-
if (!resolved && !hasConfigCreds) {
|
|
111
|
-
await noteMSTeamsCredentialHelp(prompter);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (canUseEnv) {
|
|
115
|
-
const keepEnv = await prompter.confirm({
|
|
116
|
-
message:
|
|
117
|
-
"MSTEAMS_APP_ID + MSTEAMS_APP_PASSWORD + MSTEAMS_TENANT_ID detected. Use env vars?",
|
|
118
|
-
initialValue: true,
|
|
119
|
-
});
|
|
120
|
-
if (keepEnv) {
|
|
121
|
-
next = msteamsSetupAdapter.applyAccountConfig({
|
|
122
|
-
cfg: next,
|
|
123
|
-
accountId: DEFAULT_ACCOUNT_ID,
|
|
124
|
-
input: {},
|
|
125
|
-
});
|
|
126
|
-
} else {
|
|
127
|
-
({ appId, appPassword, tenantId } = await promptMSTeamsCredentials(prompter));
|
|
128
|
-
}
|
|
129
|
-
} else if (hasConfigCreds) {
|
|
130
|
-
const keep = await prompter.confirm({
|
|
131
|
-
message: "MS Teams credentials already configured. Keep them?",
|
|
132
|
-
initialValue: true,
|
|
133
|
-
});
|
|
134
|
-
if (!keep) {
|
|
135
|
-
({ appId, appPassword, tenantId } = await promptMSTeamsCredentials(prompter));
|
|
136
|
-
}
|
|
137
|
-
} else {
|
|
138
|
-
({ appId, appPassword, tenantId } = await promptMSTeamsCredentials(prompter));
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if (appId && appPassword && tenantId) {
|
|
142
|
-
next = {
|
|
143
|
-
...next,
|
|
144
|
-
channels: {
|
|
145
|
-
...next.channels,
|
|
146
|
-
msteams: {
|
|
147
|
-
...next.channels?.msteams,
|
|
148
|
-
enabled: true,
|
|
149
|
-
appId,
|
|
150
|
-
appPassword,
|
|
151
|
-
tenantId,
|
|
152
|
-
},
|
|
153
|
-
},
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return { cfg: next, accountId: DEFAULT_ACCOUNT_ID };
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
}
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from "node:events";
|
|
2
|
-
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/setup";
|
|
3
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
-
import { createMSTeamsSetupWizardBase, msteamsSetupAdapter } from "./setup-core.js";
|
|
5
|
-
import { openDelegatedOAuthUrl } from "./setup-surface.js";
|
|
6
|
-
|
|
7
|
-
const spawn = vi.hoisted(() => vi.fn());
|
|
8
|
-
const resolveMSTeamsUserAllowlist = vi.hoisted(() => vi.fn());
|
|
9
|
-
const resolveMSTeamsChannelAllowlist = vi.hoisted(() => vi.fn());
|
|
10
|
-
const normalizeSecretInputString = vi.hoisted(() =>
|
|
11
|
-
vi.fn((value: unknown) => (typeof value === "string" ? value.trim() || undefined : undefined)),
|
|
12
|
-
);
|
|
13
|
-
const hasConfiguredMSTeamsCredentials = vi.hoisted(() => vi.fn());
|
|
14
|
-
const resolveMSTeamsCredentials = vi.hoisted(() => vi.fn());
|
|
15
|
-
|
|
16
|
-
vi.mock("./resolve-allowlist.js", () => ({
|
|
17
|
-
parseMSTeamsTeamEntry: vi.fn(),
|
|
18
|
-
resolveMSTeamsChannelAllowlist,
|
|
19
|
-
resolveMSTeamsUserAllowlist,
|
|
20
|
-
}));
|
|
21
|
-
|
|
22
|
-
vi.mock("./secret-input.js", () => ({
|
|
23
|
-
normalizeSecretInputString,
|
|
24
|
-
}));
|
|
25
|
-
|
|
26
|
-
vi.mock("./token.js", () => ({
|
|
27
|
-
hasConfiguredMSTeamsCredentials,
|
|
28
|
-
resolveMSTeamsCredentials,
|
|
29
|
-
}));
|
|
30
|
-
|
|
31
|
-
vi.mock("node:child_process", async (importOriginal) => {
|
|
32
|
-
const actual = await importOriginal<typeof import("node:child_process")>();
|
|
33
|
-
return {
|
|
34
|
-
...actual,
|
|
35
|
-
spawn,
|
|
36
|
-
};
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
describe("msteams setup surface", () => {
|
|
40
|
-
const msteamsSetupWizard = createMSTeamsSetupWizardBase();
|
|
41
|
-
|
|
42
|
-
beforeEach(() => {
|
|
43
|
-
spawn.mockReset();
|
|
44
|
-
resolveMSTeamsUserAllowlist.mockReset();
|
|
45
|
-
resolveMSTeamsChannelAllowlist.mockReset();
|
|
46
|
-
normalizeSecretInputString.mockClear();
|
|
47
|
-
hasConfiguredMSTeamsCredentials.mockReset();
|
|
48
|
-
resolveMSTeamsCredentials.mockReset();
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
afterEach(() => {
|
|
52
|
-
vi.unstubAllEnvs();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("always resolves to the default account", () => {
|
|
56
|
-
expect(msteamsSetupAdapter.resolveAccountId?.({ accountId: "work" } as never)).toBe(
|
|
57
|
-
DEFAULT_ACCOUNT_ID,
|
|
58
|
-
);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it("opens delegated OAuth URLs without invoking a shell", async () => {
|
|
62
|
-
const url = "https://login.microsoftonline.com/auth?state=$(touch pwned)";
|
|
63
|
-
const child = new EventEmitter();
|
|
64
|
-
spawn.mockReturnValue(child);
|
|
65
|
-
|
|
66
|
-
const result = openDelegatedOAuthUrl(url);
|
|
67
|
-
child.emit("exit", 0, null);
|
|
68
|
-
|
|
69
|
-
await expect(result).resolves.toBeUndefined();
|
|
70
|
-
expect(spawn).toHaveBeenCalledWith(process.platform === "darwin" ? "open" : "xdg-open", [url], {
|
|
71
|
-
stdio: "ignore",
|
|
72
|
-
shell: false,
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it("enables the msteams channel without dropping existing config", () => {
|
|
77
|
-
expect(
|
|
78
|
-
msteamsSetupAdapter.applyAccountConfig?.({
|
|
79
|
-
cfg: {
|
|
80
|
-
channels: {
|
|
81
|
-
msteams: {
|
|
82
|
-
appId: "existing-app",
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
accountId: DEFAULT_ACCOUNT_ID,
|
|
87
|
-
input: {},
|
|
88
|
-
} as never),
|
|
89
|
-
).toEqual({
|
|
90
|
-
channels: {
|
|
91
|
-
msteams: {
|
|
92
|
-
appId: "existing-app",
|
|
93
|
-
enabled: true,
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("reports configured status from resolved credentials", async () => {
|
|
100
|
-
resolveMSTeamsCredentials.mockReturnValue({
|
|
101
|
-
appId: "app",
|
|
102
|
-
});
|
|
103
|
-
hasConfiguredMSTeamsCredentials.mockReturnValue(false);
|
|
104
|
-
|
|
105
|
-
expect(
|
|
106
|
-
msteamsSetupWizard.status.resolveConfigured({
|
|
107
|
-
cfg: { channels: { msteams: {} } },
|
|
108
|
-
} as never),
|
|
109
|
-
).toBe(true);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it("reports configured status from configured credentials and renders status lines", async () => {
|
|
113
|
-
resolveMSTeamsCredentials.mockReturnValue(null);
|
|
114
|
-
hasConfiguredMSTeamsCredentials.mockReturnValue(true);
|
|
115
|
-
|
|
116
|
-
expect(
|
|
117
|
-
msteamsSetupWizard.status.resolveConfigured({
|
|
118
|
-
cfg: { channels: { msteams: {} } },
|
|
119
|
-
} as never),
|
|
120
|
-
).toBe(true);
|
|
121
|
-
|
|
122
|
-
hasConfiguredMSTeamsCredentials.mockReturnValue(false);
|
|
123
|
-
expect(msteamsSetupWizard.status.resolveStatusLines).toBeTypeOf("function");
|
|
124
|
-
await expect(
|
|
125
|
-
msteamsSetupWizard.status.resolveStatusLines?.({
|
|
126
|
-
cfg: { channels: { msteams: {} } },
|
|
127
|
-
} as never),
|
|
128
|
-
).resolves.toEqual(["MS Teams: needs app credentials"]);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it("finalize keeps env credentials when available and accepted", async () => {
|
|
132
|
-
vi.stubEnv("MSTEAMS_APP_ID", "env-app");
|
|
133
|
-
vi.stubEnv("MSTEAMS_APP_PASSWORD", "env-secret");
|
|
134
|
-
vi.stubEnv("MSTEAMS_TENANT_ID", "env-tenant");
|
|
135
|
-
resolveMSTeamsCredentials.mockReturnValue(null);
|
|
136
|
-
hasConfiguredMSTeamsCredentials.mockReturnValue(false);
|
|
137
|
-
|
|
138
|
-
const result = await msteamsSetupWizard.finalize?.({
|
|
139
|
-
cfg: { channels: { msteams: { existing: true } } },
|
|
140
|
-
prompter: {
|
|
141
|
-
confirm: vi.fn(async () => true),
|
|
142
|
-
note: vi.fn(async () => {}),
|
|
143
|
-
text: vi.fn(),
|
|
144
|
-
},
|
|
145
|
-
} as never);
|
|
146
|
-
|
|
147
|
-
expect(result).toEqual({
|
|
148
|
-
accountId: "default",
|
|
149
|
-
cfg: {
|
|
150
|
-
channels: {
|
|
151
|
-
msteams: {
|
|
152
|
-
existing: true,
|
|
153
|
-
enabled: true,
|
|
154
|
-
},
|
|
155
|
-
},
|
|
156
|
-
},
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
it("finalize prompts for manual credentials when env/config creds are unavailable", async () => {
|
|
161
|
-
resolveMSTeamsCredentials.mockReturnValue(null);
|
|
162
|
-
hasConfiguredMSTeamsCredentials.mockReturnValue(false);
|
|
163
|
-
const note = vi.fn(async () => {});
|
|
164
|
-
const confirm = vi.fn(async () => false);
|
|
165
|
-
const text = vi.fn(async ({ message }: { message: string }) => {
|
|
166
|
-
if (message === "Enter MS Teams App ID") {
|
|
167
|
-
return "app-id";
|
|
168
|
-
}
|
|
169
|
-
if (message === "Enter MS Teams App Password") {
|
|
170
|
-
return "app-password";
|
|
171
|
-
}
|
|
172
|
-
if (message === "Enter MS Teams Tenant ID") {
|
|
173
|
-
return "tenant-id";
|
|
174
|
-
}
|
|
175
|
-
throw new Error(`Unexpected prompt: ${message}`);
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
const result = await msteamsSetupWizard.finalize?.({
|
|
179
|
-
cfg: { channels: { msteams: {} } },
|
|
180
|
-
prompter: {
|
|
181
|
-
confirm,
|
|
182
|
-
note,
|
|
183
|
-
text,
|
|
184
|
-
},
|
|
185
|
-
} as never);
|
|
186
|
-
|
|
187
|
-
expect(note).toHaveBeenCalled();
|
|
188
|
-
expect(result).toEqual({
|
|
189
|
-
accountId: "default",
|
|
190
|
-
cfg: {
|
|
191
|
-
channels: {
|
|
192
|
-
msteams: {
|
|
193
|
-
enabled: true,
|
|
194
|
-
appId: "app-id",
|
|
195
|
-
appPassword: "app-password",
|
|
196
|
-
tenantId: "tenant-id",
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
},
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
});
|