@microsoft/teamsfx 0.3.3-alpha.3dc53ce2.0 → 0.3.3-alpha.7e7c7c23.0

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.
Files changed (68) hide show
  1. package/README.md +2 -2
  2. package/dist/index.esm2017.js +1413 -0
  3. package/dist/index.esm2017.js.map +1 -0
  4. package/dist/{index.js → index.esm2017.mjs} +1467 -1506
  5. package/dist/index.esm2017.mjs.map +1 -0
  6. package/dist/index.esm5.js +1575 -0
  7. package/dist/index.esm5.js.map +1 -0
  8. package/dist/index.node.cjs.js +1653 -0
  9. package/dist/index.node.cjs.js.map +1 -0
  10. package/package.json +58 -78
  11. package/types/teamsfx.d.ts +0 -2
  12. package/dist/index.js.map +0 -1
  13. package/dist/teamsfx.js +0 -30
  14. package/dist/teamsfx.js.map +0 -1
  15. package/dist-esm/src/bot/teamsBotSsoPrompt.browser.js +0 -118
  16. package/dist-esm/src/bot/teamsBotSsoPrompt.browser.js.map +0 -1
  17. package/dist-esm/src/bot/teamsBotSsoPrompt.js +0 -349
  18. package/dist-esm/src/bot/teamsBotSsoPrompt.js.map +0 -1
  19. package/dist-esm/src/bot/teamsBotSsoPromptTokenResponse.js +0 -2
  20. package/dist-esm/src/bot/teamsBotSsoPromptTokenResponse.js.map +0 -1
  21. package/dist-esm/src/core/cache.browser.js +0 -22
  22. package/dist-esm/src/core/cache.browser.js.map +0 -1
  23. package/dist-esm/src/core/cache.js +0 -28
  24. package/dist-esm/src/core/cache.js.map +0 -1
  25. package/dist-esm/src/core/configurationProvider.js +0 -124
  26. package/dist-esm/src/core/configurationProvider.js.map +0 -1
  27. package/dist-esm/src/core/defaultTediousConnectionConfiguration.browser.js +0 -28
  28. package/dist-esm/src/core/defaultTediousConnectionConfiguration.browser.js.map +0 -1
  29. package/dist-esm/src/core/defaultTediousConnectionConfiguration.js +0 -182
  30. package/dist-esm/src/core/defaultTediousConnectionConfiguration.js.map +0 -1
  31. package/dist-esm/src/core/errors.js +0 -97
  32. package/dist-esm/src/core/errors.js.map +0 -1
  33. package/dist-esm/src/core/msGraphAuthProvider.js +0 -68
  34. package/dist-esm/src/core/msGraphAuthProvider.js.map +0 -1
  35. package/dist-esm/src/core/msGraphClientProvider.js +0 -65
  36. package/dist-esm/src/core/msGraphClientProvider.js.map +0 -1
  37. package/dist-esm/src/credential/m365TenantCredential.browser.js +0 -38
  38. package/dist-esm/src/credential/m365TenantCredential.browser.js.map +0 -1
  39. package/dist-esm/src/credential/m365TenantCredential.js +0 -126
  40. package/dist-esm/src/credential/m365TenantCredential.js.map +0 -1
  41. package/dist-esm/src/credential/onBehalfOfUserCredential.browser.js +0 -46
  42. package/dist-esm/src/credential/onBehalfOfUserCredential.browser.js.map +0 -1
  43. package/dist-esm/src/credential/onBehalfOfUserCredential.js +0 -178
  44. package/dist-esm/src/credential/onBehalfOfUserCredential.js.map +0 -1
  45. package/dist-esm/src/credential/teamsUserCredential.browser.js +0 -462
  46. package/dist-esm/src/credential/teamsUserCredential.browser.js.map +0 -1
  47. package/dist-esm/src/credential/teamsUserCredential.js +0 -56
  48. package/dist-esm/src/credential/teamsUserCredential.js.map +0 -1
  49. package/dist-esm/src/index.js +0 -14
  50. package/dist-esm/src/index.js.map +0 -1
  51. package/dist-esm/src/models/accessTokenResult.js +0 -4
  52. package/dist-esm/src/models/accessTokenResult.js.map +0 -1
  53. package/dist-esm/src/models/authCodeResult.js +0 -4
  54. package/dist-esm/src/models/authCodeResult.js.map +0 -1
  55. package/dist-esm/src/models/configuration.js +0 -20
  56. package/dist-esm/src/models/configuration.js.map +0 -1
  57. package/dist-esm/src/models/grantType.js +0 -11
  58. package/dist-esm/src/models/grantType.js.map +0 -1
  59. package/dist-esm/src/models/ssoTokenInfo.js +0 -4
  60. package/dist-esm/src/models/ssoTokenInfo.js.map +0 -1
  61. package/dist-esm/src/models/userinfo.js +0 -4
  62. package/dist-esm/src/models/userinfo.js.map +0 -1
  63. package/dist-esm/src/util/logger.js +0 -134
  64. package/dist-esm/src/util/logger.js.map +0 -1
  65. package/dist-esm/src/util/utils.js +0 -130
  66. package/dist-esm/src/util/utils.js.map +0 -1
  67. package/dist-esm/src/util/utils.node.js +0 -23
  68. package/dist-esm/src/util/utils.node.js.map +0 -1
