@arbium/enterprise-agent-connect 0.0.0-stage → 0.1.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/LICENSE +202 -0
- package/README.md +117 -2
- package/dist/connectors/dell-techdirect/connector.json +39 -0
- package/dist/connectors/dell-techdirect/index.js +7 -0
- package/dist/connectors/dell-techdirect/index.js.map +1 -0
- package/dist/connectors/dell-techdirect/tools.js +49 -0
- package/dist/connectors/dell-techdirect/tools.js.map +1 -0
- package/dist/connectors/dell-techdirect/vendor.js +57 -0
- package/dist/connectors/dell-techdirect/vendor.js.map +1 -0
- package/dist/connectors/entra/connector.json +85 -0
- package/dist/connectors/entra/index.js +4 -0
- package/dist/connectors/entra/index.js.map +1 -0
- package/dist/connectors/entra/tools.js +262 -0
- package/dist/connectors/entra/tools.js.map +1 -0
- package/dist/connectors/fedex/connector.json +118 -0
- package/dist/connectors/fedex/index.js +7 -0
- package/dist/connectors/fedex/index.js.map +1 -0
- package/dist/connectors/fedex/tools.js +152 -0
- package/dist/connectors/fedex/tools.js.map +1 -0
- package/dist/connectors/fedex/vendor.js +98 -0
- package/dist/connectors/fedex/vendor.js.map +1 -0
- package/dist/connectors/http/index.js +235 -0
- package/dist/connectors/http/index.js.map +1 -0
- package/dist/connectors/intune/connector.json +106 -0
- package/dist/connectors/intune/index.js +4 -0
- package/dist/connectors/intune/index.js.map +1 -0
- package/dist/connectors/intune/tools.js +416 -0
- package/dist/connectors/intune/tools.js.map +1 -0
- package/dist/connectors/jira/connector.json +129 -0
- package/dist/connectors/jira/index.js +7 -0
- package/dist/connectors/jira/index.js.map +1 -0
- package/dist/connectors/jira/jql.js +67 -0
- package/dist/connectors/jira/jql.js.map +1 -0
- package/dist/connectors/jira/tools.js +464 -0
- package/dist/connectors/jira/tools.js.map +1 -0
- package/dist/connectors/jira/vendor.js +94 -0
- package/dist/connectors/jira/vendor.js.map +1 -0
- package/dist/connectors/microsoft/client.js +434 -0
- package/dist/connectors/microsoft/client.js.map +1 -0
- package/dist/connectors/microsoft/provider.json +118 -0
- package/dist/connectors/outlook-calendar/connector.json +136 -0
- package/dist/connectors/outlook-calendar/index.js +4 -0
- package/dist/connectors/outlook-calendar/index.js.map +1 -0
- package/dist/connectors/outlook-calendar/tools.js +398 -0
- package/dist/connectors/outlook-calendar/tools.js.map +1 -0
- package/dist/connectors/outlook-mail/connector.json +154 -0
- package/dist/connectors/outlook-mail/index.js +4 -0
- package/dist/connectors/outlook-mail/index.js.map +1 -0
- package/dist/connectors/outlook-mail/tools.js +236 -0
- package/dist/connectors/outlook-mail/tools.js.map +1 -0
- package/dist/connectors/salesforce/connector.json +122 -0
- package/dist/connectors/salesforce/index.js +7 -0
- package/dist/connectors/salesforce/index.js.map +1 -0
- package/dist/connectors/salesforce/soql.js +60 -0
- package/dist/connectors/salesforce/soql.js.map +1 -0
- package/dist/connectors/salesforce/tools.js +234 -0
- package/dist/connectors/salesforce/tools.js.map +1 -0
- package/dist/connectors/salesforce/vendor.js +107 -0
- package/dist/connectors/salesforce/vendor.js.map +1 -0
- package/dist/connectors/sharepoint-files/connector.json +194 -0
- package/dist/connectors/sharepoint-files/excel.js +300 -0
- package/dist/connectors/sharepoint-files/excel.js.map +1 -0
- package/dist/connectors/sharepoint-files/index.js +12 -0
- package/dist/connectors/sharepoint-files/index.js.map +1 -0
- package/dist/connectors/sharepoint-files/tools.js +365 -0
- package/dist/connectors/sharepoint-files/tools.js.map +1 -0
- package/dist/connectors/sharepoint-files/vendor.js +167 -0
- package/dist/connectors/sharepoint-files/vendor.js.map +1 -0
- package/dist/connectors/teams/connector.json +298 -0
- package/dist/connectors/teams/index.js +5 -0
- package/dist/connectors/teams/index.js.map +1 -0
- package/dist/connectors/teams/tools.js +391 -0
- package/dist/connectors/teams/tools.js.map +1 -0
- package/dist/packages/connector-kit/src/branding.js +102 -0
- package/dist/packages/connector-kit/src/branding.js.map +1 -0
- package/dist/packages/connector-kit/src/certificate.js +84 -0
- package/dist/packages/connector-kit/src/certificate.js.map +1 -0
- package/dist/packages/connector-kit/src/common.js +107 -0
- package/dist/packages/connector-kit/src/common.js.map +1 -0
- package/dist/packages/connector-kit/src/connector.js +492 -0
- package/dist/packages/connector-kit/src/connector.js.map +1 -0
- package/dist/packages/connector-kit/src/oauth.js +79 -0
- package/dist/packages/connector-kit/src/oauth.js.map +1 -0
- package/dist/packages/connector-kit/src/types.js +20 -0
- package/dist/packages/connector-kit/src/types.js.map +1 -0
- package/dist/packages/server/migrations/0001_tables.sql +268 -0
- package/dist/packages/server/migrations/0002_organizations.sql +72 -0
- package/dist/packages/server/migrations/0003_drop_unused.sql +3 -0
- package/dist/packages/server/migrations/0004_trigger_runners.sql +15 -0
- package/dist/packages/server/migrations/0005_run_runner.sql +3 -0
- package/dist/packages/server/migrations/0006_approvals.sql +36 -0
- package/dist/packages/server/migrations/rollback/to-legacy.sql +87 -0
- package/dist/packages/server/src/api.js +684 -0
- package/dist/packages/server/src/api.js.map +1 -0
- package/dist/packages/server/src/app.js +444 -0
- package/dist/packages/server/src/app.js.map +1 -0
- package/dist/packages/server/src/builtin.js +24 -0
- package/dist/packages/server/src/builtin.js.map +1 -0
- package/dist/packages/server/src/consent.js +36 -0
- package/dist/packages/server/src/consent.js.map +1 -0
- package/dist/packages/server/src/index.js +129 -0
- package/dist/packages/server/src/index.js.map +1 -0
- package/dist/packages/server/src/migrate.js +134 -0
- package/dist/packages/server/src/migrate.js.map +1 -0
- package/dist/packages/server/src/openapi.js +101 -0
- package/dist/packages/server/src/openapi.js.map +1 -0
- package/dist/packages/server/src/secrets.js +76 -0
- package/dist/packages/server/src/secrets.js.map +1 -0
- package/dist/packages/server/src/server.js +69 -0
- package/dist/packages/server/src/server.js.map +1 -0
- package/dist/packages/server/src/service.js +908 -0
- package/dist/packages/server/src/service.js.map +1 -0
- package/dist/packages/server/src/store.js +411 -0
- package/dist/packages/server/src/store.js.map +1 -0
- package/dist/packages/server/src/teams/activity.js +187 -0
- package/dist/packages/server/src/teams/activity.js.map +1 -0
- package/dist/packages/server/src/teams/admin.js +699 -0
- package/dist/packages/server/src/teams/admin.js.map +1 -0
- package/dist/packages/server/src/teams/approval.js +118 -0
- package/dist/packages/server/src/teams/approval.js.map +1 -0
- package/dist/packages/server/src/teams/bot.js +124 -0
- package/dist/packages/server/src/teams/bot.js.map +1 -0
- package/dist/packages/server/src/teams/claude.js +165 -0
- package/dist/packages/server/src/teams/claude.js.map +1 -0
- package/dist/packages/server/src/teams/jwt.js +121 -0
- package/dist/packages/server/src/teams/jwt.js.map +1 -0
- package/dist/packages/server/src/teams/package.js +319 -0
- package/dist/packages/server/src/teams/package.js.map +1 -0
- package/dist/packages/server/src/teams/provision.js +505 -0
- package/dist/packages/server/src/teams/provision.js.map +1 -0
- package/dist/packages/server/src/teams/runner.js +143 -0
- package/dist/packages/server/src/teams/runner.js.map +1 -0
- package/dist/packages/server/src/teams/runtime.js +701 -0
- package/dist/packages/server/src/teams/runtime.js.map +1 -0
- package/dist/packages/server/src/teams/store.js +507 -0
- package/dist/packages/server/src/teams/store.js.map +1 -0
- package/package.json +42 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../../../../packages/server/src/teams/jwt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { crc32, deflateRawSync, deflateSync } from "node:zlib";
|
|
3
|
+
import { brand, teamsDeveloper } from "../../../connector-kit/src/branding.js";
|
|
4
|
+
// The Teams app package for one agent's bot (manifest + generated icons, zipped) and the
|
|
5
|
+
// setup script that creates the bot in the customer's tenant. docs/teams.md 5 and 10.
|
|
6
|
+
export const MANIFEST_VERSION = "1.24";
|
|
7
|
+
// Teams delivers every message where the bot is installed, not just @mentions, and the bot can
|
|
8
|
+
// read those conversations through Graph. Only where it was added; consented at install.
|
|
9
|
+
export const RSC_PERMISSIONS = ["ChannelMessage.Read.Group", "ChatMessage.Read.Chat"];
|
|
10
|
+
export function manifest(input) {
|
|
11
|
+
const name = input.displayName.trim();
|
|
12
|
+
if (name.length < 1 || name.length > 30)
|
|
13
|
+
throw new Error("A bot name is 1 to 30 characters");
|
|
14
|
+
const host = new URL(input.publicUrl).host;
|
|
15
|
+
const full = `${name} is an agent your organization set up in ${brand().productName}. It reads messages in the teams and chats it is added to, and answers when asked. Your administrator controls what it may do.`;
|
|
16
|
+
return {
|
|
17
|
+
$schema: `https://developer.microsoft.com/json-schemas/teams/v${MANIFEST_VERSION}/MicrosoftTeams.schema.json`,
|
|
18
|
+
manifestVersion: MANIFEST_VERSION,
|
|
19
|
+
version: `1.0.${input.manifestVersion}`,
|
|
20
|
+
id: input.teamsAppId,
|
|
21
|
+
// The app's developer, from the branding.
|
|
22
|
+
developer: teamsDeveloper(),
|
|
23
|
+
name: { short: name, full: `${name} (${brand().productName} agent)`.slice(0, 100) },
|
|
24
|
+
description: { short: `${name}, an agent from ${brand().productName}`.slice(0, 80), full },
|
|
25
|
+
icons: { color: "color.png", outline: "outline.png" },
|
|
26
|
+
accentColor: accent(name),
|
|
27
|
+
bots: [
|
|
28
|
+
{
|
|
29
|
+
botId: input.botAppId,
|
|
30
|
+
scopes: ["personal", "team", "groupChat"],
|
|
31
|
+
isNotificationOnly: false,
|
|
32
|
+
supportsFiles: false,
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
webApplicationInfo: {
|
|
36
|
+
id: input.botAppId,
|
|
37
|
+
resource: `api://${host}/agent-connect/teams/${input.botAppId}`,
|
|
38
|
+
},
|
|
39
|
+
authorization: {
|
|
40
|
+
permissions: {
|
|
41
|
+
resourceSpecific: RSC_PERMISSIONS.map((name) => ({ name, type: "Application" })),
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export function packageZip(input) {
|
|
47
|
+
const name = input.displayName;
|
|
48
|
+
return zip([
|
|
49
|
+
["manifest.json", Buffer.from(JSON.stringify(manifest(input), null, 2))],
|
|
50
|
+
["color.png", colorIcon(name)],
|
|
51
|
+
["outline.png", outlineIcon(name)],
|
|
52
|
+
]);
|
|
53
|
+
}
|
|
54
|
+
// ---- icons: the agent's initials, from a 5x7 bitmap font, on a color from its name ----
|
|
55
|
+
const GLYPHS = {
|
|
56
|
+
A: "01110100011000111111100011000110001",
|
|
57
|
+
B: "11110100011000111110100011000111110",
|
|
58
|
+
C: "01110100011000010000100001000101110",
|
|
59
|
+
D: "11100100101000110001100011001011100",
|
|
60
|
+
E: "11111100001000011110100001000011111",
|
|
61
|
+
F: "11111100001000011110100001000010000",
|
|
62
|
+
G: "01110100011000010111100011000101111",
|
|
63
|
+
H: "10001100011000111111100011000110001",
|
|
64
|
+
I: "01110001000010000100001000010001110",
|
|
65
|
+
J: "00111000100001000010000101001001100",
|
|
66
|
+
K: "10001100101010011000101001001010001",
|
|
67
|
+
L: "10000100001000010000100001000011111",
|
|
68
|
+
M: "10001110111010110101100011000110001",
|
|
69
|
+
N: "10001100011100110101100111000110001",
|
|
70
|
+
O: "01110100011000110001100011000101110",
|
|
71
|
+
P: "11110100011000111110100001000010000",
|
|
72
|
+
Q: "01110100011000110001101011001001101",
|
|
73
|
+
R: "11110100011000111110101001001010001",
|
|
74
|
+
S: "01111100001000001110000010000111110",
|
|
75
|
+
T: "11111001000010000100001000010000100",
|
|
76
|
+
U: "10001100011000110001100011000101110",
|
|
77
|
+
V: "10001100011000110001100010101000100",
|
|
78
|
+
W: "10001100011000110101101011010101010",
|
|
79
|
+
X: "10001100010101000100010101000110001",
|
|
80
|
+
Y: "10001100010101000100001000010000100",
|
|
81
|
+
Z: "11111000010001000100010001000011111",
|
|
82
|
+
"0": "01110100011001110101110011000101110",
|
|
83
|
+
"1": "00100011000010000100001000010001110",
|
|
84
|
+
"2": "01110100010000100010001000100011111",
|
|
85
|
+
"3": "11111000100010000010000011000101110",
|
|
86
|
+
"4": "00010001100101010010111110001000010",
|
|
87
|
+
"5": "11111100001111000001000011000101110",
|
|
88
|
+
"6": "00110010001000011110100011000101110",
|
|
89
|
+
"7": "11111000010001000100010000100001000",
|
|
90
|
+
"8": "01110100011000101110100011000101110",
|
|
91
|
+
"9": "01110100011000101111000010001001100",
|
|
92
|
+
};
|
|
93
|
+
/** Up to two characters: the first letters of the first two words, else "AI". */
|
|
94
|
+
export function initials(name) {
|
|
95
|
+
const words = name
|
|
96
|
+
.normalize("NFD")
|
|
97
|
+
.replace(/\p{M}/gu, "")
|
|
98
|
+
.toUpperCase()
|
|
99
|
+
.split(/[^A-Z0-9]+/)
|
|
100
|
+
.filter(Boolean);
|
|
101
|
+
const out = words
|
|
102
|
+
.slice(0, 2)
|
|
103
|
+
.map((w) => w[0])
|
|
104
|
+
.join("");
|
|
105
|
+
return out || "AI";
|
|
106
|
+
}
|
|
107
|
+
const hue = (name) => createHash("sha256").update(name).digest()[0] / 255;
|
|
108
|
+
function hsl(h, s, l) {
|
|
109
|
+
const f = (n) => {
|
|
110
|
+
const k = (n + h * 12) % 12;
|
|
111
|
+
const a = s * Math.min(l, 1 - l);
|
|
112
|
+
return Math.round(255 * (l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1))));
|
|
113
|
+
};
|
|
114
|
+
return [f(0), f(8), f(4)];
|
|
115
|
+
}
|
|
116
|
+
function accent(name) {
|
|
117
|
+
return `#${hsl(hue(name), 0.55, 0.38)
|
|
118
|
+
.map((v) => v.toString(16).padStart(2, "0"))
|
|
119
|
+
.join("")}`.toUpperCase();
|
|
120
|
+
}
|
|
121
|
+
// Pixels of the initials, centered, `scale` pixels per font dot.
|
|
122
|
+
function glyphMask(text, size, scale) {
|
|
123
|
+
const chars = [...text].map((c) => GLYPHS[c] ?? GLYPHS.A);
|
|
124
|
+
const width = (chars.length * 5 + (chars.length - 1)) * scale;
|
|
125
|
+
const x0 = Math.floor((size - width) / 2);
|
|
126
|
+
const y0 = Math.floor((size - 7 * scale) / 2);
|
|
127
|
+
return (x, y) => {
|
|
128
|
+
const gx = Math.floor((x - x0) / scale);
|
|
129
|
+
const gy = Math.floor((y - y0) / scale);
|
|
130
|
+
if (x < x0 || y < y0 || gy >= 7)
|
|
131
|
+
return false;
|
|
132
|
+
const index = Math.floor(gx / 6);
|
|
133
|
+
const col = gx % 6;
|
|
134
|
+
if (index >= chars.length || col === 5)
|
|
135
|
+
return false;
|
|
136
|
+
return chars[index][gy * 5 + col] === "1";
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/** 192×192, the initials in white on the agent's color. */
|
|
140
|
+
export function colorIcon(name) {
|
|
141
|
+
const text = initials(name);
|
|
142
|
+
const [r, g, b] = hsl(hue(name), 0.55, 0.38);
|
|
143
|
+
const on = glyphMask(text, 192, text.length > 1 ? 12 : 16);
|
|
144
|
+
return png(192, (x, y) => (on(x, y) ? [255, 255, 255, 255] : [r, g, b, 255]));
|
|
145
|
+
}
|
|
146
|
+
/** 32×32, only white and transparent pixels, as Teams requires. */
|
|
147
|
+
export function outlineIcon(name) {
|
|
148
|
+
const text = initials(name);
|
|
149
|
+
const on = glyphMask(text, 32, 2);
|
|
150
|
+
return png(32, (x, y) => (on(x, y) ? [255, 255, 255, 255] : [0, 0, 0, 0]));
|
|
151
|
+
}
|
|
152
|
+
function chunk(type, data) {
|
|
153
|
+
const length = Buffer.alloc(4);
|
|
154
|
+
length.writeUInt32BE(data.length);
|
|
155
|
+
const body = Buffer.concat([Buffer.from(type, "ascii"), data]);
|
|
156
|
+
const crc = Buffer.alloc(4);
|
|
157
|
+
crc.writeUInt32BE(crc32(body));
|
|
158
|
+
return Buffer.concat([length, body, crc]);
|
|
159
|
+
}
|
|
160
|
+
function png(size, pixel) {
|
|
161
|
+
const header = Buffer.alloc(13);
|
|
162
|
+
header.writeUInt32BE(size, 0);
|
|
163
|
+
header.writeUInt32BE(size, 4);
|
|
164
|
+
header.set([8, 6, 0, 0, 0], 8); // 8-bit RGBA
|
|
165
|
+
const raw = Buffer.alloc(size * (size * 4 + 1));
|
|
166
|
+
for (let y = 0; y < size; y++)
|
|
167
|
+
for (let x = 0; x < size; x++)
|
|
168
|
+
raw.set(pixel(x, y), y * (size * 4 + 1) + 1 + x * 4);
|
|
169
|
+
return Buffer.concat([
|
|
170
|
+
Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
|
|
171
|
+
chunk("IHDR", header),
|
|
172
|
+
chunk("IDAT", deflateSync(raw)),
|
|
173
|
+
chunk("IEND", Buffer.alloc(0)),
|
|
174
|
+
]);
|
|
175
|
+
}
|
|
176
|
+
// ---- zip (deflate), enough for three files ----
|
|
177
|
+
function zip(files) {
|
|
178
|
+
const locals = [];
|
|
179
|
+
const centrals = [];
|
|
180
|
+
let offset = 0;
|
|
181
|
+
for (const [name, data] of files) {
|
|
182
|
+
const packed = deflateRawSync(data);
|
|
183
|
+
const nameBytes = Buffer.from(name, "utf8");
|
|
184
|
+
const common = Buffer.alloc(26);
|
|
185
|
+
common.writeUInt16LE(20, 0); // version needed
|
|
186
|
+
common.writeUInt16LE(0, 2); // flags
|
|
187
|
+
common.writeUInt16LE(8, 4); // deflate
|
|
188
|
+
common.writeUInt32LE(0x00210000, 6); // 1980-01-01 00:00, for reproducible output
|
|
189
|
+
common.writeUInt32LE(crc32(data), 10);
|
|
190
|
+
common.writeUInt32LE(packed.length, 14);
|
|
191
|
+
common.writeUInt32LE(data.length, 18);
|
|
192
|
+
common.writeUInt16LE(nameBytes.length, 22);
|
|
193
|
+
common.writeUInt16LE(0, 24);
|
|
194
|
+
const local = Buffer.concat([Buffer.from([0x50, 0x4b, 0x03, 0x04]), common, nameBytes, packed]);
|
|
195
|
+
const central = Buffer.alloc(46);
|
|
196
|
+
central.writeUInt32LE(0x02014b50, 0);
|
|
197
|
+
central.writeUInt16LE(20, 4);
|
|
198
|
+
common.copy(central, 6);
|
|
199
|
+
central.writeUInt32LE(offset, 42);
|
|
200
|
+
centrals.push(central, nameBytes);
|
|
201
|
+
locals.push(local);
|
|
202
|
+
offset += local.length;
|
|
203
|
+
}
|
|
204
|
+
const dir = Buffer.concat(centrals);
|
|
205
|
+
const end = Buffer.alloc(22);
|
|
206
|
+
end.writeUInt32LE(0x06054b50, 0);
|
|
207
|
+
end.writeUInt16LE(files.length, 8);
|
|
208
|
+
end.writeUInt16LE(files.length, 10);
|
|
209
|
+
end.writeUInt32LE(dir.length, 12);
|
|
210
|
+
end.writeUInt32LE(offset, 16);
|
|
211
|
+
return Buffer.concat([...locals, dir, end]);
|
|
212
|
+
}
|
|
213
|
+
// ---- setup script ----
|
|
214
|
+
/** The bot's app registration, by the unique name both Add to Teams and the script give it. */
|
|
215
|
+
const appUri = (botId) => `https://graph.microsoft.com/v1.0/applications(uniqueName='${brand().resourcePrefix}-bot-${botId}')`;
|
|
216
|
+
// PowerShell reads the typographic single quotes as quotes too; each is doubled like '.
|
|
217
|
+
const psQuote = (s) => `'${s.replace(/['\u2018\u2019\u201a\u201b]/g, "$&$&")}'`;
|
|
218
|
+
/** One PowerShell script that creates the agent's bot in the customer's tenant: app
|
|
219
|
+
* registration with the service's certificate, Azure Bot with the Teams channel, and the
|
|
220
|
+
* Teams app in the organization's catalog. The admin pastes the printed application ID back. */
|
|
221
|
+
export function setupScript(input) {
|
|
222
|
+
// The bot's app id is only known once the script made the app: the package is filled in
|
|
223
|
+
// there, from a manifest with a placeholder.
|
|
224
|
+
const PLACEHOLDER = "00000000-0000-0000-0000-00000000b07a";
|
|
225
|
+
const template = JSON.stringify(manifest({ ...input, botAppId: PLACEHOLDER, manifestVersion: 1 }), null, 2);
|
|
226
|
+
const endpoint = `${input.publicUrl.replace(/\/+$/, "")}/teams/bots/{0}/messages`;
|
|
227
|
+
return `# Creates the Microsoft Teams bot for the ${brand().productName} agent ${JSON.stringify(input.displayName)}.
|
|
228
|
+
# Needs an Azure subscription where you are Contributor (the bot uses the free tier and costs
|
|
229
|
+
# nothing), PowerShell 7 (Windows, macOS or Linux) with the MicrosoftTeams module
|
|
230
|
+
# (Install-Module MicrosoftTeams), and az login --tenant ${input.tenantId} as someone who can
|
|
231
|
+
# create app registrations. It signs you in to Teams itself (a Teams administrator); on macOS
|
|
232
|
+
# and Linux with a code you enter in a browser.
|
|
233
|
+
# Safe to run again: what already exists is reused.
|
|
234
|
+
param(
|
|
235
|
+
[string]$Subscription = "",
|
|
236
|
+
[string]$ResourceGroup = "${brand().teams.resourceGroup}",
|
|
237
|
+
# Where the bot's Azure record is kept.
|
|
238
|
+
[string]$Location = "westeurope"
|
|
239
|
+
)
|
|
240
|
+
$ErrorActionPreference = "Stop"
|
|
241
|
+
$PSNativeCommandUseErrorActionPreference = $true
|
|
242
|
+
$Name = ${psQuote(input.displayName)}
|
|
243
|
+
$Tenant = ${psQuote(input.tenantId)}
|
|
244
|
+
$TeamsAppId = ${psQuote(input.teamsAppId)}
|
|
245
|
+
|
|
246
|
+
# 0. Check everything this needs before creating anything.
|
|
247
|
+
if (-not (Get-Module -ListAvailable MicrosoftTeams)) { throw "Install the Teams module first: Install-Module MicrosoftTeams" }
|
|
248
|
+
if ((az account show --query tenantId -o tsv) -ne $Tenant) { throw "Sign in to tenant $Tenant with az login --tenant $Tenant" }
|
|
249
|
+
if ($Subscription) { az account set --subscription $Subscription }
|
|
250
|
+
$Sub = az account show --query "{id:id,tenant:tenantId}" -o json | ConvertFrom-Json
|
|
251
|
+
if (-not $Sub.id -or $Sub.tenant -ne $Tenant) { throw "This needs an Azure subscription where you are Contributor. The bot uses the free tier and costs nothing. Pass one with -Subscription." }
|
|
252
|
+
# Windows signs in with a window; elsewhere Microsoft shows a code to enter in a browser.
|
|
253
|
+
try { Get-CsTenant | Out-Null } catch {
|
|
254
|
+
if ($IsWindows -or $PSVersionTable.PSEdition -eq "Desktop") { Connect-MicrosoftTeams | Out-Null } else { Connect-MicrosoftTeams -UseDeviceAuthentication | Out-Null }
|
|
255
|
+
}
|
|
256
|
+
$Existing = Get-TeamsApp -ExternalId $TeamsAppId
|
|
257
|
+
function Retry([scriptblock]$Step) {
|
|
258
|
+
for ($i = 1; ; $i++) {
|
|
259
|
+
try { return & $Step } catch { if ($i -ge 5) { throw }; Start-Sleep -Seconds 10 }
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
$Work = Join-Path ([IO.Path]::GetTempPath()) ("${brand().resourcePrefix}-bot-" + [guid]::NewGuid())
|
|
263
|
+
New-Item -ItemType Directory $Work | Out-Null
|
|
264
|
+
|
|
265
|
+
# 1. App registration in this organization only, with ${brand().productName}'s certificate (public half).
|
|
266
|
+
# Found again by its unique name, never by its display name, so no other app is touched.
|
|
267
|
+
$AppUri = ${psQuote(appUri(input.botId))}
|
|
268
|
+
@{ displayName = "$Name (${brand().productName})"; signInAudience = "AzureADMyOrg" } | ConvertTo-Json | Set-Content (Join-Path $Work "app.json")
|
|
269
|
+
az rest --method PATCH --uri $AppUri --headers "Prefer=create-if-missing" --body ("@" + (Join-Path $Work "app.json")) | Out-Null
|
|
270
|
+
$app = Retry { az rest --method GET --uri ($AppUri + '?$select=id,appId') | ConvertFrom-Json }
|
|
271
|
+
Write-Host "Application ID: $($app.appId)"
|
|
272
|
+
if (-not (az ad sp list --filter "appId eq '$($app.appId)'" --query "[0].id" -o tsv)) { Retry { az ad sp create --id $app.appId | Out-Null } }
|
|
273
|
+
Set-Content (Join-Path $Work "${brand().resourcePrefix}.pem") -NoNewline -Value @'
|
|
274
|
+
${input.certificate.trim()}
|
|
275
|
+
'@
|
|
276
|
+
Retry { az ad app credential reset --id $app.appId --cert ("@" + (Join-Path $Work "${brand().resourcePrefix}.pem")) --append | Out-Null }
|
|
277
|
+
|
|
278
|
+
# 2. Azure Bot (free tier) with the Teams channel, sending messages to ${brand().productName}.
|
|
279
|
+
$Bot = "${brand().resourcePrefix}-" + $app.appId.Substring(0, 8)
|
|
280
|
+
az provider register -n Microsoft.BotService --wait
|
|
281
|
+
az group create -n $ResourceGroup -l $Location | Out-Null
|
|
282
|
+
$found = az resource list -g $ResourceGroup --resource-type Microsoft.BotService/botServices --query "[?name=='$Bot'].id" -o tsv
|
|
283
|
+
# The name holds only 8 hex of the app id, so a bot made for another app may hold it.
|
|
284
|
+
if ($found -and (az resource show --ids $found --query properties.msaAppId -o tsv) -ne $app.appId) { throw "An Azure Bot named $Bot in $ResourceGroup belongs to another app, so it is left as it is. Rename or remove it, then run this script again." }
|
|
285
|
+
if (-not $found) { Retry { az bot create -g $ResourceGroup -n $Bot --app-type SingleTenant --appid $app.appId --tenant-id $Tenant --endpoint (${psQuote(endpoint)} -f $app.appId) --sku F0 --display-name $Name | Out-Null } }
|
|
286
|
+
try { az bot msteams show -g $ResourceGroup -n $Bot 2>$null | Out-Null } catch { az bot msteams create -g $ResourceGroup -n $Bot | Out-Null }
|
|
287
|
+
|
|
288
|
+
# 3. The Teams app, published to your organization's app catalog.
|
|
289
|
+
$Manifest = @'
|
|
290
|
+
${template}
|
|
291
|
+
'@
|
|
292
|
+
Set-Content (Join-Path $Work "manifest.json") -Value $Manifest.Replace(${psQuote(PLACEHOLDER)}, $app.appId)
|
|
293
|
+
[IO.File]::WriteAllBytes((Join-Path $Work "color.png"), [Convert]::FromBase64String(${psQuote(colorIcon(input.displayName).toString("base64"))}))
|
|
294
|
+
[IO.File]::WriteAllBytes((Join-Path $Work "outline.png"), [Convert]::FromBase64String(${psQuote(outlineIcon(input.displayName).toString("base64"))}))
|
|
295
|
+
$Zip = Join-Path $Work "agent.zip"
|
|
296
|
+
Compress-Archive -Path (Join-Path $Work "manifest.json"), (Join-Path $Work "color.png"), (Join-Path $Work "outline.png") -DestinationPath $Zip
|
|
297
|
+
if ($Existing) { Set-TeamsApp -Id $Existing.Id -Path $Zip | Out-Null } else { New-TeamsApp -DistributionMethod organization -Path $Zip | Out-Null }
|
|
298
|
+
|
|
299
|
+
Write-Host ""
|
|
300
|
+
Write-Host "Done. Paste this application ID into ${brand().productName} before you add the bot to a team: $($app.appId)"
|
|
301
|
+
`;
|
|
302
|
+
}
|
|
303
|
+
/** What removes the bot from the customer's tenant again. `catalogOnly`: the service already
|
|
304
|
+
* deleted the rest, so only the Teams app (which needs a signed-in administrator) is left. */
|
|
305
|
+
export function removalScript(input) {
|
|
306
|
+
const lines = [
|
|
307
|
+
"# Removes the agent's Teams bot from your organization. Run in PowerShell 7.",
|
|
308
|
+
"# Or, without PowerShell: Teams admin center, Teams apps, Manage apps, open the app, Delete.",
|
|
309
|
+
'if ($IsWindows -or $PSVersionTable.PSEdition -eq "Desktop") { Connect-MicrosoftTeams } else { Connect-MicrosoftTeams -UseDeviceAuthentication }',
|
|
310
|
+
`Get-TeamsApp -ExternalId ${psQuote(input.teamsAppId)} | ForEach-Object { Remove-TeamsApp -Id $_.Id }`,
|
|
311
|
+
];
|
|
312
|
+
if (input.botAppId && !input.catalogOnly) {
|
|
313
|
+
// Only an app registration carrying this bot's unique name is the service's to delete.
|
|
314
|
+
const unique = `${brand().resourcePrefix}-bot-${input.botId}`;
|
|
315
|
+
lines.push(`$Made = az rest --method GET --uri ${psQuote(`https://graph.microsoft.com/v1.0/applications(appId='${input.botAppId}')?$select=uniqueName`)} --query uniqueName -o tsv`, `if ($Made -eq ${psQuote(unique)}) {`, ` az resource list --resource-type Microsoft.BotService/botServices --query "[?name=='${brand().resourcePrefix}-${input.botAppId.slice(0, 8)}'].id" -o tsv | ForEach-Object { if ((az resource show --ids $_ --query properties.msaAppId -o tsv) -eq ${psQuote(input.botAppId)}) { az resource delete --ids $_ } }`, ` az ad app delete --id ${input.botAppId}`, `} else { Write-Host "App registration ${input.botAppId} was not made by this bot's setup, so it is left as it is. Delete it and its Azure Bot yourself if they are the bot's." }`);
|
|
316
|
+
}
|
|
317
|
+
return lines.join("\n") + "\n";
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=package.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package.js","sourceRoot":"","sources":["../../../../../packages/server/src/teams/package.ts"],"names":[],"mappings":"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"}
|