@@ -0,0 +1,1653 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var tslib = require('tslib');
6
+ var jwt_decode = require('jwt-decode');
7
+ var msalNode = require('@azure/msal-node');
8
+ var crypto = require('crypto');
9
+ var microsoftGraphClient = require('@microsoft/microsoft-graph-client');
10
+ var identity = require('@azure/identity');
11
+ var botbuilder = require('botbuilder');
12
+ var botbuilderDialogs = require('botbuilder-dialogs');
13
+ var uuid = require('uuid');
14
+
15
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
16
+
17
+ var jwt_decode__default = /*#__PURE__*/_interopDefaultLegacy(jwt_decode);
18
+
19
+ // Copyright (c) Microsoft Corporation.
20
+ /**
21
+ * Error code to trace the error types.
22
+ * @beta
23
+ */
24
+ exports.ErrorCode = void 0;
25
+ (function (ErrorCode) {
26
+ /**
27
+ * Invalid parameter error.
28
+ */
29
+ ErrorCode["InvalidParameter"] = "InvalidParameter";
30
+ /**
31
+ * Invalid configuration error.
32
+ */
33
+ ErrorCode["InvalidConfiguration"] = "InvalidConfiguration";
34
+ /**
35
+ * Invalid certificate error.
36
+ */
37
+ ErrorCode["InvalidCertificate"] = "InvalidCertificate";
38
+ /**
39
+ * Internal error.
40
+ */
41
+ ErrorCode["InternalError"] = "InternalError";
42
+ /**
43
+ * Channel is not supported error.
44
+ */
45
+ ErrorCode["ChannelNotSupported"] = "ChannelNotSupported";
46
+ /**
47
+ * Runtime is not supported error.
48
+ */
49
+ ErrorCode["RuntimeNotSupported"] = "RuntimeNotSupported";
50
+ /**
51
+ * User failed to finish the AAD consent flow failed.
52
+ */
53
+ ErrorCode["ConsentFailed"] = "ConsentFailed";
54
+ /**
55
+ * The user or administrator has not consented to use the application error.
56
+ */
57
+ ErrorCode["UiRequiredError"] = "UiRequiredError";
58
+ /**
59
+ * Token is not within its valid time range error.
60
+ */
61
+ ErrorCode["TokenExpiredError"] = "TokenExpiredError";
62
+ /**
63
+ * Call service (AAD or simple authentication server) failed.
64
+ */
65
+ ErrorCode["ServiceError"] = "ServiceError";
66
+ /**
67
+ * Operation failed.
68
+ */
69
+ ErrorCode["FailedOperation"] = "FailedOperation";
70
+ })(exports.ErrorCode || (exports.ErrorCode = {}));
71
+ /**
72
+ * @internal
73
+ */
74
+ var ErrorMessage = /** @class */ (function () {
75
+ function ErrorMessage() {
76
+ }
77
+ // InvalidConfiguration Error
78
+ ErrorMessage.InvalidConfiguration = "{0} in configuration is invalid: {1}.";
79
+ ErrorMessage.ConfigurationNotExists = "Configuration does not exist. {0}";
80
+ ErrorMessage.ResourceConfigurationNotExists = "{0} resource configuration does not exist.";
81
+ ErrorMessage.MissingResourceConfiguration = "Missing resource configuration with type: {0}, name: {1}.";
82
+ ErrorMessage.AuthenticationConfigurationNotExists = "Authentication configuration does not exist.";
83
+ // RuntimeNotSupported Error
84
+ ErrorMessage.BrowserRuntimeNotSupported = "{0} is not supported in browser.";
85
+ ErrorMessage.NodejsRuntimeNotSupported = "{0} is not supported in Node.";
86
+ // Internal Error
87
+ ErrorMessage.FailToAcquireTokenOnBehalfOfUser = "Failed to acquire access token on behalf of user: {0}";
88
+ // ChannelNotSupported Error
89
+ ErrorMessage.OnlyMSTeamsChannelSupported = "{0} is only supported in MS Teams Channel";
90
+ return ErrorMessage;
91
+ }());
92
+ /**
93
+ * Error class with code and message thrown by the SDK.
94
+ *
95
+ * @beta
96
+ */
97
+ var ErrorWithCode = /** @class */ (function (_super) {
98
+ tslib.__extends(ErrorWithCode, _super);
99
+ /**
100
+ * Constructor of ErrorWithCode.
101
+ *
102
+ * @param {string} message - error message.
103
+ * @param {ErrorCode} code - error code.
104
+ *
105
+ * @beta
106
+ */
107
+ function ErrorWithCode(message, code) {
108
+ var _newTarget = this.constructor;
109
+ var _this = this;
110
+ if (!code) {
111
+ _this = _super.call(this, message) || this;
112
+ return _this;
113
+ }
114
+ _this = _super.call(this, message) || this;
115
+ Object.setPrototypeOf(_this, ErrorWithCode.prototype);
116
+ _this.name = _newTarget.name + "." + code;
117
+ _this.code = code;
118
+ return _this;
119
+ }
120
+ return ErrorWithCode;
121
+ }(Error));
122
+
123
+ // Copyright (c) Microsoft Corporation.
124
+ // Licensed under the MIT license.
125
+ /**
126
+ * Available resource type.
127
+ * @beta
128
+ */
129
+ exports.ResourceType = void 0;
130
+ (function (ResourceType) {
131
+ /**
132
+ * SQL database.
133
+ *
134
+ */
135
+ ResourceType[ResourceType["SQL"] = 0] = "SQL";
136
+ /**
137
+ * Rest API.
138
+ *
139
+ */
140
+ ResourceType[ResourceType["API"] = 1] = "API";
141
+ })(exports.ResourceType || (exports.ResourceType = {}));
142
+
143
+ // Copyright (c) Microsoft Corporation.
144
+ // Licensed under the MIT license.
145
+ /**
146
+ * Log level.
147
+ *
148
+ * @beta
149
+ */
150
+ exports.LogLevel = void 0;
151
+ (function (LogLevel) {
152
+ /**
153
+ * Show verbose, information, warning and error message.
154
+ */
155
+ LogLevel[LogLevel["Verbose"] = 0] = "Verbose";
156
+ /**
157
+ * Show information, warning and error message.
158
+ */
159
+ LogLevel[LogLevel["Info"] = 1] = "Info";
160
+ /**
161
+ * Show warning and error message.
162
+ */
163
+ LogLevel[LogLevel["Warn"] = 2] = "Warn";
164
+ /**
165
+ * Show error message.
166
+ */
167
+ LogLevel[LogLevel["Error"] = 3] = "Error";
168
+ })(exports.LogLevel || (exports.LogLevel = {}));
169
+ /**
170
+ * Update log level helper.
171
+ *
172
+ * @param { LogLevel } level - log level in configuration
173
+ *
174
+ * @beta
175
+ */
176
+ function setLogLevel(level) {
177
+ internalLogger.level = level;
178
+ }
179
+ /**
180
+ * Get log level.
181
+ *
182
+ * @returns Log level
183
+ *
184
+ * @beta
185
+ */
186
+ function getLogLevel() {
187
+ return internalLogger.level;
188
+ }
189
+ var InternalLogger = /** @class */ (function () {
190
+ function InternalLogger() {
191
+ this.level = undefined;
192
+ this.defaultLogger = {
193
+ verbose: console.debug,
194
+ info: console.info,
195
+ warn: console.warn,
196
+ error: console.error,
197
+ };
198
+ }
199
+ InternalLogger.prototype.error = function (message) {
200
+ this.log(exports.LogLevel.Error, function (x) { return x.error; }, message);
201
+ };
202
+ InternalLogger.prototype.warn = function (message) {
203
+ this.log(exports.LogLevel.Warn, function (x) { return x.warn; }, message);
204
+ };
205
+ InternalLogger.prototype.info = function (message) {
206
+ this.log(exports.LogLevel.Info, function (x) { return x.info; }, message);
207
+ };
208
+ InternalLogger.prototype.verbose = function (message) {
209
+ this.log(exports.LogLevel.Verbose, function (x) { return x.verbose; }, message);
210
+ };
211
+ InternalLogger.prototype.log = function (logLevel, logFunction, message) {
212
+ if (message.trim() === "") {
213
+ return;
214
+ }
215
+ var timestamp = new Date().toUTCString();
216
+ var logHeader = "[" + timestamp + "] : @microsoft/teamsfx : " + exports.LogLevel[logLevel] + " - ";
217
+ var logMessage = "" + logHeader + message;
218
+ if (this.level !== undefined && this.level <= logLevel) {
219
+ if (this.customLogger) {
220
+ logFunction(this.customLogger)(logMessage);
221
+ }
222
+ else if (this.customLogFunction) {
223
+ this.customLogFunction(logLevel, logMessage);
224
+ }
225
+ else {
226
+ logFunction(this.defaultLogger)(logMessage);
227
+ }
228
+ }
229
+ };
230
+ return InternalLogger;
231
+ }());
232
+ /**
233
+ * Logger instance used internally
234
+ *
235
+ * @internal
236
+ */
237
+ var internalLogger = new InternalLogger();
238
+ /**
239
+ * Set custom logger. Use the output functions if it's set. Priority is higher than setLogFunction.
240
+ *
241
+ * @param {Logger} logger - custom logger. If it's undefined, custom logger will be cleared.
242
+ *
243
+ * @example
244
+ * ```typescript
245
+ * setLogger({
246
+ * verbose: console.debug,
247
+ * info: console.info,
248
+ * warn: console.warn,
249
+ * error: console.error,
250
+ * });
251
+ * ```
252
+ *
253
+ * @beta
254
+ */
255
+ function setLogger(logger) {
256
+ internalLogger.customLogger = logger;
257
+ }
258
+ /**
259
+ * Set custom log function. Use the function if it's set. Priority is lower than setLogger.
260
+ *
261
+ * @param {LogFunction} logFunction - custom log function. If it's undefined, custom log function will be cleared.
262
+ *
263
+ * @example
264
+ * ```typescript
265
+ * setLogFunction((level: LogLevel, message: string) => {
266
+ * if (level === LogLevel.Error) {
267
+ * console.log(message);
268
+ * }
269
+ * });
270
+ * ```
271
+ *
272
+ * @beta
273
+ */
274
+ function setLogFunction(logFunction) {
275
+ internalLogger.customLogFunction = logFunction;
276
+ }
277
+
278
+ // Copyright (c) Microsoft Corporation.
279
+ /**
280
+ * Parse jwt token payload
281
+ *
282
+ * @param token
283
+ *
284
+ * @returns Payload object
285
+ *
286
+ * @internal
287
+ */
288
+ function parseJwt(token) {
289
+ try {
290
+ var tokenObj = jwt_decode__default["default"](token);
291
+ if (!tokenObj || !tokenObj.exp) {
292
+ throw new ErrorWithCode("Decoded token is null or exp claim does not exists.", exports.ErrorCode.InternalError);
293
+ }
294
+ return tokenObj;
295
+ }
296
+ catch (err) {
297
+ var errorMsg = "Parse jwt token failed in node env with error: " + err.message;
298
+ internalLogger.error(errorMsg);
299
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.InternalError);
300
+ }
301
+ }
302
+ /**
303
+ * @internal
304
+ */
305
+ function getUserInfoFromSsoToken(ssoToken) {
306
+ if (!ssoToken) {
307
+ var errorMsg = "SSO token is undefined.";
308
+ internalLogger.error(errorMsg);
309
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.InvalidParameter);
310
+ }
311
+ var tokenObject = parseJwt(ssoToken);
312
+ var userInfo = {
313
+ displayName: tokenObject.name,
314
+ objectId: tokenObject.oid,
315
+ preferredUserName: "",
316
+ };
317
+ if (tokenObject.ver === "2.0") {
318
+ userInfo.preferredUserName = tokenObject.preferred_username;
319
+ }
320
+ else if (tokenObject.ver === "1.0") {
321
+ userInfo.preferredUserName = tokenObject.upn;
322
+ }
323
+ return userInfo;
324
+ }
325
+ /**
326
+ * Format string template with replacements
327
+ *
328
+ * ```typescript
329
+ * const template = "{0} and {1} are fruit. {0} is my favorite one."
330
+ * const formattedStr = formatString(template, "apple", "pear"); // formattedStr: "apple and pear are fruit. apple is my favorite one."
331
+ * ```
332
+ *
333
+ * @param str string template
334
+ * @param replacements replacement string array
335
+ * @returns Formatted string
336
+ *
337
+ * @internal
338
+ */
339
+ function formatString(str) {
340
+ var replacements = [];
341
+ for (var _i = 1; _i < arguments.length; _i++) {
342
+ replacements[_i - 1] = arguments[_i];
343
+ }
344
+ var args = replacements;
345
+ return str.replace(/{(\d+)}/g, function (match, number) {
346
+ return typeof args[number] != "undefined" ? args[number] : match;
347
+ });
348
+ }
349
+ /**
350
+ * @internal
351
+ */
352
+ function validateScopesType(value) {
353
+ // string
354
+ if (typeof value === "string" || value instanceof String) {
355
+ return;
356
+ }
357
+ // empty array
358
+ if (Array.isArray(value) && value.length === 0) {
359
+ return;
360
+ }
361
+ // string array
362
+ if (Array.isArray(value) && value.length > 0 && value.every(function (item) { return typeof item === "string"; })) {
363
+ return;
364
+ }
365
+ var errorMsg = "The type of scopes is not valid, it must be string or string array";
366
+ internalLogger.error(errorMsg);
367
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.InvalidParameter);
368
+ }
369
+ /**
370
+ * @internal
371
+ */
372
+ function getScopesArray(scopes) {
373
+ var scopesArray = typeof scopes === "string" ? scopes.split(" ") : scopes;
374
+ return scopesArray.filter(function (x) { return x !== null && x !== ""; });
375
+ }
376
+ /**
377
+ * @internal
378
+ */
379
+ function getAuthority(authorityHost, tenantId) {
380
+ var normalizedAuthorityHost = authorityHost.replace(/\/+$/g, "");
381
+ return normalizedAuthorityHost + "/" + tenantId;
382
+ }
383
+ /**
384
+ * @internal
385
+ */
386
+ var isNode = typeof process !== "undefined" &&
387
+ !!process.version &&
388
+ !!process.versions &&
389
+ !!process.versions.node;
390
+
391
+ // Copyright (c) Microsoft Corporation.
392
+ /**
393
+ * Global configuration instance
394
+ *
395
+ */
396
+ var config;
397
+ /**
398
+ * Initialize configuration from environment variables or configuration object and set the global instance
399
+ *
400
+ * @param {Configuration} configuration - Optional configuration that overrides the default configuration values. The override depth is 1.
401
+ *
402
+ * @throws {@link ErrorCode|InvalidParameter} when configuration is not passed in browser environment
403
+ *
404
+ * @beta
405
+ */
406
+ function loadConfiguration(configuration) {
407
+ internalLogger.info("load configuration");
408
+ // browser environment
409
+ if (!isNode) {
410
+ if (!configuration) {
411
+ var errorMsg = "You are running the code in browser. Configuration must be passed in.";
412
+ internalLogger.error(errorMsg);
413
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.InvalidParameter);
414
+ }
415
+ config = configuration;
416
+ return;
417
+ }
418
+ // node environment
419
+ var newAuthentication;
420
+ var newResources = [];
421
+ var defaultResourceName = "default";
422
+ if (configuration === null || configuration === void 0 ? void 0 : configuration.authentication) {
423
+ newAuthentication = configuration.authentication;
424
+ }
425
+ else {
426
+ newAuthentication = {
427
+ authorityHost: process.env.M365_AUTHORITY_HOST,
428
+ tenantId: process.env.M365_TENANT_ID,
429
+ clientId: process.env.M365_CLIENT_ID,
430
+ clientSecret: process.env.M365_CLIENT_SECRET,
431
+ simpleAuthEndpoint: process.env.SIMPLE_AUTH_ENDPOINT,
432
+ initiateLoginEndpoint: process.env.INITIATE_LOGIN_ENDPOINT,
433
+ applicationIdUri: process.env.M365_APPLICATION_ID_URI,
434
+ };
435
+ }
436
+ if (configuration === null || configuration === void 0 ? void 0 : configuration.resources) {
437
+ newResources = configuration.resources;
438
+ }
439
+ else {
440
+ newResources = [
441
+ {
442
+ // SQL resource
443
+ type: exports.ResourceType.SQL,
444
+ name: defaultResourceName,
445
+ properties: {
446
+ sqlServerEndpoint: process.env.SQL_ENDPOINT,
447
+ sqlUsername: process.env.SQL_USER_NAME,
448
+ sqlPassword: process.env.SQL_PASSWORD,
449
+ sqlDatabaseName: process.env.SQL_DATABASE_NAME,
450
+ sqlIdentityId: process.env.IDENTITY_ID,
451
+ },
452
+ },
453
+ {
454
+ // API resource
455
+ type: exports.ResourceType.API,
456
+ name: defaultResourceName,
457
+ properties: {
458
+ endpoint: process.env.API_ENDPOINT,
459
+ },
460
+ },
461
+ ];
462
+ }
463
+ config = {
464
+ authentication: newAuthentication,
465
+ resources: newResources,
466
+ };
467
+ }
468
+ /**
469
+ * Get configuration for a specific resource.
470
+ * @param {ResourceType} resourceType - The type of resource
471
+ * @param {string} resourceName - The name of resource, default value is "default".
472
+ *
473
+ * @returns Resource configuration for target resource from global configuration instance.
474
+ *
475
+ * @throws {@link ErrorCode|InvalidConfiguration} when resource configuration with the specific type and name is not found
476
+ *
477
+ * @beta
478
+ */
479
+ function getResourceConfiguration(resourceType, resourceName) {
480
+ var _a;
481
+ if (resourceName === void 0) { resourceName = "default"; }
482
+ internalLogger.info("Get resource configuration of " + exports.ResourceType[resourceType] + " from " + resourceName);
483
+ var result = (_a = config.resources) === null || _a === void 0 ? void 0 : _a.find(function (item) { return item.type === resourceType && item.name === resourceName; });
484
+ if (result) {
485
+ return result.properties;
486
+ }
487
+ var errorMsg = formatString(ErrorMessage.MissingResourceConfiguration, exports.ResourceType[resourceType], resourceName);
488
+ internalLogger.error(errorMsg);
489
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.InvalidConfiguration);
490
+ }
491
+ /**
492
+ * Get configuration for authentication.
493
+ *
494
+ * @returns Authentication configuration from global configuration instance, the value may be undefined if no authentication config exists in current environment.
495
+ *
496
+ * @throws {@link ErrorCode|InvalidConfiguration} when global configuration does not exist
497
+ *
498
+ * @beta
499
+ */
500
+ function getAuthenticationConfiguration() {
501
+ internalLogger.info("Get authentication configuration");
502
+ if (config) {
503
+ return config.authentication;
504
+ }
505
+ var errorMsg = "Please call loadConfiguration() first before calling getAuthenticationConfiguration().";
506
+ internalLogger.error(errorMsg);
507
+ throw new ErrorWithCode(formatString(ErrorMessage.ConfigurationNotExists, errorMsg), exports.ErrorCode.InvalidConfiguration);
508
+ }
509
+
510
+ /**
511
+ * @internal
512
+ */
513
+ function createConfidentialClientApplication(authentication) {
514
+ var authority = getAuthority(authentication.authorityHost, authentication.tenantId);
515
+ var clientCertificate = parseCertificate(authentication.certificateContent);
516
+ var auth = {
517
+ clientId: authentication.clientId,
518
+ authority: authority,
519
+ };
520
+ if (clientCertificate) {
521
+ auth.clientCertificate = clientCertificate;
522
+ }
523
+ else {
524
+ auth.clientSecret = authentication.clientSecret;
525
+ }
526
+ return new msalNode.ConfidentialClientApplication({
527
+ auth: auth,
528
+ });
529
+ }
530
+ /**
531
+ * @internal
532
+ */
533
+ function parseCertificate(certificateContent) {
534
+ if (!certificateContent) {
535
+ return undefined;
536
+ }
537
+ var certificatePattern = /(-+BEGIN CERTIFICATE-+)(\n\r?|\r\n?)([A-Za-z0-9+/\n\r]+=*)(\n\r?|\r\n?)(-+END CERTIFICATE-+)/;
538
+ var match = certificatePattern.exec(certificateContent);
539
+ if (!match) {
540
+ var errorMsg = "The certificate content does not contain a PEM-encoded certificate.";
541
+ internalLogger.error(errorMsg);
542
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.InvalidCertificate);
543
+ }
544
+ var thumbprint = crypto.createHash("sha1")
545
+ .update(Buffer.from(match[3], "base64"))
546
+ .digest("hex")
547
+ .toUpperCase();
548
+ return {
549
+ thumbprint: thumbprint,
550
+ privateKey: certificateContent,
551
+ };
552
+ }
553
+
554
+ // Copyright (c) Microsoft Corporation.
555
+ /**
556
+ * Represent Microsoft 365 tenant identity, and it is usually used when user is not involved like time-triggered automation job.
557
+ *
558
+ * @example
559
+ * ```typescript
560
+ * loadConfiguration(); // load configuration from environment variables
561
+ * const credential = new M365TenantCredential();
562
+ * ```
563
+ *
564
+ * @remarks
565
+ * Only works in in server side.
566
+ *
567
+ * @beta
568
+ */
569
+ var M365TenantCredential = /** @class */ (function () {
570
+ /**
571
+ * Constructor of M365TenantCredential.
572
+ *
573
+ * @remarks
574
+ * Only works in in server side.
575
+ *
576
+ * @throws {@link ErrorCode|InvalidConfiguration} when client id, client secret or tenant id is not found in config.
577
+ * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is nodeJS.
578
+ *
579
+ * @beta
580
+ */
581
+ function M365TenantCredential() {
582
+ internalLogger.info("Create M365 tenant credential");
583
+ var config = this.loadAndValidateConfig();
584
+ this.msalClient = createConfidentialClientApplication(config);
585
+ }
586
+ /**
587
+ * Get access token for credential.
588
+ *
589
+ * @example
590
+ * ```typescript
591
+ * await credential.getToken(["User.Read.All"]) // Get Graph access token for single scope using string array
592
+ * await credential.getToken("User.Read.All") // Get Graph access token for single scope using string
593
+ * await credential.getToken(["User.Read.All", "Calendars.Read"]) // Get Graph access token for multiple scopes using string array
594
+ * await credential.getToken("User.Read.All Calendars.Read") // Get Graph access token for multiple scopes using space-separated string
595
+ * await credential.getToken("https://graph.microsoft.com/User.Read.All") // Get Graph access token with full resource URI
596
+ * await credential.getToken(["https://outlook.office.com/Mail.Read"]) // Get Outlook access token
597
+ * ```
598
+ *
599
+ * @param {string | string[]} scopes - The list of scopes for which the token will have access.
600
+ * @param {GetTokenOptions} options - The options used to configure any requests this TokenCredential implementation might make.
601
+ *
602
+ * @throws {@link ErrorCode|ServiceError} when get access token with authentication error.
603
+ * @throws {@link ErrorCode|InternalError} when get access token with unknown error.
604
+ * @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
605
+ * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is nodeJS.
606
+ *
607
+ * @returns Access token with expected scopes.
608
+ * Throw error if get access token failed.
609
+ *
610
+ * @beta
611
+ */
612
+ M365TenantCredential.prototype.getToken = function (scopes, options) {
613
+ return tslib.__awaiter(this, void 0, void 0, function () {
614
+ var accessToken, scopesStr, scopesArray, authenticationResult, err_1, errorMsg, errorMsg;
615
+ return tslib.__generator(this, function (_a) {
616
+ switch (_a.label) {
617
+ case 0:
618
+ validateScopesType(scopes);
619
+ scopesStr = typeof scopes === "string" ? scopes : scopes.join(" ");
620
+ internalLogger.info("Get access token with scopes: " + scopesStr);
621
+ _a.label = 1;
622
+ case 1:
623
+ _a.trys.push([1, 3, , 4]);
624
+ scopesArray = getScopesArray(scopes);
625
+ return [4 /*yield*/, this.msalClient.acquireTokenByClientCredential({
626
+ scopes: scopesArray,
627
+ })];
628
+ case 2:
629
+ authenticationResult = _a.sent();
630
+ if (authenticationResult) {
631
+ accessToken = {
632
+ token: authenticationResult.accessToken,
633
+ expiresOnTimestamp: authenticationResult.expiresOn.getTime(),
634
+ };
635
+ }
636
+ return [3 /*break*/, 4];
637
+ case 3:
638
+ err_1 = _a.sent();
639
+ errorMsg = "Get M365 tenant credential failed with error: " + err_1.message;
640
+ internalLogger.error(errorMsg);
641
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.ServiceError);
642
+ case 4:
643
+ if (!accessToken) {
644
+ errorMsg = "Get M365 tenant credential access token failed with empty access token";
645
+ internalLogger.error(errorMsg);
646
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.InternalError);
647
+ }
648
+ return [2 /*return*/, accessToken];
649
+ }
650
+ });
651
+ });
652
+ };
653
+ /**
654
+ * Load and validate authentication configuration
655
+ * @returns Authentication configuration
656
+ */
657
+ M365TenantCredential.prototype.loadAndValidateConfig = function () {
658
+ internalLogger.verbose("Validate authentication configuration");
659
+ var config = getAuthenticationConfiguration();
660
+ if (!config) {
661
+ internalLogger.error(ErrorMessage.AuthenticationConfigurationNotExists);
662
+ throw new ErrorWithCode(ErrorMessage.AuthenticationConfigurationNotExists, exports.ErrorCode.InvalidConfiguration);
663
+ }
664
+ if (config.clientId && (config.clientSecret || config.certificateContent) && config.tenantId) {
665
+ return config;
666
+ }
667
+ var missingValues = [];
668
+ if (!config.clientId) {
669
+ missingValues.push("clientId");
670
+ }
671
+ if (!config.clientSecret && !config.certificateContent) {
672
+ missingValues.push("clientSecret or certificateContent");
673
+ }
674
+ if (!config.tenantId) {
675
+ missingValues.push("tenantId");
676
+ }
677
+ var errorMsg = formatString(ErrorMessage.InvalidConfiguration, missingValues.join(", "), "undefined");
678
+ internalLogger.error(errorMsg);
679
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.InvalidConfiguration);
680
+ };
681
+ return M365TenantCredential;
682
+ }());
683
+
684
+ // Copyright (c) Microsoft Corporation.
685
+ /**
686
+ * Represent on-behalf-of flow to get user identity, and it is designed to be used in server side.
687
+ *
688
+ * @example
689
+ * ```typescript
690
+ * loadConfiguration(); // load configuration from environment variables
691
+ * const credential = new OnBehalfOfUserCredential(ssoToken);
692
+ * ```
693
+ *
694
+ * @remarks
695
+ * Can only be used in server side.
696
+ *
697
+ * @beta
698
+ */
699
+ var OnBehalfOfUserCredential = /** @class */ (function () {
700
+ /**
701
+ * Constructor of OnBehalfOfUserCredential
702
+ *
703
+ * @remarks
704
+ * Only works in in server side.
705
+ *
706
+ * @param {string} ssoToken - User token provided by Teams SSO feature.
707
+ *
708
+ * @throws {@link ErrorCode|InvalidConfiguration} when client id, client secret, certificate content, authority host or tenant id is not found in config.
709
+ * @throws {@link ErrorCode|InternalError} when SSO token is not valid.
710
+ * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
711
+ *
712
+ * @beta
713
+ */
714
+ function OnBehalfOfUserCredential(ssoToken) {
715
+ var _a, _b, _c, _d, _e;
716
+ internalLogger.info("Get on behalf of user credential");
717
+ var missingConfigurations = [];
718
+ if (!((_a = config === null || config === void 0 ? void 0 : config.authentication) === null || _a === void 0 ? void 0 : _a.clientId)) {
719
+ missingConfigurations.push("clientId");
720
+ }
721
+ if (!((_b = config === null || config === void 0 ? void 0 : config.authentication) === null || _b === void 0 ? void 0 : _b.authorityHost)) {
722
+ missingConfigurations.push("authorityHost");
723
+ }
724
+ if (!((_c = config === null || config === void 0 ? void 0 : config.authentication) === null || _c === void 0 ? void 0 : _c.clientSecret) && !((_d = config === null || config === void 0 ? void 0 : config.authentication) === null || _d === void 0 ? void 0 : _d.certificateContent)) {
725
+ missingConfigurations.push("clientSecret or certificateContent");
726
+ }
727
+ if (!((_e = config === null || config === void 0 ? void 0 : config.authentication) === null || _e === void 0 ? void 0 : _e.tenantId)) {
728
+ missingConfigurations.push("tenantId");
729
+ }
730
+ if (missingConfigurations.length != 0) {
731
+ var errorMsg = formatString(ErrorMessage.InvalidConfiguration, missingConfigurations.join(", "), "undefined");
732
+ internalLogger.error(errorMsg);
733
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.InvalidConfiguration);
734
+ }
735
+ this.msalClient = createConfidentialClientApplication(config.authentication);
736
+ var decodedSsoToken = parseJwt(ssoToken);
737
+ this.ssoToken = {
738
+ token: ssoToken,
739
+ expiresOnTimestamp: decodedSsoToken.exp,
740
+ };
741
+ }
742
+ /**
743
+ * Get access token from credential.
744
+ *
745
+ * @example
746
+ * ```typescript
747
+ * await credential.getToken([]) // Get SSO token using empty string array
748
+ * await credential.getToken("") // Get SSO token using empty string
749
+ * await credential.getToken([".default"]) // Get Graph access token with default scope using string array
750
+ * await credential.getToken(".default") // Get Graph access token with default scope using string
751
+ * await credential.getToken(["User.Read"]) // Get Graph access token for single scope using string array
752
+ * await credential.getToken("User.Read") // Get Graph access token for single scope using string
753
+ * await credential.getToken(["User.Read", "Application.Read.All"]) // Get Graph access token for multiple scopes using string array
754
+ * await credential.getToken("User.Read Application.Read.All") // Get Graph access token for multiple scopes using space-separated string
755
+ * await credential.getToken("https://graph.microsoft.com/User.Read") // Get Graph access token with full resource URI
756
+ * await credential.getToken(["https://outlook.office.com/Mail.Read"]) // Get Outlook access token
757
+ * ```
758
+ *
759
+ * @param {string | string[]} scopes - The list of scopes for which the token will have access.
760
+ * @param {GetTokenOptions} options - The options used to configure any requests this TokenCredential implementation might make.
761
+ *
762
+ * @throws {@link ErrorCode|InternalError} when failed to acquire access token on behalf of user with unknown error.
763
+ * @throws {@link ErrorCode|TokenExpiredError} when SSO token has already expired.
764
+ * @throws {@link ErrorCode|UiRequiredError} when need user consent to get access token.
765
+ * @throws {@link ErrorCode|ServiceError} when failed to get access token from simple auth server.
766
+ * @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
767
+ * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
768
+ *
769
+ * @returns Access token with expected scopes.
770
+ *
771
+ * @remarks
772
+ * If scopes is empty string or array, it returns SSO token.
773
+ * If scopes is non-empty, it returns access token for target scope.
774
+ *
775
+ * @beta
776
+ */
777
+ OnBehalfOfUserCredential.prototype.getToken = function (scopes, options) {
778
+ return tslib.__awaiter(this, void 0, void 0, function () {
779
+ var scopesArray, result, errorMsg, authenticationResult, error_1, errorMsg;
780
+ return tslib.__generator(this, function (_a) {
781
+ switch (_a.label) {
782
+ case 0:
783
+ validateScopesType(scopes);
784
+ scopesArray = getScopesArray(scopes);
785
+ if (!!scopesArray.length) return [3 /*break*/, 1];
786
+ internalLogger.info("Get SSO token.");
787
+ if (Math.floor(Date.now() / 1000) > this.ssoToken.expiresOnTimestamp) {
788
+ errorMsg = "Sso token has already expired.";
789
+ internalLogger.error(errorMsg);
790
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.TokenExpiredError);
791
+ }
792
+ result = this.ssoToken;
793
+ return [3 /*break*/, 6];
794
+ case 1:
795
+ internalLogger.info("Get access token with scopes: " + scopesArray.join(" "));
796
+ authenticationResult = void 0;
797
+ _a.label = 2;
798
+ case 2:
799
+ _a.trys.push([2, 4, , 5]);
800
+ return [4 /*yield*/, this.msalClient.acquireTokenOnBehalfOf({
801
+ oboAssertion: this.ssoToken.token,
802
+ scopes: scopesArray,
803
+ })];
804
+ case 3:
805
+ authenticationResult = _a.sent();
806
+ return [3 /*break*/, 5];
807
+ case 4:
808
+ error_1 = _a.sent();
809
+ throw this.generateAuthServerError(error_1);
810
+ case 5:
811
+ if (!authenticationResult) {
812
+ errorMsg = "Access token is null";
813
+ internalLogger.error(errorMsg);
814
+ throw new ErrorWithCode(formatString(ErrorMessage.FailToAcquireTokenOnBehalfOfUser, errorMsg), exports.ErrorCode.InternalError);
815
+ }
816
+ result = {
817
+ token: authenticationResult.accessToken,
818
+ expiresOnTimestamp: authenticationResult.expiresOn.getTime(),
819
+ };
820
+ _a.label = 6;
821
+ case 6: return [2 /*return*/, result];
822
+ }
823
+ });
824
+ });
825
+ };
826
+ /**
827
+ * Get basic user info from SSO token.
828
+ *
829
+ * @example
830
+ * ```typescript
831
+ * const currentUser = getUserInfo();
832
+ * ```
833
+ *
834
+ * @throws {@link ErrorCode|InternalError} when SSO token is not valid.
835
+ * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
836
+ *
837
+ * @returns Basic user info with user displayName, objectId and preferredUserName.
838
+ *
839
+ * @beta
840
+ */
841
+ OnBehalfOfUserCredential.prototype.getUserInfo = function () {
842
+ internalLogger.info("Get basic user info from SSO token");
843
+ return getUserInfoFromSsoToken(this.ssoToken.token);
844
+ };
845
+ OnBehalfOfUserCredential.prototype.generateAuthServerError = function (err) {
846
+ var errorMessage = err.errorMessage;
847
+ if (err.name === "InteractionRequiredAuthError") {
848
+ var fullErrorMsg = "Failed to get access token from AAD server, interaction required: " + errorMessage;
849
+ internalLogger.warn(fullErrorMsg);
850
+ return new ErrorWithCode(fullErrorMsg, exports.ErrorCode.UiRequiredError);
851
+ }
852
+ else if (errorMessage && errorMessage.indexOf("AADSTS500133") >= 0) {
853
+ var fullErrorMsg = "Failed to get access token from AAD server, sso token expired: " + errorMessage;
854
+ internalLogger.error(fullErrorMsg);
855
+ return new ErrorWithCode(fullErrorMsg, exports.ErrorCode.TokenExpiredError);
856
+ }
857
+ else {
858
+ var fullErrorMsg = formatString(ErrorMessage.FailToAcquireTokenOnBehalfOfUser, errorMessage);
859
+ internalLogger.error(fullErrorMsg);
860
+ return new ErrorWithCode(fullErrorMsg, exports.ErrorCode.ServiceError);
861
+ }
862
+ };
863
+ return OnBehalfOfUserCredential;
864
+ }());
865
+
866
+ // Copyright (c) Microsoft Corporation.
867
+ /**
868
+ * Represent Teams current user's identity, and it is used within Teams client applications.
869
+ *
870
+ * @remarks
871
+ * Can only be used within Teams.
872
+ *
873
+ * @beta
874
+ */
875
+ var TeamsUserCredential = /** @class */ (function () {
876
+ /**
877
+ * Constructor of TeamsUserCredential.
878
+ * @remarks
879
+ * Can only be used within Teams.
880
+ * @beta
881
+ */
882
+ function TeamsUserCredential() {
883
+ throw new ErrorWithCode(formatString(ErrorMessage.NodejsRuntimeNotSupported, "TeamsUserCredential"), exports.ErrorCode.RuntimeNotSupported);
884
+ }
885
+ /**
886
+ * Popup login page to get user's access token with specific scopes.
887
+ * @remarks
888
+ * Can only be used within Teams.
889
+ * @beta
890
+ */
891
+ TeamsUserCredential.prototype.login = function (scopes) {
892
+ return tslib.__awaiter(this, void 0, void 0, function () {
893
+ return tslib.__generator(this, function (_a) {
894
+ throw new ErrorWithCode(formatString(ErrorMessage.NodejsRuntimeNotSupported, "TeamsUserCredential"), exports.ErrorCode.RuntimeNotSupported);
895
+ });
896
+ });
897
+ };
898
+ /**
899
+ * Get access token from credential.
900
+ * @remarks
901
+ * Can only be used within Teams.
902
+ * @beta
903
+ */
904
+ TeamsUserCredential.prototype.getToken = function (scopes, options) {
905
+ return tslib.__awaiter(this, void 0, void 0, function () {
906
+ return tslib.__generator(this, function (_a) {
907
+ throw new ErrorWithCode(formatString(ErrorMessage.NodejsRuntimeNotSupported, "TeamsUserCredential"), exports.ErrorCode.RuntimeNotSupported);
908
+ });
909
+ });
910
+ };
911
+ /**
912
+ * Get basic user info from SSO token
913
+ * @remarks
914
+ * Can only be used within Teams.
915
+ * @beta
916
+ */
917
+ TeamsUserCredential.prototype.getUserInfo = function () {
918
+ throw new ErrorWithCode(formatString(ErrorMessage.NodejsRuntimeNotSupported, "TeamsUserCredential"), exports.ErrorCode.RuntimeNotSupported);
919
+ };
920
+ return TeamsUserCredential;
921
+ }());
922
+
923
+ // Copyright (c) Microsoft Corporation.
924
+ var defaultScope = "https://graph.microsoft.com/.default";
925
+ /**
926
+ * Microsoft Graph auth provider for Teams Framework
927
+ *
928
+ * @beta
929
+ */
930
+ var MsGraphAuthProvider = /** @class */ (function () {
931
+ /**
932
+ * Constructor of MsGraphAuthProvider.
933
+ *
934
+ * @param {TokenCredential} credential - Credential used to invoke Microsoft Graph APIs.
935
+ * @param {string | string[]} scopes - The list of scopes for which the token will have access.
936
+ *
937
+ * @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
938
+ *
939
+ * @returns An instance of MsGraphAuthProvider.
940
+ *
941
+ * @beta
942
+ */
943
+ function MsGraphAuthProvider(credential, scopes) {
944
+ this.credential = credential;
945
+ var scopesStr = defaultScope;
946
+ if (scopes) {
947
+ validateScopesType(scopes);
948
+ scopesStr = typeof scopes === "string" ? scopes : scopes.join(" ");
949
+ if (scopesStr === "") {
950
+ scopesStr = defaultScope;
951
+ }
952
+ }
953
+ internalLogger.info("Create Microsoft Graph Authentication Provider with scopes: '" + scopesStr + "'");
954
+ this.scopes = scopesStr;
955
+ }
956
+ /**
957
+ * Get access token for Microsoft Graph API requests.
958
+ *
959
+ * @throws {@link ErrorCode|InternalError} when get access token failed due to empty token or unknown other problems.
960
+ * @throws {@link ErrorCode|TokenExpiredError} when SSO token has already expired.
961
+ * @throws {@link ErrorCode|UiRequiredError} when need user consent to get access token.
962
+ * @throws {@link ErrorCode|ServiceError} when failed to get access token from simple auth or AAD server.
963
+ * @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
964
+ *
965
+ * @returns Access token from the credential.
966
+ *
967
+ */
968
+ MsGraphAuthProvider.prototype.getAccessToken = function () {
969
+ return tslib.__awaiter(this, void 0, void 0, function () {
970
+ var accessToken;
971
+ return tslib.__generator(this, function (_a) {
972
+ switch (_a.label) {
973
+ case 0:
974
+ internalLogger.info("Get Graph Access token with scopes: '" + this.scopes + "'");
975
+ return [4 /*yield*/, this.credential.getToken(this.scopes)];
976
+ case 1:
977
+ accessToken = _a.sent();
978
+ return [2 /*return*/, new Promise(function (resolve, reject) {
979
+ if (accessToken) {
980
+ resolve(accessToken.token);
981
+ }
982
+ else {
983
+ var errorMsg = "Graph access token is undefined or empty";
984
+ internalLogger.error(errorMsg);
985
+ reject(new ErrorWithCode(errorMsg, exports.ErrorCode.InternalError));
986
+ }
987
+ })];
988
+ }
989
+ });
990
+ });
991
+ };
992
+ return MsGraphAuthProvider;
993
+ }());
994
+
995
+ // Copyright (c) Microsoft Corporation.
996
+ /**
997
+ * Get Microsoft graph client.
998
+ *
999
+ * @example
1000
+ * Get Microsoft graph client by TokenCredential
1001
+ * ```typescript
1002
+ * // Sso token example (Azure Function)
1003
+ * const ssoToken = "YOUR_TOKEN_STRING";
1004
+ * const options = {"AAD_APP_ID", "AAD_APP_SECRET"};
1005
+ * const credential = new OnBehalfOfAADUserCredential(ssoToken, options);
1006
+ * const graphClient = await createMicrosoftGraphClient(credential);
1007
+ * const profile = await graphClient.api("/me").get();
1008
+ *
1009
+ * // TeamsBotSsoPrompt example (Bot Application)
1010
+ * const requiredScopes = ["User.Read"];
1011
+ * const config: Configuration = {
1012
+ * loginUrl: loginUrl,
1013
+ * clientId: clientId,
1014
+ * clientSecret: clientSecret,
1015
+ * tenantId: tenantId
1016
+ * };
1017
+ * const prompt = new TeamsBotSsoPrompt(dialogId, {
1018
+ * config: config
1019
+ * scopes: '["User.Read"],
1020
+ * });
1021
+ * this.addDialog(prompt);
1022
+ *
1023
+ * const oboCredential = new OnBehalfOfAADUserCredential(
1024
+ * getUserId(dialogContext),
1025
+ * {
1026
+ * clientId: "AAD_APP_ID",
1027
+ * clientSecret: "AAD_APP_SECRET"
1028
+ * });
1029
+ * try {
1030
+ * const graphClient = await createMicrosoftGraphClient(credential);
1031
+ * const profile = await graphClient.api("/me").get();
1032
+ * } catch (e) {
1033
+ * dialogContext.beginDialog(dialogId);
1034
+ * return Dialog.endOfTurn();
1035
+ * }
1036
+ * ```
1037
+ *
1038
+ * @param {TokenCredential} credential - token credential instance.
1039
+ * @param scopes - The array of Microsoft Token scope of access. Default value is `[.default]`.
1040
+ *
1041
+ * @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
1042
+ *
1043
+ * @returns Graph client with specified scopes.
1044
+ *
1045
+ * @beta
1046
+ */
1047
+ function createMicrosoftGraphClient(credential, scopes) {
1048
+ internalLogger.info("Create Microsoft Graph Client");
1049
+ var authProvider = new MsGraphAuthProvider(credential, scopes);
1050
+ var graphClient = microsoftGraphClient.Client.initWithMiddleware({
1051
+ authProvider: authProvider,
1052
+ });
1053
+ return graphClient;
1054
+ }
1055
+
1056
+ // Copyright (c) Microsoft Corporation.
1057
+ /**
1058
+ * SQL connection configuration instance.
1059
+ * @remarks
1060
+ * Only works in in server side.
1061
+ *
1062
+ * @beta
1063
+ *
1064
+ */
1065
+ var DefaultTediousConnectionConfiguration = /** @class */ (function () {
1066
+ function DefaultTediousConnectionConfiguration() {
1067
+ /**
1068
+ * MSSQL default scope
1069
+ * https://docs.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-connect-msi
1070
+ */
1071
+ this.defaultSQLScope = "https://database.windows.net/";
1072
+ }
1073
+ /**
1074
+ * Generate connection configuration consumed by tedious.
1075
+ *
1076
+ * @returns Connection configuration of tedious for the SQL.
1077
+ *
1078
+ * @throws {@link ErrorCode|InvalidConfiguration} when SQL config resource configuration is invalid.
1079
+ * @throws {@link ErrorCode|InternalError} when get user MSI token failed or MSI token is invalid.
1080
+ * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
1081
+ *
1082
+ * @beta
1083
+ */
1084
+ DefaultTediousConnectionConfiguration.prototype.getConfig = function () {
1085
+ return tslib.__awaiter(this, void 0, void 0, function () {
1086
+ var configuration, errMsg, configWithUPS, configWithToken, error_1;
1087
+ return tslib.__generator(this, function (_a) {
1088
+ switch (_a.label) {
1089
+ case 0:
1090
+ internalLogger.info("Get SQL configuration");
1091
+ configuration = getResourceConfiguration(exports.ResourceType.SQL);
1092
+ if (!configuration) {
1093
+ errMsg = "SQL resource configuration not exist";
1094
+ internalLogger.error(errMsg);
1095
+ throw new ErrorWithCode(errMsg, exports.ErrorCode.InvalidConfiguration);
1096
+ }
1097
+ try {
1098
+ this.isSQLConfigurationValid(configuration);
1099
+ }
1100
+ catch (err) {
1101
+ throw err;
1102
+ }
1103
+ if (!this.isMsiAuthentication()) {
1104
+ configWithUPS = this.generateDefaultConfig(configuration);
1105
+ internalLogger.verbose("SQL configuration with username and password generated");
1106
+ return [2 /*return*/, configWithUPS];
1107
+ }
1108
+ _a.label = 1;
1109
+ case 1:
1110
+ _a.trys.push([1, 3, , 4]);
1111
+ return [4 /*yield*/, this.generateTokenConfig(configuration)];
1112
+ case 2:
1113
+ configWithToken = _a.sent();
1114
+ internalLogger.verbose("SQL configuration with MSI token generated");
1115
+ return [2 /*return*/, configWithToken];
1116
+ case 3:
1117
+ error_1 = _a.sent();
1118
+ throw error_1;
1119
+ case 4: return [2 /*return*/];
1120
+ }
1121
+ });
1122
+ });
1123
+ };
1124
+ /**
1125
+ * Check SQL use MSI identity or username and password.
1126
+ *
1127
+ * @returns false - login with SQL MSI identity, true - login with username and password.
1128
+ * @internal
1129
+ */
1130
+ DefaultTediousConnectionConfiguration.prototype.isMsiAuthentication = function () {
1131
+ internalLogger.verbose("Check connection config using MSI access token or username and password");
1132
+ var configuration = getResourceConfiguration(exports.ResourceType.SQL);
1133
+ if ((configuration === null || configuration === void 0 ? void 0 : configuration.sqlUsername) != null && (configuration === null || configuration === void 0 ? void 0 : configuration.sqlPassword) != null) {
1134
+ internalLogger.verbose("Login with username and password");
1135
+ return false;
1136
+ }
1137
+ internalLogger.verbose("Login with MSI identity");
1138
+ return true;
1139
+ };
1140
+ /**
1141
+ * check configuration is an available configurations.
1142
+ * @param { SqlConfiguration } sqlConfig
1143
+ *
1144
+ * @returns true - SQL configuration has a valid SQL endpoints, SQL username with password or identity ID.
1145
+ * false - configuration is not valid.
1146
+ * @internal
1147
+ */
1148
+ DefaultTediousConnectionConfiguration.prototype.isSQLConfigurationValid = function (sqlConfig) {
1149
+ internalLogger.verbose("Check SQL configuration if valid");
1150
+ if (!sqlConfig.sqlServerEndpoint) {
1151
+ internalLogger.error("SQL configuration is not valid without SQL server endpoint exist");
1152
+ throw new ErrorWithCode("SQL configuration error without SQL server endpoint exist", exports.ErrorCode.InvalidConfiguration);
1153
+ }
1154
+ if (!(sqlConfig.sqlUsername && sqlConfig.sqlPassword) && !sqlConfig.sqlIdentityId) {
1155
+ var errMsg = "SQL configuration is not valid without " + (sqlConfig.sqlIdentityId ? "" : "identity id ") + " " + (sqlConfig.sqlUsername ? "" : "SQL username ") + " " + (sqlConfig.sqlPassword ? "" : "SQL password") + " exist";
1156
+ internalLogger.error(errMsg);
1157
+ throw new ErrorWithCode(errMsg, exports.ErrorCode.InvalidConfiguration);
1158
+ }
1159
+ internalLogger.verbose("SQL configuration is valid");
1160
+ };
1161
+ /**
1162
+ * Generate tedious connection configuration with default authentication type.
1163
+ *
1164
+ * @param { SqlConfiguration } SQL configuration with username and password.
1165
+ *
1166
+ * @returns Tedious connection configuration with username and password.
1167
+ * @internal
1168
+ */
1169
+ DefaultTediousConnectionConfiguration.prototype.generateDefaultConfig = function (sqlConfig) {
1170
+ internalLogger.verbose("SQL server " + sqlConfig.sqlServerEndpoint + ", user name " + sqlConfig.sqlUsername + ", database name " + sqlConfig.sqlDatabaseName);
1171
+ var config = {
1172
+ server: sqlConfig.sqlServerEndpoint,
1173
+ authentication: {
1174
+ type: TediousAuthenticationType.default,
1175
+ options: {
1176
+ userName: sqlConfig.sqlUsername,
1177
+ password: sqlConfig.sqlPassword,
1178
+ },
1179
+ },
1180
+ options: {
1181
+ database: sqlConfig.sqlDatabaseName,
1182
+ encrypt: true,
1183
+ },
1184
+ };
1185
+ return config;
1186
+ };
1187
+ /**
1188
+ * Generate tedious connection configuration with azure-active-directory-access-token authentication type.
1189
+ *
1190
+ * @param { SqlConfiguration } SQL configuration with AAD access token.
1191
+ *
1192
+ * @returns Tedious connection configuration with access token.
1193
+ * @internal
1194
+ */
1195
+ DefaultTediousConnectionConfiguration.prototype.generateTokenConfig = function (sqlConfig) {
1196
+ return tslib.__awaiter(this, void 0, void 0, function () {
1197
+ var token, credential, errMsg, config;
1198
+ return tslib.__generator(this, function (_a) {
1199
+ switch (_a.label) {
1200
+ case 0:
1201
+ internalLogger.verbose("Generate tedious config with MSI token");
1202
+ _a.label = 1;
1203
+ case 1:
1204
+ _a.trys.push([1, 3, , 4]);
1205
+ credential = new identity.ManagedIdentityCredential(sqlConfig.sqlIdentityId);
1206
+ return [4 /*yield*/, credential.getToken(this.defaultSQLScope)];
1207
+ case 2:
1208
+ token = _a.sent();
1209
+ return [3 /*break*/, 4];
1210
+ case 3:
1211
+ _a.sent();
1212
+ errMsg = "Get user MSI token failed";
1213
+ internalLogger.error(errMsg);
1214
+ throw new ErrorWithCode(errMsg, exports.ErrorCode.InternalError);
1215
+ case 4:
1216
+ if (token) {
1217
+ config = {
1218
+ server: sqlConfig.sqlServerEndpoint,
1219
+ authentication: {
1220
+ type: TediousAuthenticationType.MSI,
1221
+ options: {
1222
+ token: token.token,
1223
+ },
1224
+ },
1225
+ options: {
1226
+ database: sqlConfig.sqlDatabaseName,
1227
+ encrypt: true,
1228
+ },
1229
+ };
1230
+ internalLogger.verbose("Generate token configuration success, server endpoint is " + sqlConfig.sqlServerEndpoint + ", database name is " + sqlConfig.sqlDatabaseName);
1231
+ return [2 /*return*/, config];
1232
+ }
1233
+ internalLogger.error("Generate token configuration, server endpoint is " + sqlConfig.sqlServerEndpoint + ", MSI token is not valid");
1234
+ throw new ErrorWithCode("MSI token is not valid", exports.ErrorCode.InternalError);
1235
+ }
1236
+ });
1237
+ });
1238
+ };
1239
+ return DefaultTediousConnectionConfiguration;
1240
+ }());
1241
+ /**
1242
+ * tedious connection config authentication type.
1243
+ * https://tediousjs.github.io/tedious/api-connection.html
1244
+ * @internal
1245
+ */
1246
+ var TediousAuthenticationType;
1247
+ (function (TediousAuthenticationType) {
1248
+ TediousAuthenticationType["default"] = "default";
1249
+ TediousAuthenticationType["MSI"] = "azure-active-directory-access-token";
1250
+ })(TediousAuthenticationType || (TediousAuthenticationType = {}));
1251
+
1252
+ // Copyright (c) Microsoft Corporation.
1253
+ var invokeResponseType = "invokeResponse";
1254
+ /**
1255
+ * Response body returned for a token exchange invoke activity.
1256
+ *
1257
+ * @beta
1258
+ */
1259
+ var TokenExchangeInvokeResponse = /** @class */ (function () {
1260
+ function TokenExchangeInvokeResponse(id, failureDetail) {
1261
+ this.id = id;
1262
+ this.failureDetail = failureDetail;
1263
+ }
1264
+ return TokenExchangeInvokeResponse;
1265
+ }());
1266
+ /**
1267
+ * Creates a new prompt that leverage Teams Single Sign On (SSO) support for bot to automatically sign in user and
1268
+ * help receive oauth token, asks the user to consent if needed.
1269
+ *
1270
+ * @remarks
1271
+ * The prompt will attempt to retrieve the users current token of the desired scopes and store it in
1272
+ * the token store.
1273
+ *
1274
+ * User will be automatically signed in leveraging Teams support of Bot Single Sign On(SSO):
1275
+ * https://docs.microsoft.com/en-us/microsoftteams/platform/bots/how-to/authentication/auth-aad-sso-bots
1276
+ *
1277
+ * @example
1278
+ * When used with your bots `DialogSet` you can simply add a new instance of the prompt as a named
1279
+ * dialog using `DialogSet.add()`. You can then start the prompt from a waterfall step using either
1280
+ * `DialogContext.beginDialog()` or `DialogContext.prompt()`. The user will be prompted to sign in as
1281
+ * needed and their access token will be passed as an argument to the callers next waterfall step:
1282
+ *
1283
+ * ```JavaScript
1284
+ * const { ConversationState, MemoryStorage } = require('botbuilder');
1285
+ * const { DialogSet, WaterfallDialog } = require('botbuilder-dialogs');
1286
+ * const { TeamsBotSsoPrompt } = require('@microsoft/teamsfx');
1287
+ *
1288
+ * const convoState = new ConversationState(new MemoryStorage());
1289
+ * const dialogState = convoState.createProperty('dialogState');
1290
+ * const dialogs = new DialogSet(dialogState);
1291
+ *
1292
+ * loadConfiguration();
1293
+ * dialogs.add(new TeamsBotSsoPrompt('TeamsBotSsoPrompt', {
1294
+ * scopes: ["User.Read"],
1295
+ * }));
1296
+ *
1297
+ * dialogs.add(new WaterfallDialog('taskNeedingLogin', [
1298
+ * async (step) => {
1299
+ * return await step.beginDialog('TeamsBotSsoPrompt');
1300
+ * },
1301
+ * async (step) => {
1302
+ * const token = step.result;
1303
+ * if (token) {
1304
+ *
1305
+ * // ... continue with task needing access token ...
1306
+ *
1307
+ * } else {
1308
+ * await step.context.sendActivity(`Sorry... We couldn't log you in. Try again later.`);
1309
+ * return await step.endDialog();
1310
+ * }
1311
+ * }
1312
+ * ]));
1313
+ * ```
1314
+ *
1315
+ * @beta
1316
+ */
1317
+ var TeamsBotSsoPrompt = /** @class */ (function (_super) {
1318
+ tslib.__extends(TeamsBotSsoPrompt, _super);
1319
+ /**
1320
+ * Constructor of TeamsBotSsoPrompt.
1321
+ *
1322
+ * @param dialogId Unique ID of the dialog within its parent `DialogSet` or `ComponentDialog`.
1323
+ * @param settings Settings used to configure the prompt.
1324
+ *
1325
+ * @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
1326
+ * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
1327
+ *
1328
+ * @beta
1329
+ */
1330
+ function TeamsBotSsoPrompt(dialogId, settings) {
1331
+ var _this = _super.call(this, dialogId) || this;
1332
+ _this.settings = settings;
1333
+ validateScopesType(settings.scopes);
1334
+ internalLogger.info("Create a new Teams Bot SSO Prompt");
1335
+ return _this;
1336
+ }
1337
+ /**
1338
+ * Called when a prompt dialog is pushed onto the dialog stack and is being activated.
1339
+ * @remarks
1340
+ * If the task is successful, the result indicates whether the prompt is still
1341
+ * active after the turn has been processed by the prompt.
1342
+ *
1343
+ * @param dc The DialogContext for the current turn of the conversation.
1344
+ *
1345
+ * @throws {@link ErrorCode|InvalidParameter} when timeout property in teams bot sso prompt settings is not number or is not positive.
1346
+ * @throws {@link ErrorCode|ChannelNotSupported} when bot channel is not MS Teams.
1347
+ * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
1348
+ *
1349
+ * @returns A `Promise` representing the asynchronous operation.
1350
+ *
1351
+ * @beta
1352
+ */
1353
+ TeamsBotSsoPrompt.prototype.beginDialog = function (dc) {
1354
+ var _a;
1355
+ return tslib.__awaiter(this, void 0, void 0, function () {
1356
+ var default_timeout, timeout, errorMsg, errorMsg, state;
1357
+ return tslib.__generator(this, function (_b) {
1358
+ switch (_b.label) {
1359
+ case 0:
1360
+ internalLogger.info("Begin Teams Bot SSO Prompt");
1361
+ this.ensureMsTeamsChannel(dc);
1362
+ default_timeout = 900000;
1363
+ timeout = default_timeout;
1364
+ if (this.settings.timeout) {
1365
+ if (typeof this.settings.timeout != "number") {
1366
+ errorMsg = "type of timeout property in teamsBotSsoPromptSettings should be number.";
1367
+ internalLogger.error(errorMsg);
1368
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.InvalidParameter);
1369
+ }
1370
+ if (this.settings.timeout <= 0) {
1371
+ errorMsg = "value of timeout property in teamsBotSsoPromptSettings should be positive.";
1372
+ internalLogger.error(errorMsg);
1373
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.InvalidParameter);
1374
+ }
1375
+ timeout = this.settings.timeout;
1376
+ }
1377
+ if (this.settings.endOnInvalidMessage === undefined) {
1378
+ this.settings.endOnInvalidMessage = true;
1379
+ }
1380
+ state = (_a = dc.activeDialog) === null || _a === void 0 ? void 0 : _a.state;
1381
+ state.state = {};
1382
+ state.options = {};
1383
+ state.expires = new Date().getTime() + timeout;
1384
+ // Send OAuth card to get SSO token
1385
+ return [4 /*yield*/, this.sendOAuthCardAsync(dc.context)];
1386
+ case 1:
1387
+ // Send OAuth card to get SSO token
1388
+ _b.sent();
1389
+ return [2 /*return*/, botbuilderDialogs.Dialog.EndOfTurn];
1390
+ }
1391
+ });
1392
+ });
1393
+ };
1394
+ /**
1395
+ * Called when a prompt dialog is the active dialog and the user replied with a new activity.
1396
+ *
1397
+ * @remarks
1398
+ * If the task is successful, the result indicates whether the dialog is still
1399
+ * active after the turn has been processed by the dialog.
1400
+ * The prompt generally continues to receive the user's replies until it accepts the
1401
+ * user's reply as valid input for the prompt.
1402
+ *
1403
+ * @param dc The DialogContext for the current turn of the conversation.
1404
+ *
1405
+ * @returns A `Promise` representing the asynchronous operation.
1406
+ *
1407
+ * @throws {@link ErrorCode|ChannelNotSupported} when bot channel is not MS Teams.
1408
+ * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
1409
+ *
1410
+ * @beta
1411
+ */
1412
+ TeamsBotSsoPrompt.prototype.continueDialog = function (dc) {
1413
+ var _a;
1414
+ return tslib.__awaiter(this, void 0, void 0, function () {
1415
+ var state, isMessage, isTimeoutActivityType, hasTimedOut, recognized;
1416
+ return tslib.__generator(this, function (_b) {
1417
+ switch (_b.label) {
1418
+ case 0:
1419
+ internalLogger.info("Continue Teams Bot SSO Prompt");
1420
+ this.ensureMsTeamsChannel(dc);
1421
+ state = (_a = dc.activeDialog) === null || _a === void 0 ? void 0 : _a.state;
1422
+ isMessage = dc.context.activity.type === botbuilder.ActivityTypes.Message;
1423
+ isTimeoutActivityType = isMessage ||
1424
+ this.isTeamsVerificationInvoke(dc.context) ||
1425
+ this.isTokenExchangeRequestInvoke(dc.context);
1426
+ hasTimedOut = isTimeoutActivityType && new Date().getTime() > state.expires;
1427
+ if (!hasTimedOut) return [3 /*break*/, 2];
1428
+ internalLogger.warn("End Teams Bot SSO Prompt due to timeout");
1429
+ return [4 /*yield*/, dc.endDialog(undefined)];
1430
+ case 1: return [2 /*return*/, _b.sent()];
1431
+ case 2:
1432
+ if (!(this.isTeamsVerificationInvoke(dc.context) ||
1433
+ this.isTokenExchangeRequestInvoke(dc.context))) return [3 /*break*/, 6];
1434
+ return [4 /*yield*/, this.recognizeToken(dc)];
1435
+ case 3:
1436
+ recognized = _b.sent();
1437
+ if (!recognized.succeeded) return [3 /*break*/, 5];
1438
+ return [4 /*yield*/, dc.endDialog(recognized.value)];
1439
+ case 4: return [2 /*return*/, _b.sent()];
1440
+ case 5: return [3 /*break*/, 8];
1441
+ case 6:
1442
+ if (!(isMessage && this.settings.endOnInvalidMessage)) return [3 /*break*/, 8];
1443
+ internalLogger.warn("End Teams Bot SSO Prompt due to invalid message");
1444
+ return [4 /*yield*/, dc.endDialog(undefined)];
1445
+ case 7: return [2 /*return*/, _b.sent()];
1446
+ case 8: return [2 /*return*/, botbuilderDialogs.Dialog.EndOfTurn];
1447
+ }
1448
+ });
1449
+ });
1450
+ };
1451
+ /**
1452
+ * Ensure bot is running in MS Teams since TeamsBotSsoPrompt is only supported in MS Teams channel.
1453
+ * @param dc dialog context
1454
+ * @throws {@link ErrorCode|ChannelNotSupported} if bot channel is not MS Teams
1455
+ * @internal
1456
+ */
1457
+ TeamsBotSsoPrompt.prototype.ensureMsTeamsChannel = function (dc) {
1458
+ if (dc.context.activity.channelId != botbuilder.Channels.Msteams) {
1459
+ var errorMsg = formatString(ErrorMessage.OnlyMSTeamsChannelSupported, "Teams Bot SSO Prompt");
1460
+ internalLogger.error(errorMsg);
1461
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.ChannelNotSupported);
1462
+ }
1463
+ };
1464
+ /**
1465
+ * Send OAuthCard that tells Teams to obtain an authentication token for the bot application.
1466
+ * For details see https://docs.microsoft.com/en-us/microsoftteams/platform/bots/how-to/authentication/auth-aad-sso-bots.
1467
+ *
1468
+ * @internal
1469
+ */
1470
+ TeamsBotSsoPrompt.prototype.sendOAuthCardAsync = function (context) {
1471
+ return tslib.__awaiter(this, void 0, void 0, function () {
1472
+ var account, loginHint, signInResource, card, msg;
1473
+ return tslib.__generator(this, function (_a) {
1474
+ switch (_a.label) {
1475
+ case 0:
1476
+ internalLogger.verbose("Send OAuth card to get SSO token");
1477
+ return [4 /*yield*/, botbuilder.TeamsInfo.getMember(context, context.activity.from.id)];
1478
+ case 1:
1479
+ account = _a.sent();
1480
+ internalLogger.verbose("Get Teams member account user principal name: " + account.userPrincipalName);
1481
+ loginHint = account.userPrincipalName ? account.userPrincipalName : "";
1482
+ signInResource = this.getSignInResource(loginHint);
1483
+ card = botbuilder.CardFactory.oauthCard("", "Teams SSO Sign In", "Sign In", signInResource.signInLink, signInResource.tokenExchangeResource);
1484
+ card.content.buttons[0].type = botbuilder.ActionTypes.Signin;
1485
+ msg = botbuilder.MessageFactory.attachment(card);
1486
+ // Send prompt
1487
+ return [4 /*yield*/, context.sendActivity(msg)];
1488
+ case 2:
1489
+ // Send prompt
1490
+ _a.sent();
1491
+ return [2 /*return*/];
1492
+ }
1493
+ });
1494
+ });
1495
+ };
1496
+ /**
1497
+ * Get sign in resource.
1498
+ *
1499
+ * @throws {@link ErrorCode|InvalidConfiguration} if client id, tenant id or initiate login endpoint is not found in config.
1500
+ *
1501
+ * @internal
1502
+ */
1503
+ TeamsBotSsoPrompt.prototype.getSignInResource = function (loginHint) {
1504
+ var _a, _b, _c, _d, _e;
1505
+ internalLogger.verbose("Get sign in authentication configuration");
1506
+ var missingConfigurations = [];
1507
+ if (!((_a = config === null || config === void 0 ? void 0 : config.authentication) === null || _a === void 0 ? void 0 : _a.initiateLoginEndpoint)) {
1508
+ missingConfigurations.push("initiateLoginEndpoint");
1509
+ }
1510
+ if (!((_b = config === null || config === void 0 ? void 0 : config.authentication) === null || _b === void 0 ? void 0 : _b.clientId)) {
1511
+ missingConfigurations.push("clientId");
1512
+ }
1513
+ if (!((_c = config === null || config === void 0 ? void 0 : config.authentication) === null || _c === void 0 ? void 0 : _c.tenantId)) {
1514
+ missingConfigurations.push("tenantId");
1515
+ }
1516
+ if (!((_d = config === null || config === void 0 ? void 0 : config.authentication) === null || _d === void 0 ? void 0 : _d.applicationIdUri)) {
1517
+ missingConfigurations.push("applicationIdUri");
1518
+ }
1519
+ if (missingConfigurations.length != 0) {
1520
+ var errorMsg = formatString(ErrorMessage.InvalidConfiguration, missingConfigurations.join(", "), "undefined");
1521
+ internalLogger.error(errorMsg);
1522
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.InvalidConfiguration);
1523
+ }
1524
+ var signInLink = config.authentication.initiateLoginEndpoint + "?scope=" + encodeURI(this.settings.scopes.join(" ")) + "&clientId=" + config.authentication.clientId + "&tenantId=" + config.authentication.tenantId + "&loginHint=" + loginHint;
1525
+ internalLogger.verbose("Sign in link: " + signInLink);
1526
+ var tokenExchangeResource = {
1527
+ id: uuid.v4(),
1528
+ uri: ((_e = config.authentication) === null || _e === void 0 ? void 0 : _e.applicationIdUri.replace(/\/$/, "")) + "/access_as_user",
1529
+ };
1530
+ internalLogger.verbose("Token exchange resource uri: " + tokenExchangeResource.uri);
1531
+ return {
1532
+ signInLink: signInLink,
1533
+ tokenExchangeResource: tokenExchangeResource,
1534
+ };
1535
+ };
1536
+ /**
1537
+ * @internal
1538
+ */
1539
+ TeamsBotSsoPrompt.prototype.recognizeToken = function (dc) {
1540
+ return tslib.__awaiter(this, void 0, void 0, function () {
1541
+ var context, tokenResponse, warningMsg, ssoToken, credential, exchangedToken, ssoTokenExpiration, warningMsg;
1542
+ return tslib.__generator(this, function (_a) {
1543
+ switch (_a.label) {
1544
+ case 0:
1545
+ context = dc.context;
1546
+ if (!this.isTokenExchangeRequestInvoke(context)) return [3 /*break*/, 10];
1547
+ internalLogger.verbose("Receive token exchange request");
1548
+ if (!!(context.activity.value && this.isTokenExchangeRequest(context.activity.value))) return [3 /*break*/, 2];
1549
+ warningMsg = "The bot received an InvokeActivity that is missing a TokenExchangeInvokeRequest value. This is required to be sent with the InvokeActivity.";
1550
+ internalLogger.warn(warningMsg);
1551
+ return [4 /*yield*/, context.sendActivity(this.getTokenExchangeInvokeResponse(botbuilder.StatusCodes.BAD_REQUEST, warningMsg))];
1552
+ case 1:
1553
+ _a.sent();
1554
+ return [3 /*break*/, 9];
1555
+ case 2:
1556
+ ssoToken = context.activity.value.token;
1557
+ credential = new OnBehalfOfUserCredential(ssoToken);
1558
+ exchangedToken = void 0;
1559
+ _a.label = 3;
1560
+ case 3:
1561
+ _a.trys.push([3, 7, , 9]);
1562
+ return [4 /*yield*/, credential.getToken(this.settings.scopes)];
1563
+ case 4:
1564
+ exchangedToken = _a.sent();
1565
+ if (!exchangedToken) return [3 /*break*/, 6];
1566
+ return [4 /*yield*/, context.sendActivity(this.getTokenExchangeInvokeResponse(botbuilder.StatusCodes.OK, "", context.activity.value.id))];
1567
+ case 5:
1568
+ _a.sent();
1569
+ ssoTokenExpiration = parseJwt(ssoToken).exp;
1570
+ tokenResponse = {
1571
+ ssoToken: ssoToken,
1572
+ ssoTokenExpiration: new Date(ssoTokenExpiration * 1000).toISOString(),
1573
+ connectionName: "",
1574
+ token: exchangedToken.token,
1575
+ expiration: exchangedToken.expiresOnTimestamp.toString(),
1576
+ };
1577
+ _a.label = 6;
1578
+ case 6: return [3 /*break*/, 9];
1579
+ case 7:
1580
+ _a.sent();
1581
+ warningMsg = "The bot is unable to exchange token. Ask for user consent.";
1582
+ internalLogger.info(warningMsg);
1583
+ return [4 /*yield*/, context.sendActivity(this.getTokenExchangeInvokeResponse(botbuilder.StatusCodes.PRECONDITION_FAILED, warningMsg, context.activity.value.id))];
1584
+ case 8:
1585
+ _a.sent();
1586
+ return [3 /*break*/, 9];
1587
+ case 9: return [3 /*break*/, 13];
1588
+ case 10:
1589
+ if (!this.isTeamsVerificationInvoke(context)) return [3 /*break*/, 13];
1590
+ internalLogger.verbose("Receive Teams state verification request");
1591
+ return [4 /*yield*/, this.sendOAuthCardAsync(dc.context)];
1592
+ case 11:
1593
+ _a.sent();
1594
+ return [4 /*yield*/, context.sendActivity({ type: invokeResponseType, value: { status: botbuilder.StatusCodes.OK } })];
1595
+ case 12:
1596
+ _a.sent();
1597
+ _a.label = 13;
1598
+ case 13: return [2 /*return*/, tokenResponse !== undefined
1599
+ ? { succeeded: true, value: tokenResponse }
1600
+ : { succeeded: false }];
1601
+ }
1602
+ });
1603
+ });
1604
+ };
1605
+ /**
1606
+ * @internal
1607
+ */
1608
+ TeamsBotSsoPrompt.prototype.getTokenExchangeInvokeResponse = function (status, failureDetail, id) {
1609
+ var invokeResponse = {
1610
+ type: invokeResponseType,
1611
+ value: { status: status, body: new TokenExchangeInvokeResponse(id, failureDetail) },
1612
+ };
1613
+ return invokeResponse;
1614
+ };
1615
+ /**
1616
+ * @internal
1617
+ */
1618
+ TeamsBotSsoPrompt.prototype.isTeamsVerificationInvoke = function (context) {
1619
+ var activity = context.activity;
1620
+ return activity.type === botbuilder.ActivityTypes.Invoke && activity.name === botbuilder.verifyStateOperationName;
1621
+ };
1622
+ /**
1623
+ * @internal
1624
+ */
1625
+ TeamsBotSsoPrompt.prototype.isTokenExchangeRequestInvoke = function (context) {
1626
+ var activity = context.activity;
1627
+ return activity.type === botbuilder.ActivityTypes.Invoke && activity.name === botbuilder.tokenExchangeOperationName;
1628
+ };
1629
+ /**
1630
+ * @internal
1631
+ */
1632
+ TeamsBotSsoPrompt.prototype.isTokenExchangeRequest = function (obj) {
1633
+ return obj.hasOwnProperty("token");
1634
+ };
1635
+ return TeamsBotSsoPrompt;
1636
+ }(botbuilderDialogs.Dialog));
1637
+
1638
+ exports.DefaultTediousConnectionConfiguration = DefaultTediousConnectionConfiguration;
1639
+ exports.ErrorWithCode = ErrorWithCode;
1640
+ exports.M365TenantCredential = M365TenantCredential;
1641
+ exports.MsGraphAuthProvider = MsGraphAuthProvider;
1642
+ exports.OnBehalfOfUserCredential = OnBehalfOfUserCredential;
1643
+ exports.TeamsBotSsoPrompt = TeamsBotSsoPrompt;
1644
+ exports.TeamsUserCredential = TeamsUserCredential;
1645
+ exports.createMicrosoftGraphClient = createMicrosoftGraphClient;
1646
+ exports.getAuthenticationConfiguration = getAuthenticationConfiguration;
1647
+ exports.getLogLevel = getLogLevel;
1648
+ exports.getResourceConfiguration = getResourceConfiguration;
1649
+ exports.loadConfiguration = loadConfiguration;
1650
+ exports.setLogFunction = setLogFunction;
1651
+ exports.setLogLevel = setLogLevel;
1652
+ exports.setLogger = setLogger;
1653
+ //# sourceMappingURL=index.node.cjs.js.map