@microsoft/teamsfx 0.4.1-alpha.fcc60ca0.0 → 0.4.2-alpha.01e159e5.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.
- package/README.md +3 -4
- package/dist/index.esm2017.js +147 -220
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +22 -9
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +355 -549
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +442 -546
- package/dist/index.node.cjs.js.map +1 -1
- package/package.json +12 -9
- package/types/teamsfx.d.ts +8 -2
package/dist/index.esm5.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { __extends, __awaiter, __generator } from 'tslib';
|
|
2
1
|
import jwt_decode from 'jwt-decode';
|
|
2
|
+
import { __awaiter } from 'tslib';
|
|
3
3
|
import * as microsoftTeams from '@microsoft/teams-js';
|
|
4
|
-
import
|
|
4
|
+
import { PublicClientApplication } from '@azure/msal-browser';
|
|
5
5
|
import { Client } from '@microsoft/microsoft-graph-client';
|
|
6
6
|
|
|
7
7
|
// Copyright (c) Microsoft Corporation.
|
|
8
|
+
// Licensed under the MIT license.
|
|
8
9
|
/**
|
|
9
10
|
* Error code to trace the error types.
|
|
10
11
|
* @beta
|
|
@@ -55,35 +56,35 @@ var ErrorCode;
|
|
|
55
56
|
* Operation failed.
|
|
56
57
|
*/
|
|
57
58
|
ErrorCode["FailedOperation"] = "FailedOperation";
|
|
59
|
+
/**
|
|
60
|
+
* Invalid response error.
|
|
61
|
+
*/
|
|
62
|
+
ErrorCode["InvalidResponse"] = "InvalidResponse";
|
|
58
63
|
})(ErrorCode || (ErrorCode = {}));
|
|
59
64
|
/**
|
|
60
65
|
* @internal
|
|
61
66
|
*/
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
ErrorMessage.OnlyMSTeamsChannelSupported = "{0} is only supported in MS Teams Channel";
|
|
78
|
-
return ErrorMessage;
|
|
79
|
-
}());
|
|
67
|
+
class ErrorMessage {
|
|
68
|
+
}
|
|
69
|
+
// InvalidConfiguration Error
|
|
70
|
+
ErrorMessage.InvalidConfiguration = "{0} in configuration is invalid: {1}.";
|
|
71
|
+
ErrorMessage.ConfigurationNotExists = "Configuration does not exist. {0}";
|
|
72
|
+
ErrorMessage.ResourceConfigurationNotExists = "{0} resource configuration does not exist.";
|
|
73
|
+
ErrorMessage.MissingResourceConfiguration = "Missing resource configuration with type: {0}, name: {1}.";
|
|
74
|
+
ErrorMessage.AuthenticationConfigurationNotExists = "Authentication configuration does not exist.";
|
|
75
|
+
// RuntimeNotSupported Error
|
|
76
|
+
ErrorMessage.BrowserRuntimeNotSupported = "{0} is not supported in browser.";
|
|
77
|
+
ErrorMessage.NodejsRuntimeNotSupported = "{0} is not supported in Node.";
|
|
78
|
+
// Internal Error
|
|
79
|
+
ErrorMessage.FailToAcquireTokenOnBehalfOfUser = "Failed to acquire access token on behalf of user: {0}";
|
|
80
|
+
// ChannelNotSupported Error
|
|
81
|
+
ErrorMessage.OnlyMSTeamsChannelSupported = "{0} is only supported in MS Teams Channel";
|
|
80
82
|
/**
|
|
81
83
|
* Error class with code and message thrown by the SDK.
|
|
82
84
|
*
|
|
83
85
|
* @beta
|
|
84
86
|
*/
|
|
85
|
-
|
|
86
|
-
__extends(ErrorWithCode, _super);
|
|
87
|
+
class ErrorWithCode extends Error {
|
|
87
88
|
/**
|
|
88
89
|
* Constructor of ErrorWithCode.
|
|
89
90
|
*
|
|
@@ -92,21 +93,17 @@ var ErrorWithCode = /** @class */ (function (_super) {
|
|
|
92
93
|
*
|
|
93
94
|
* @beta
|
|
94
95
|
*/
|
|
95
|
-
|
|
96
|
-
var _newTarget = this.constructor;
|
|
97
|
-
var _this = this;
|
|
96
|
+
constructor(message, code) {
|
|
98
97
|
if (!code) {
|
|
99
|
-
|
|
100
|
-
return
|
|
98
|
+
super(message);
|
|
99
|
+
return this;
|
|
101
100
|
}
|
|
102
|
-
|
|
103
|
-
Object.setPrototypeOf(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return _this;
|
|
101
|
+
super(message);
|
|
102
|
+
Object.setPrototypeOf(this, ErrorWithCode.prototype);
|
|
103
|
+
this.name = `${new.target.name}.${code}`;
|
|
104
|
+
this.code = code;
|
|
107
105
|
}
|
|
108
|
-
|
|
109
|
-
}(Error));
|
|
106
|
+
}
|
|
110
107
|
|
|
111
108
|
// Copyright (c) Microsoft Corporation.
|
|
112
109
|
// Licensed under the MIT license.
|
|
@@ -174,8 +171,8 @@ function setLogLevel(level) {
|
|
|
174
171
|
function getLogLevel() {
|
|
175
172
|
return internalLogger.level;
|
|
176
173
|
}
|
|
177
|
-
|
|
178
|
-
|
|
174
|
+
class InternalLogger {
|
|
175
|
+
constructor(name, logLevel) {
|
|
179
176
|
this.level = undefined;
|
|
180
177
|
this.defaultLogger = {
|
|
181
178
|
verbose: console.debug,
|
|
@@ -186,31 +183,31 @@ var InternalLogger = /** @class */ (function () {
|
|
|
186
183
|
this.name = name;
|
|
187
184
|
this.level = logLevel;
|
|
188
185
|
}
|
|
189
|
-
|
|
190
|
-
this.log(LogLevel.Error,
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
this.log(LogLevel.Warn,
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
this.log(LogLevel.Info,
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
this.log(LogLevel.Verbose,
|
|
200
|
-
}
|
|
201
|
-
|
|
186
|
+
error(message) {
|
|
187
|
+
this.log(LogLevel.Error, (x) => x.error, message);
|
|
188
|
+
}
|
|
189
|
+
warn(message) {
|
|
190
|
+
this.log(LogLevel.Warn, (x) => x.warn, message);
|
|
191
|
+
}
|
|
192
|
+
info(message) {
|
|
193
|
+
this.log(LogLevel.Info, (x) => x.info, message);
|
|
194
|
+
}
|
|
195
|
+
verbose(message) {
|
|
196
|
+
this.log(LogLevel.Verbose, (x) => x.verbose, message);
|
|
197
|
+
}
|
|
198
|
+
log(logLevel, logFunction, message) {
|
|
202
199
|
if (message.trim() === "") {
|
|
203
200
|
return;
|
|
204
201
|
}
|
|
205
|
-
|
|
206
|
-
|
|
202
|
+
const timestamp = new Date().toUTCString();
|
|
203
|
+
let logHeader;
|
|
207
204
|
if (this.name) {
|
|
208
|
-
logHeader =
|
|
205
|
+
logHeader = `[${timestamp}] : @microsoft/teamsfx - ${this.name} : ${LogLevel[logLevel]} - `;
|
|
209
206
|
}
|
|
210
207
|
else {
|
|
211
|
-
logHeader =
|
|
208
|
+
logHeader = `[${timestamp}] : @microsoft/teamsfx : ${LogLevel[logLevel]} - `;
|
|
212
209
|
}
|
|
213
|
-
|
|
210
|
+
const logMessage = `${logHeader}${message}`;
|
|
214
211
|
if (this.level !== undefined && this.level <= logLevel) {
|
|
215
212
|
if (this.customLogger) {
|
|
216
213
|
logFunction(this.customLogger)(logMessage);
|
|
@@ -222,15 +219,14 @@ var InternalLogger = /** @class */ (function () {
|
|
|
222
219
|
logFunction(this.defaultLogger)(logMessage);
|
|
223
220
|
}
|
|
224
221
|
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
}());
|
|
222
|
+
}
|
|
223
|
+
}
|
|
228
224
|
/**
|
|
229
225
|
* Logger instance used internally
|
|
230
226
|
*
|
|
231
227
|
* @internal
|
|
232
228
|
*/
|
|
233
|
-
|
|
229
|
+
const internalLogger = new InternalLogger();
|
|
234
230
|
/**
|
|
235
231
|
* Set custom logger. Use the output functions if it's set. Priority is higher than setLogFunction.
|
|
236
232
|
*
|
|
@@ -283,14 +279,14 @@ function setLogFunction(logFunction) {
|
|
|
283
279
|
*/
|
|
284
280
|
function parseJwt(token) {
|
|
285
281
|
try {
|
|
286
|
-
|
|
282
|
+
const tokenObj = jwt_decode(token);
|
|
287
283
|
if (!tokenObj || !tokenObj.exp) {
|
|
288
284
|
throw new ErrorWithCode("Decoded token is null or exp claim does not exists.", ErrorCode.InternalError);
|
|
289
285
|
}
|
|
290
286
|
return tokenObj;
|
|
291
287
|
}
|
|
292
288
|
catch (err) {
|
|
293
|
-
|
|
289
|
+
const errorMsg = "Parse jwt token failed in node env with error: " + err.message;
|
|
294
290
|
internalLogger.error(errorMsg);
|
|
295
291
|
throw new ErrorWithCode(errorMsg, ErrorCode.InternalError);
|
|
296
292
|
}
|
|
@@ -300,12 +296,12 @@ function parseJwt(token) {
|
|
|
300
296
|
*/
|
|
301
297
|
function getUserInfoFromSsoToken(ssoToken) {
|
|
302
298
|
if (!ssoToken) {
|
|
303
|
-
|
|
299
|
+
const errorMsg = "SSO token is undefined.";
|
|
304
300
|
internalLogger.error(errorMsg);
|
|
305
301
|
throw new ErrorWithCode(errorMsg, ErrorCode.InvalidParameter);
|
|
306
302
|
}
|
|
307
|
-
|
|
308
|
-
|
|
303
|
+
const tokenObject = parseJwt(ssoToken);
|
|
304
|
+
const userInfo = {
|
|
309
305
|
displayName: tokenObject.name,
|
|
310
306
|
objectId: tokenObject.oid,
|
|
311
307
|
preferredUserName: "",
|
|
@@ -318,6 +314,57 @@ function getUserInfoFromSsoToken(ssoToken) {
|
|
|
318
314
|
}
|
|
319
315
|
return userInfo;
|
|
320
316
|
}
|
|
317
|
+
/**
|
|
318
|
+
* @internal
|
|
319
|
+
*/
|
|
320
|
+
function getTenantIdAndLoginHintFromSsoToken(ssoToken) {
|
|
321
|
+
if (!ssoToken) {
|
|
322
|
+
const errorMsg = "SSO token is undefined.";
|
|
323
|
+
internalLogger.error(errorMsg);
|
|
324
|
+
throw new ErrorWithCode(errorMsg, ErrorCode.InvalidParameter);
|
|
325
|
+
}
|
|
326
|
+
const tokenObject = parseJwt(ssoToken);
|
|
327
|
+
const userInfo = {
|
|
328
|
+
tid: tokenObject.tid,
|
|
329
|
+
loginHint: tokenObject.ver === "2.0"
|
|
330
|
+
? tokenObject.preferred_username
|
|
331
|
+
: tokenObject.upn,
|
|
332
|
+
};
|
|
333
|
+
return userInfo;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* @internal
|
|
337
|
+
*/
|
|
338
|
+
function parseAccessTokenFromAuthCodeTokenResponse(tokenResponse) {
|
|
339
|
+
try {
|
|
340
|
+
const tokenResponseObject = typeof tokenResponse == "string"
|
|
341
|
+
? JSON.parse(tokenResponse)
|
|
342
|
+
: tokenResponse;
|
|
343
|
+
if (!tokenResponseObject || !tokenResponseObject.accessToken) {
|
|
344
|
+
const errorMsg = "Get empty access token from Auth Code token response.";
|
|
345
|
+
internalLogger.error(errorMsg);
|
|
346
|
+
throw new Error(errorMsg);
|
|
347
|
+
}
|
|
348
|
+
const token = tokenResponseObject.accessToken;
|
|
349
|
+
const tokenObject = parseJwt(token);
|
|
350
|
+
if (tokenObject.ver !== "1.0" && tokenObject.ver !== "2.0") {
|
|
351
|
+
const errorMsg = "SSO token is not valid with an unknown version: " + tokenObject.ver;
|
|
352
|
+
internalLogger.error(errorMsg);
|
|
353
|
+
throw new Error(errorMsg);
|
|
354
|
+
}
|
|
355
|
+
const accessToken = {
|
|
356
|
+
token: token,
|
|
357
|
+
expiresOnTimestamp: tokenObject.exp * 1000,
|
|
358
|
+
};
|
|
359
|
+
return accessToken;
|
|
360
|
+
}
|
|
361
|
+
catch (error) {
|
|
362
|
+
const errorMsg = "Parse access token failed from Auth Code token response in node env with error: " +
|
|
363
|
+
error.message;
|
|
364
|
+
internalLogger.error(errorMsg);
|
|
365
|
+
throw new ErrorWithCode(errorMsg, ErrorCode.InternalError);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
321
368
|
/**
|
|
322
369
|
* Format string template with replacements
|
|
323
370
|
*
|
|
@@ -332,12 +379,8 @@ function getUserInfoFromSsoToken(ssoToken) {
|
|
|
332
379
|
*
|
|
333
380
|
* @internal
|
|
334
381
|
*/
|
|
335
|
-
function formatString(str) {
|
|
336
|
-
|
|
337
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
338
|
-
replacements[_i - 1] = arguments[_i];
|
|
339
|
-
}
|
|
340
|
-
var args = replacements;
|
|
382
|
+
function formatString(str, ...replacements) {
|
|
383
|
+
const args = replacements;
|
|
341
384
|
return str.replace(/{(\d+)}/g, function (match, number) {
|
|
342
385
|
return typeof args[number] != "undefined" ? args[number] : match;
|
|
343
386
|
});
|
|
@@ -355,17 +398,17 @@ function validateScopesType(value) {
|
|
|
355
398
|
return;
|
|
356
399
|
}
|
|
357
400
|
// string array
|
|
358
|
-
if (Array.isArray(value) && value.length > 0 && value.every(
|
|
401
|
+
if (Array.isArray(value) && value.length > 0 && value.every((item) => typeof item === "string")) {
|
|
359
402
|
return;
|
|
360
403
|
}
|
|
361
|
-
|
|
404
|
+
const errorMsg = "The type of scopes is not valid, it must be string or string array";
|
|
362
405
|
internalLogger.error(errorMsg);
|
|
363
406
|
throw new ErrorWithCode(errorMsg, ErrorCode.InvalidParameter);
|
|
364
407
|
}
|
|
365
408
|
/**
|
|
366
409
|
* @internal
|
|
367
410
|
*/
|
|
368
|
-
|
|
411
|
+
const isNode = typeof process !== "undefined" &&
|
|
369
412
|
!!process.version &&
|
|
370
413
|
!!process.versions &&
|
|
371
414
|
!!process.versions.node;
|
|
@@ -375,7 +418,7 @@ var isNode = typeof process !== "undefined" &&
|
|
|
375
418
|
* Global configuration instance
|
|
376
419
|
*
|
|
377
420
|
*/
|
|
378
|
-
|
|
421
|
+
let config;
|
|
379
422
|
/**
|
|
380
423
|
* Initialize configuration from environment variables or configuration object and set the global instance
|
|
381
424
|
*
|
|
@@ -390,7 +433,7 @@ function loadConfiguration(configuration) {
|
|
|
390
433
|
// browser environment
|
|
391
434
|
if (!isNode) {
|
|
392
435
|
if (!configuration) {
|
|
393
|
-
|
|
436
|
+
const errorMsg = "You are running the code in browser. Configuration must be passed in.";
|
|
394
437
|
internalLogger.error(errorMsg);
|
|
395
438
|
throw new ErrorWithCode(errorMsg, ErrorCode.InvalidParameter);
|
|
396
439
|
}
|
|
@@ -398,9 +441,9 @@ function loadConfiguration(configuration) {
|
|
|
398
441
|
return;
|
|
399
442
|
}
|
|
400
443
|
// node environment
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
444
|
+
let newAuthentication;
|
|
445
|
+
let newResources = [];
|
|
446
|
+
const defaultResourceName = "default";
|
|
404
447
|
if (configuration === null || configuration === void 0 ? void 0 : configuration.authentication) {
|
|
405
448
|
newAuthentication = configuration.authentication;
|
|
406
449
|
}
|
|
@@ -458,15 +501,14 @@ function loadConfiguration(configuration) {
|
|
|
458
501
|
*
|
|
459
502
|
* @beta
|
|
460
503
|
*/
|
|
461
|
-
function getResourceConfiguration(resourceType, resourceName) {
|
|
504
|
+
function getResourceConfiguration(resourceType, resourceName = "default") {
|
|
462
505
|
var _a;
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
var result = (_a = config.resources) === null || _a === void 0 ? void 0 : _a.find(function (item) { return item.type === resourceType && item.name === resourceName; });
|
|
506
|
+
internalLogger.info(`Get resource configuration of ${ResourceType[resourceType]} from ${resourceName}`);
|
|
507
|
+
const result = (_a = config.resources) === null || _a === void 0 ? void 0 : _a.find((item) => item.type === resourceType && item.name === resourceName);
|
|
466
508
|
if (result) {
|
|
467
509
|
return result.properties;
|
|
468
510
|
}
|
|
469
|
-
|
|
511
|
+
const errorMsg = formatString(ErrorMessage.MissingResourceConfiguration, ResourceType[resourceType], resourceName);
|
|
470
512
|
internalLogger.error(errorMsg);
|
|
471
513
|
throw new ErrorWithCode(errorMsg, ErrorCode.InvalidConfiguration);
|
|
472
514
|
}
|
|
@@ -484,7 +526,7 @@ function getAuthenticationConfiguration() {
|
|
|
484
526
|
if (config) {
|
|
485
527
|
return config.authentication;
|
|
486
528
|
}
|
|
487
|
-
|
|
529
|
+
const errorMsg = "Please call loadConfiguration() first before calling getAuthenticationConfiguration().";
|
|
488
530
|
internalLogger.error(errorMsg);
|
|
489
531
|
throw new ErrorWithCode(formatString(ErrorMessage.ConfigurationNotExists, errorMsg), ErrorCode.InvalidConfiguration);
|
|
490
532
|
}
|
|
@@ -498,7 +540,7 @@ function getAuthenticationConfiguration() {
|
|
|
498
540
|
*
|
|
499
541
|
* @beta
|
|
500
542
|
*/
|
|
501
|
-
|
|
543
|
+
class M365TenantCredential {
|
|
502
544
|
/**
|
|
503
545
|
* Constructor of M365TenantCredential.
|
|
504
546
|
*
|
|
@@ -506,7 +548,7 @@ var M365TenantCredential = /** @class */ (function () {
|
|
|
506
548
|
* Only works in in server side.
|
|
507
549
|
* @beta
|
|
508
550
|
*/
|
|
509
|
-
|
|
551
|
+
constructor() {
|
|
510
552
|
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "M365TenantCredential"), ErrorCode.RuntimeNotSupported);
|
|
511
553
|
}
|
|
512
554
|
/**
|
|
@@ -516,15 +558,12 @@ var M365TenantCredential = /** @class */ (function () {
|
|
|
516
558
|
* Only works in in server side.
|
|
517
559
|
* @beta
|
|
518
560
|
*/
|
|
519
|
-
|
|
520
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
521
|
-
|
|
522
|
-
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "M365TenantCredential"), ErrorCode.RuntimeNotSupported);
|
|
523
|
-
});
|
|
561
|
+
getToken(scopes, options) {
|
|
562
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
563
|
+
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "M365TenantCredential"), ErrorCode.RuntimeNotSupported);
|
|
524
564
|
});
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
}());
|
|
565
|
+
}
|
|
566
|
+
}
|
|
528
567
|
|
|
529
568
|
// Copyright (c) Microsoft Corporation.
|
|
530
569
|
/**
|
|
@@ -535,7 +574,7 @@ var M365TenantCredential = /** @class */ (function () {
|
|
|
535
574
|
*
|
|
536
575
|
* @beta
|
|
537
576
|
*/
|
|
538
|
-
|
|
577
|
+
class OnBehalfOfUserCredential {
|
|
539
578
|
/**
|
|
540
579
|
* Constructor of OnBehalfOfUserCredential
|
|
541
580
|
*
|
|
@@ -543,7 +582,7 @@ var OnBehalfOfUserCredential = /** @class */ (function () {
|
|
|
543
582
|
* Can Only works in in server side.
|
|
544
583
|
* @beta
|
|
545
584
|
*/
|
|
546
|
-
|
|
585
|
+
constructor(ssoToken) {
|
|
547
586
|
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "OnBehalfOfUserCredential"), ErrorCode.RuntimeNotSupported);
|
|
548
587
|
}
|
|
549
588
|
/**
|
|
@@ -552,66 +591,27 @@ var OnBehalfOfUserCredential = /** @class */ (function () {
|
|
|
552
591
|
* Can only be used in server side.
|
|
553
592
|
* @beta
|
|
554
593
|
*/
|
|
555
|
-
|
|
556
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
557
|
-
|
|
558
|
-
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "OnBehalfOfUserCredential"), ErrorCode.RuntimeNotSupported);
|
|
559
|
-
});
|
|
594
|
+
getToken(scopes, options) {
|
|
595
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
596
|
+
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "OnBehalfOfUserCredential"), ErrorCode.RuntimeNotSupported);
|
|
560
597
|
});
|
|
561
|
-
}
|
|
598
|
+
}
|
|
562
599
|
/**
|
|
563
600
|
* Get basic user info from SSO token.
|
|
564
601
|
* @remarks
|
|
565
602
|
* Can only be used in server side.
|
|
566
603
|
* @beta
|
|
567
604
|
*/
|
|
568
|
-
|
|
605
|
+
getUserInfo() {
|
|
569
606
|
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "OnBehalfOfUserCredential"), ErrorCode.RuntimeNotSupported);
|
|
570
|
-
};
|
|
571
|
-
return OnBehalfOfUserCredential;
|
|
572
|
-
}());
|
|
573
|
-
|
|
574
|
-
// Copyright (c) Microsoft Corporation.
|
|
575
|
-
// Licensed under the MIT license.
|
|
576
|
-
/**
|
|
577
|
-
* Configuration used in initialization.
|
|
578
|
-
* @internal
|
|
579
|
-
*/
|
|
580
|
-
var Cache = /** @class */ (function () {
|
|
581
|
-
function Cache() {
|
|
582
607
|
}
|
|
583
|
-
|
|
584
|
-
return sessionStorage.getItem(key);
|
|
585
|
-
};
|
|
586
|
-
Cache.set = function (key, value) {
|
|
587
|
-
sessionStorage.setItem(key, value);
|
|
588
|
-
};
|
|
589
|
-
Cache.remove = function (key) {
|
|
590
|
-
sessionStorage.removeItem(key);
|
|
591
|
-
};
|
|
592
|
-
return Cache;
|
|
593
|
-
}());
|
|
594
|
-
|
|
595
|
-
// Copyright (c) Microsoft Corporation.
|
|
596
|
-
// Licensed under the MIT license.
|
|
597
|
-
/**
|
|
598
|
-
* @internal
|
|
599
|
-
*/
|
|
600
|
-
var GrantType;
|
|
601
|
-
(function (GrantType) {
|
|
602
|
-
GrantType["authCode"] = "authorization_code";
|
|
603
|
-
GrantType["ssoToken"] = "sso_token";
|
|
604
|
-
})(GrantType || (GrantType = {}));
|
|
608
|
+
}
|
|
605
609
|
|
|
606
610
|
// Copyright (c) Microsoft Corporation.
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
var loginPageWidth = 600;
|
|
612
|
-
var loginPageHeight = 535;
|
|
613
|
-
var maxRetryCount = 3;
|
|
614
|
-
var retryTimeSpanInMillisecond = 3000;
|
|
611
|
+
const tokenRefreshTimeSpanInMillisecond = 5 * 60 * 1000;
|
|
612
|
+
const initializeTeamsSdkTimeoutInMillisecond = 5000;
|
|
613
|
+
const loginPageWidth = 600;
|
|
614
|
+
const loginPageHeight = 535;
|
|
615
615
|
/**
|
|
616
616
|
* Represent Teams current user's identity, and it is used within Teams tab application.
|
|
617
617
|
*
|
|
@@ -620,7 +620,7 @@ var retryTimeSpanInMillisecond = 3000;
|
|
|
620
620
|
*
|
|
621
621
|
* @beta
|
|
622
622
|
*/
|
|
623
|
-
|
|
623
|
+
class TeamsUserCredential {
|
|
624
624
|
/**
|
|
625
625
|
* Constructor of TeamsUserCredential.
|
|
626
626
|
* Developer need to call loadConfiguration(config) before using this class.
|
|
@@ -629,7 +629,6 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
629
629
|
* ```typescript
|
|
630
630
|
* const config = {
|
|
631
631
|
* authentication: {
|
|
632
|
-
* runtimeConnectorEndpoint: "https://xxx.xxx.com",
|
|
633
632
|
* initiateLoginEndpoint: "https://localhost:3000/auth-start.html",
|
|
634
633
|
* clientId: "xxx"
|
|
635
634
|
* }
|
|
@@ -643,10 +642,11 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
643
642
|
*
|
|
644
643
|
* @beta
|
|
645
644
|
*/
|
|
646
|
-
|
|
645
|
+
constructor() {
|
|
647
646
|
internalLogger.info("Create teams user credential");
|
|
648
647
|
this.config = this.loadAndValidateConfig();
|
|
649
648
|
this.ssoToken = null;
|
|
649
|
+
this.initialized = false;
|
|
650
650
|
}
|
|
651
651
|
/**
|
|
652
652
|
* Popup login page to get user's access token with specific scopes.
|
|
@@ -664,66 +664,67 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
664
664
|
* @param scopes - The list of scopes for which the token will have access, before that, we will request user to consent.
|
|
665
665
|
*
|
|
666
666
|
* @throws {@link ErrorCode|InternalError} when failed to login with unknown error.
|
|
667
|
-
* @throws {@link ErrorCode|ServiceError} when simple auth server failed to exchange access token.
|
|
668
667
|
* @throws {@link ErrorCode|ConsentFailed} when user canceled or failed to consent.
|
|
669
668
|
* @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
|
|
670
669
|
* @throws {@link ErrorCode|RuntimeNotSupported} when runtime is nodeJS.
|
|
671
670
|
*
|
|
672
671
|
* @beta
|
|
673
672
|
*/
|
|
674
|
-
|
|
675
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
673
|
+
login(scopes) {
|
|
674
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
675
|
+
validateScopesType(scopes);
|
|
676
|
+
const scopesStr = typeof scopes === "string" ? scopes : scopes.join(" ");
|
|
677
|
+
internalLogger.info(`Popup login page to get user's access token with scopes: ${scopesStr}`);
|
|
678
|
+
if (!this.initialized) {
|
|
679
|
+
yield this.init();
|
|
680
|
+
}
|
|
681
|
+
return new Promise((resolve, reject) => {
|
|
682
|
+
microsoftTeams.initialize(() => {
|
|
683
|
+
microsoftTeams.authentication.authenticate({
|
|
684
|
+
url: `${this.config.initiateLoginEndpoint}?clientId=${this.config.clientId}&scope=${encodeURI(scopesStr)}&loginHint=${this.loginHint}`,
|
|
685
|
+
width: loginPageWidth,
|
|
686
|
+
height: loginPageHeight,
|
|
687
|
+
successCallback: (result) => __awaiter(this, void 0, void 0, function* () {
|
|
688
|
+
if (!result) {
|
|
689
|
+
const errorMsg = "Get empty authentication result from MSAL";
|
|
690
|
+
internalLogger.error(errorMsg);
|
|
691
|
+
reject(new ErrorWithCode(errorMsg, ErrorCode.InternalError));
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
let resultJson = {};
|
|
695
|
+
try {
|
|
696
|
+
resultJson = JSON.parse(result);
|
|
697
|
+
}
|
|
698
|
+
catch (error) {
|
|
699
|
+
// If can not parse result as Json, will throw error.
|
|
700
|
+
const failedToParseResult = "Failed to parse response to Json.";
|
|
701
|
+
internalLogger.error(failedToParseResult);
|
|
702
|
+
reject(new ErrorWithCode(failedToParseResult, ErrorCode.InvalidResponse));
|
|
703
|
+
}
|
|
704
|
+
// If code exists in result, user may using previous auth-start and auth-end page.
|
|
705
|
+
if (resultJson.code) {
|
|
706
|
+
const helpLink = "https://aka.ms/teamsfx-auth-code-flow";
|
|
707
|
+
const usingPreviousAuthPage = "Found auth code in response. Auth code is not support for current version of SDK. " +
|
|
708
|
+
`Please refer to the help link for how to fix the issue: ${helpLink}.`;
|
|
709
|
+
internalLogger.error(usingPreviousAuthPage);
|
|
710
|
+
reject(new ErrorWithCode(usingPreviousAuthPage, ErrorCode.InvalidResponse));
|
|
711
|
+
}
|
|
712
|
+
// If sessionStorage exists in result, set the values in current session storage.
|
|
713
|
+
if (resultJson.sessionStorage) {
|
|
714
|
+
this.setSessionStorage(resultJson.sessionStorage);
|
|
715
|
+
}
|
|
716
|
+
resolve();
|
|
717
|
+
}),
|
|
718
|
+
failureCallback: (reason) => {
|
|
719
|
+
const errorMsg = `Consent failed for the scope ${scopesStr} with error: ${reason}`;
|
|
720
|
+
internalLogger.error(errorMsg);
|
|
721
|
+
reject(new ErrorWithCode(errorMsg, ErrorCode.ConsentFailed));
|
|
722
|
+
},
|
|
723
|
+
});
|
|
724
|
+
});
|
|
724
725
|
});
|
|
725
726
|
});
|
|
726
|
-
}
|
|
727
|
+
}
|
|
727
728
|
/**
|
|
728
729
|
* Get access token from credential.
|
|
729
730
|
*
|
|
@@ -748,7 +749,6 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
748
749
|
*
|
|
749
750
|
* @throws {@link ErrorCode|InternalError} when failed to get access token with unknown error.
|
|
750
751
|
* @throws {@link ErrorCode|UiRequiredError} when need user consent to get access token.
|
|
751
|
-
* @throws {@link ErrorCode|ServiceError} when failed to get access token from simple auth server.
|
|
752
752
|
* @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
|
|
753
753
|
* @throws {@link ErrorCode|RuntimeNotSupported} when runtime is nodeJS.
|
|
754
754
|
*
|
|
@@ -759,46 +759,62 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
759
759
|
*
|
|
760
760
|
* @beta
|
|
761
761
|
*/
|
|
762
|
-
|
|
763
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
return [2 /*return*/, ssoToken];
|
|
776
|
-
case 2:
|
|
777
|
-
internalLogger.info("Get access token with scopes: " + scopeStr);
|
|
778
|
-
return [4 /*yield*/, this.getAccessTokenCacheKey(scopeStr)];
|
|
779
|
-
case 3:
|
|
780
|
-
cachedKey = _a.sent();
|
|
781
|
-
cachedToken = this.getTokenCache(cachedKey);
|
|
782
|
-
if (cachedToken) {
|
|
783
|
-
if (!this.isAccessTokenNearExpired(cachedToken)) {
|
|
784
|
-
internalLogger.verbose("Get access token from cache");
|
|
785
|
-
return [2 /*return*/, cachedToken];
|
|
786
|
-
}
|
|
787
|
-
else {
|
|
788
|
-
internalLogger.verbose("Cached access token is expired");
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
else {
|
|
792
|
-
internalLogger.verbose("No cached access token");
|
|
793
|
-
}
|
|
794
|
-
return [4 /*yield*/, this.getAndCacheAccessTokenFromSimpleAuthServer(scopeStr)];
|
|
795
|
-
case 4:
|
|
796
|
-
accessToken = _a.sent();
|
|
797
|
-
return [2 /*return*/, accessToken];
|
|
762
|
+
getToken(scopes, options) {
|
|
763
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
764
|
+
validateScopesType(scopes);
|
|
765
|
+
const ssoToken = yield this.getSSOToken();
|
|
766
|
+
const scopeStr = typeof scopes === "string" ? scopes : scopes.join(" ");
|
|
767
|
+
if (scopeStr === "") {
|
|
768
|
+
internalLogger.info("Get SSO token");
|
|
769
|
+
return ssoToken;
|
|
770
|
+
}
|
|
771
|
+
else {
|
|
772
|
+
internalLogger.info("Get access token with scopes: " + scopeStr);
|
|
773
|
+
if (!this.initialized) {
|
|
774
|
+
yield this.init();
|
|
798
775
|
}
|
|
799
|
-
|
|
776
|
+
let tokenResponse;
|
|
777
|
+
const scopesArray = typeof scopes === "string" ? scopes.split(" ") : scopes;
|
|
778
|
+
const domain = window.location.origin;
|
|
779
|
+
// First try to get Access Token from cache.
|
|
780
|
+
try {
|
|
781
|
+
const account = this.msalInstance.getAccountByUsername(this.loginHint);
|
|
782
|
+
const scopesRequestForAcquireTokenSilent = {
|
|
783
|
+
scopes: scopesArray,
|
|
784
|
+
account: account !== null && account !== void 0 ? account : undefined,
|
|
785
|
+
redirectUri: `${domain}/blank-auth-end.html`,
|
|
786
|
+
};
|
|
787
|
+
tokenResponse = yield this.msalInstance.acquireTokenSilent(scopesRequestForAcquireTokenSilent);
|
|
788
|
+
}
|
|
789
|
+
catch (error) {
|
|
790
|
+
const acquireTokenSilentFailedMessage = `Failed to call acquireTokenSilent. Reason: ${error === null || error === void 0 ? void 0 : error.message}. `;
|
|
791
|
+
internalLogger.verbose(acquireTokenSilentFailedMessage);
|
|
792
|
+
}
|
|
793
|
+
if (!tokenResponse) {
|
|
794
|
+
// If fail to get Access Token from cache, try to get Access token by silent login.
|
|
795
|
+
try {
|
|
796
|
+
const scopesRequestForSsoSilent = {
|
|
797
|
+
scopes: scopesArray,
|
|
798
|
+
loginHint: this.loginHint,
|
|
799
|
+
redirectUri: `${domain}/blank-auth-end.html`,
|
|
800
|
+
};
|
|
801
|
+
tokenResponse = yield this.msalInstance.ssoSilent(scopesRequestForSsoSilent);
|
|
802
|
+
}
|
|
803
|
+
catch (error) {
|
|
804
|
+
const ssoSilentFailedMessage = `Failed to call ssoSilent. Reason: ${error === null || error === void 0 ? void 0 : error.message}. `;
|
|
805
|
+
internalLogger.verbose(ssoSilentFailedMessage);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
if (!tokenResponse) {
|
|
809
|
+
const errorMsg = `Failed to get access token cache silently, please login first: you need login first before get access token.`;
|
|
810
|
+
internalLogger.error(errorMsg);
|
|
811
|
+
throw new ErrorWithCode(errorMsg, ErrorCode.UiRequiredError);
|
|
812
|
+
}
|
|
813
|
+
const accessToken = parseAccessTokenFromAuthCodeTokenResponse(tokenResponse);
|
|
814
|
+
return accessToken;
|
|
815
|
+
}
|
|
800
816
|
});
|
|
801
|
-
}
|
|
817
|
+
}
|
|
802
818
|
/**
|
|
803
819
|
* Get basic user info from SSO token
|
|
804
820
|
*
|
|
@@ -815,153 +831,73 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
815
831
|
*
|
|
816
832
|
* @beta
|
|
817
833
|
*/
|
|
818
|
-
|
|
819
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
case 0:
|
|
824
|
-
internalLogger.info("Get basic user info from SSO token");
|
|
825
|
-
return [4 /*yield*/, this.getSSOToken()];
|
|
826
|
-
case 1:
|
|
827
|
-
ssoToken = _a.sent();
|
|
828
|
-
return [2 /*return*/, getUserInfoFromSsoToken(ssoToken.token)];
|
|
829
|
-
}
|
|
830
|
-
});
|
|
831
|
-
});
|
|
832
|
-
};
|
|
833
|
-
TeamsUserCredential.prototype.exchangeAccessTokenFromSimpleAuthServer = function (scopesStr, authCodeResult) {
|
|
834
|
-
var _a, _b;
|
|
835
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
836
|
-
var axiosInstance, retryCount, response, tokenResult, key, err_2;
|
|
837
|
-
return __generator(this, function (_c) {
|
|
838
|
-
switch (_c.label) {
|
|
839
|
-
case 0: return [4 /*yield*/, this.getAxiosInstance()];
|
|
840
|
-
case 1:
|
|
841
|
-
axiosInstance = _c.sent();
|
|
842
|
-
retryCount = 0;
|
|
843
|
-
_c.label = 2;
|
|
844
|
-
case 2:
|
|
845
|
-
_c.label = 3;
|
|
846
|
-
case 3:
|
|
847
|
-
_c.trys.push([3, 6, , 9]);
|
|
848
|
-
return [4 /*yield*/, axiosInstance.post("/auth/token", {
|
|
849
|
-
scope: scopesStr,
|
|
850
|
-
code: authCodeResult.code,
|
|
851
|
-
code_verifier: authCodeResult.codeVerifier,
|
|
852
|
-
redirect_uri: authCodeResult.redirectUri,
|
|
853
|
-
grant_type: GrantType.authCode,
|
|
854
|
-
})];
|
|
855
|
-
case 4:
|
|
856
|
-
response = _c.sent();
|
|
857
|
-
tokenResult = response.data;
|
|
858
|
-
return [4 /*yield*/, this.getAccessTokenCacheKey(scopesStr)];
|
|
859
|
-
case 5:
|
|
860
|
-
key = _c.sent();
|
|
861
|
-
// Important: tokens are stored in sessionStorage, read more here: https://aka.ms/teamsfx-session-storage-notice
|
|
862
|
-
this.setTokenCache(key, {
|
|
863
|
-
token: tokenResult.access_token,
|
|
864
|
-
expiresOnTimestamp: tokenResult.expires_on,
|
|
865
|
-
});
|
|
866
|
-
return [2 /*return*/];
|
|
867
|
-
case 6:
|
|
868
|
-
err_2 = _c.sent();
|
|
869
|
-
if (!(((_b = (_a = err_2.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.type) && err_2.response.data.type === "AadUiRequiredException")) return [3 /*break*/, 8];
|
|
870
|
-
internalLogger.warn("Exchange access token failed, retry...");
|
|
871
|
-
if (!(retryCount < maxRetryCount)) return [3 /*break*/, 8];
|
|
872
|
-
return [4 /*yield*/, this.sleep(retryTimeSpanInMillisecond)];
|
|
873
|
-
case 7:
|
|
874
|
-
_c.sent();
|
|
875
|
-
retryCount++;
|
|
876
|
-
return [3 /*break*/, 2];
|
|
877
|
-
case 8: throw err_2;
|
|
878
|
-
case 9: return [3 /*break*/, 2];
|
|
879
|
-
case 10: return [2 /*return*/];
|
|
880
|
-
}
|
|
881
|
-
});
|
|
834
|
+
getUserInfo() {
|
|
835
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
836
|
+
internalLogger.info("Get basic user info from SSO token");
|
|
837
|
+
const ssoToken = yield this.getSSOToken();
|
|
838
|
+
return getUserInfoFromSsoToken(ssoToken.token);
|
|
882
839
|
});
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
grant_type: GrantType.ssoToken,
|
|
902
|
-
})];
|
|
903
|
-
case 2:
|
|
904
|
-
response = _a.sent();
|
|
905
|
-
accessTokenResult = response.data;
|
|
906
|
-
accessToken = {
|
|
907
|
-
token: accessTokenResult.access_token,
|
|
908
|
-
expiresOnTimestamp: accessTokenResult.expires_on,
|
|
909
|
-
};
|
|
910
|
-
return [4 /*yield*/, this.getAccessTokenCacheKey(scopesStr)];
|
|
911
|
-
case 3:
|
|
912
|
-
cacheKey = _a.sent();
|
|
913
|
-
this.setTokenCache(cacheKey, accessToken);
|
|
914
|
-
return [2 /*return*/, accessToken];
|
|
915
|
-
case 4:
|
|
916
|
-
err_3 = _a.sent();
|
|
917
|
-
throw this.generateAuthServerError(err_3);
|
|
918
|
-
case 5: return [2 /*return*/];
|
|
919
|
-
}
|
|
920
|
-
});
|
|
840
|
+
}
|
|
841
|
+
init() {
|
|
842
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
843
|
+
const ssoToken = yield this.getSSOToken();
|
|
844
|
+
const info = getTenantIdAndLoginHintFromSsoToken(ssoToken.token);
|
|
845
|
+
this.loginHint = info.loginHint;
|
|
846
|
+
this.tid = info.tid;
|
|
847
|
+
const msalConfig = {
|
|
848
|
+
auth: {
|
|
849
|
+
clientId: this.config.clientId,
|
|
850
|
+
authority: `https://login.microsoftonline.com/${this.tid}`,
|
|
851
|
+
},
|
|
852
|
+
cache: {
|
|
853
|
+
cacheLocation: "sessionStorage",
|
|
854
|
+
},
|
|
855
|
+
};
|
|
856
|
+
this.msalInstance = new PublicClientApplication(msalConfig);
|
|
857
|
+
this.initialized = true;
|
|
921
858
|
});
|
|
922
|
-
}
|
|
859
|
+
}
|
|
923
860
|
/**
|
|
924
861
|
* Get SSO token using teams SDK
|
|
925
862
|
* It will try to get SSO token from memory first, if SSO token doesn't exist or about to expired, then it will using teams SDK to get SSO token
|
|
926
863
|
* @returns SSO token
|
|
927
864
|
*/
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
if (_this.ssoToken.expiresOnTimestamp - Date.now() > tokenRefreshTimeSpanInMillisecond) {
|
|
865
|
+
getSSOToken() {
|
|
866
|
+
return new Promise((resolve, reject) => {
|
|
867
|
+
if (this.ssoToken) {
|
|
868
|
+
if (this.ssoToken.expiresOnTimestamp - Date.now() > tokenRefreshTimeSpanInMillisecond) {
|
|
933
869
|
internalLogger.verbose("Get SSO token from memory cache");
|
|
934
|
-
resolve(
|
|
870
|
+
resolve(this.ssoToken);
|
|
935
871
|
return;
|
|
936
872
|
}
|
|
937
873
|
}
|
|
938
|
-
|
|
939
|
-
microsoftTeams.initialize(
|
|
874
|
+
let initialized = false;
|
|
875
|
+
microsoftTeams.initialize(() => {
|
|
940
876
|
initialized = true;
|
|
941
877
|
microsoftTeams.authentication.getAuthToken({
|
|
942
|
-
successCallback:
|
|
878
|
+
successCallback: (token) => {
|
|
943
879
|
if (!token) {
|
|
944
|
-
|
|
880
|
+
const errorMsg = "Get empty SSO token from Teams";
|
|
945
881
|
internalLogger.error(errorMsg);
|
|
946
882
|
reject(new ErrorWithCode(errorMsg, ErrorCode.InternalError));
|
|
947
883
|
return;
|
|
948
884
|
}
|
|
949
|
-
|
|
885
|
+
const tokenObject = parseJwt(token);
|
|
950
886
|
if (tokenObject.ver !== "1.0" && tokenObject.ver !== "2.0") {
|
|
951
|
-
|
|
887
|
+
const errorMsg = "SSO token is not valid with an unknown version: " + tokenObject.ver;
|
|
952
888
|
internalLogger.error(errorMsg);
|
|
953
889
|
reject(new ErrorWithCode(errorMsg, ErrorCode.InternalError));
|
|
954
890
|
return;
|
|
955
891
|
}
|
|
956
|
-
|
|
957
|
-
token
|
|
892
|
+
const ssoToken = {
|
|
893
|
+
token,
|
|
958
894
|
expiresOnTimestamp: tokenObject.exp * 1000,
|
|
959
895
|
};
|
|
960
|
-
|
|
896
|
+
this.ssoToken = ssoToken;
|
|
961
897
|
resolve(ssoToken);
|
|
962
898
|
},
|
|
963
|
-
failureCallback:
|
|
964
|
-
|
|
899
|
+
failureCallback: (errMessage) => {
|
|
900
|
+
const errorMsg = "Get SSO token failed with error: " + errMessage;
|
|
965
901
|
internalLogger.error(errorMsg);
|
|
966
902
|
reject(new ErrorWithCode(errorMsg, ErrorCode.InternalError));
|
|
967
903
|
},
|
|
@@ -969,178 +905,65 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
969
905
|
});
|
|
970
906
|
});
|
|
971
907
|
// If the code not running in Teams, the initialize callback function would never trigger
|
|
972
|
-
setTimeout(
|
|
908
|
+
setTimeout(() => {
|
|
973
909
|
if (!initialized) {
|
|
974
|
-
|
|
910
|
+
const errorMsg = "Initialize teams sdk timeout, maybe the code is not running inside Teams";
|
|
975
911
|
internalLogger.error(errorMsg);
|
|
976
912
|
reject(new ErrorWithCode(errorMsg, ErrorCode.InternalError));
|
|
977
913
|
}
|
|
978
914
|
}, initializeTeamsSdkTimeoutInMillisecond);
|
|
979
915
|
});
|
|
980
|
-
}
|
|
916
|
+
}
|
|
981
917
|
/**
|
|
982
918
|
* Load and validate authentication configuration
|
|
983
919
|
* @returns Authentication configuration
|
|
984
920
|
*/
|
|
985
|
-
|
|
921
|
+
loadAndValidateConfig() {
|
|
986
922
|
internalLogger.verbose("Validate authentication configuration");
|
|
987
|
-
|
|
923
|
+
const config = getAuthenticationConfiguration();
|
|
988
924
|
if (!config) {
|
|
989
925
|
internalLogger.error(ErrorMessage.AuthenticationConfigurationNotExists);
|
|
990
926
|
throw new ErrorWithCode(ErrorMessage.AuthenticationConfigurationNotExists, ErrorCode.InvalidConfiguration);
|
|
991
927
|
}
|
|
992
|
-
if (config.initiateLoginEndpoint && config.
|
|
928
|
+
if (config.initiateLoginEndpoint && config.clientId) {
|
|
993
929
|
return config;
|
|
994
930
|
}
|
|
995
|
-
|
|
931
|
+
const missingValues = [];
|
|
996
932
|
if (!config.initiateLoginEndpoint) {
|
|
997
933
|
missingValues.push("initiateLoginEndpoint");
|
|
998
934
|
}
|
|
999
|
-
if (!config.simpleAuthEndpoint) {
|
|
1000
|
-
missingValues.push("simpleAuthEndpoint");
|
|
1001
|
-
}
|
|
1002
935
|
if (!config.clientId) {
|
|
1003
936
|
missingValues.push("clientId");
|
|
1004
937
|
}
|
|
1005
|
-
|
|
938
|
+
const errorMsg = formatString(ErrorMessage.InvalidConfiguration, missingValues.join(", "), "undefined");
|
|
1006
939
|
internalLogger.error(errorMsg);
|
|
1007
940
|
throw new ErrorWithCode(errorMsg, ErrorCode.InvalidConfiguration);
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
* Get axios instance with sso token bearer header
|
|
1011
|
-
* @returns AxiosInstance
|
|
1012
|
-
*/
|
|
1013
|
-
TeamsUserCredential.prototype.getAxiosInstance = function () {
|
|
1014
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1015
|
-
var ssoToken, axiosInstance;
|
|
1016
|
-
return __generator(this, function (_a) {
|
|
1017
|
-
switch (_a.label) {
|
|
1018
|
-
case 0: return [4 /*yield*/, this.getSSOToken()];
|
|
1019
|
-
case 1:
|
|
1020
|
-
ssoToken = _a.sent();
|
|
1021
|
-
axiosInstance = axios.create({
|
|
1022
|
-
baseURL: this.config.simpleAuthEndpoint,
|
|
1023
|
-
});
|
|
1024
|
-
axiosInstance.interceptors.request.use(function (config) {
|
|
1025
|
-
config.headers.Authorization = "Bearer " + ssoToken.token;
|
|
1026
|
-
return config;
|
|
1027
|
-
});
|
|
1028
|
-
return [2 /*return*/, axiosInstance];
|
|
1029
|
-
}
|
|
1030
|
-
});
|
|
1031
|
-
});
|
|
1032
|
-
};
|
|
1033
|
-
/**
|
|
1034
|
-
* Set access token to cache
|
|
1035
|
-
* @param key
|
|
1036
|
-
* @param token
|
|
1037
|
-
*/
|
|
1038
|
-
TeamsUserCredential.prototype.setTokenCache = function (key, token) {
|
|
1039
|
-
Cache.set(key, JSON.stringify(token));
|
|
1040
|
-
};
|
|
1041
|
-
/**
|
|
1042
|
-
* Get access token from cache.
|
|
1043
|
-
* If there is no cache or cannot be parsed, then it will return null
|
|
1044
|
-
* @param key
|
|
1045
|
-
* @returns Access token or null
|
|
1046
|
-
*/
|
|
1047
|
-
TeamsUserCredential.prototype.getTokenCache = function (key) {
|
|
1048
|
-
var value = Cache.get(key);
|
|
1049
|
-
if (value === null) {
|
|
1050
|
-
return null;
|
|
1051
|
-
}
|
|
1052
|
-
var accessToken = this.validateAndParseJson(value);
|
|
1053
|
-
return accessToken;
|
|
1054
|
-
};
|
|
1055
|
-
/**
|
|
1056
|
-
* Parses passed value as JSON access token, if value is not a valid json string JSON.parse() will throw an error.
|
|
1057
|
-
* @param jsonValue
|
|
1058
|
-
*/
|
|
1059
|
-
TeamsUserCredential.prototype.validateAndParseJson = function (jsonValue) {
|
|
941
|
+
}
|
|
942
|
+
setSessionStorage(sessonStorageValues) {
|
|
1060
943
|
try {
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
* (e.g. JSON.parse will parse an escaped string into an unescaped string), so adding a type check
|
|
1065
|
-
* of the parsed value is necessary in order to be certain that the string represents a valid JSON object.
|
|
1066
|
-
*
|
|
1067
|
-
*/
|
|
1068
|
-
return parsedJson && typeof parsedJson === "object" ? parsedJson : null;
|
|
1069
|
-
}
|
|
1070
|
-
catch (error) {
|
|
1071
|
-
return null;
|
|
1072
|
-
}
|
|
1073
|
-
};
|
|
1074
|
-
/**
|
|
1075
|
-
* Generate cache key
|
|
1076
|
-
* @param scopesStr
|
|
1077
|
-
* @returns Access token cache key, a key example: accessToken-userId-clientId-tenantId-scopes
|
|
1078
|
-
*/
|
|
1079
|
-
TeamsUserCredential.prototype.getAccessTokenCacheKey = function (scopesStr) {
|
|
1080
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1081
|
-
var ssoToken, ssoTokenObj, clientId, userObjectId, tenantId, key;
|
|
1082
|
-
return __generator(this, function (_a) {
|
|
1083
|
-
switch (_a.label) {
|
|
1084
|
-
case 0: return [4 /*yield*/, this.getSSOToken()];
|
|
1085
|
-
case 1:
|
|
1086
|
-
ssoToken = _a.sent();
|
|
1087
|
-
ssoTokenObj = parseJwt(ssoToken.token);
|
|
1088
|
-
clientId = this.config.clientId;
|
|
1089
|
-
userObjectId = ssoTokenObj.oid;
|
|
1090
|
-
tenantId = ssoTokenObj.tid;
|
|
1091
|
-
key = [accessTokenCacheKeyPrefix, userObjectId, clientId, tenantId, scopesStr]
|
|
1092
|
-
.join(separator)
|
|
1093
|
-
.replace(/" "/g, "_");
|
|
1094
|
-
return [2 /*return*/, key];
|
|
1095
|
-
}
|
|
944
|
+
const sessionStorageKeys = Object.keys(sessonStorageValues);
|
|
945
|
+
sessionStorageKeys.forEach((key) => {
|
|
946
|
+
sessionStorage.setItem(key, sessonStorageValues[key]);
|
|
1096
947
|
});
|
|
1097
|
-
});
|
|
1098
|
-
};
|
|
1099
|
-
/**
|
|
1100
|
-
* Check whether the token is about to expire (within 5 minutes)
|
|
1101
|
-
* @returns Boolean value indicate whether the token is about to expire
|
|
1102
|
-
*/
|
|
1103
|
-
TeamsUserCredential.prototype.isAccessTokenNearExpired = function (token) {
|
|
1104
|
-
var expireDate = new Date(token.expiresOnTimestamp);
|
|
1105
|
-
if (expireDate.getTime() - Date.now() > tokenRefreshTimeSpanInMillisecond) {
|
|
1106
|
-
return false;
|
|
1107
948
|
}
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
errorMessage = err.response.data.detail;
|
|
1115
|
-
if (err.response.data.type === "AadUiRequiredException") {
|
|
1116
|
-
var fullErrorMsg_1 = "Failed to get access token from authentication server, please login first: " +
|
|
1117
|
-
errorMessage;
|
|
1118
|
-
internalLogger.warn(fullErrorMsg_1);
|
|
1119
|
-
return new ErrorWithCode(fullErrorMsg_1, ErrorCode.UiRequiredError);
|
|
1120
|
-
}
|
|
1121
|
-
else {
|
|
1122
|
-
var fullErrorMsg_2 = "Failed to get access token from authentication server: " + errorMessage;
|
|
1123
|
-
internalLogger.error(fullErrorMsg_2);
|
|
1124
|
-
return new ErrorWithCode(fullErrorMsg_2, ErrorCode.ServiceError);
|
|
1125
|
-
}
|
|
949
|
+
catch (error) {
|
|
950
|
+
// Values in result.sessionStorage can not be set into session storage.
|
|
951
|
+
// Throw error since this may block user.
|
|
952
|
+
const errorMessage = `Failed to set values in session storage. Error: ${error.message}`;
|
|
953
|
+
internalLogger.error(errorMessage);
|
|
954
|
+
throw new ErrorWithCode(errorMessage, ErrorCode.InternalError);
|
|
1126
955
|
}
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
};
|
|
1130
|
-
TeamsUserCredential.prototype.sleep = function (ms) {
|
|
1131
|
-
return new Promise(function (resolve) { return setTimeout(resolve, ms); });
|
|
1132
|
-
};
|
|
1133
|
-
return TeamsUserCredential;
|
|
1134
|
-
}());
|
|
956
|
+
}
|
|
957
|
+
}
|
|
1135
958
|
|
|
1136
959
|
// Copyright (c) Microsoft Corporation.
|
|
1137
|
-
|
|
960
|
+
const defaultScope = "https://graph.microsoft.com/.default";
|
|
1138
961
|
/**
|
|
1139
962
|
* Microsoft Graph auth provider for Teams Framework
|
|
1140
963
|
*
|
|
1141
964
|
* @beta
|
|
1142
965
|
*/
|
|
1143
|
-
|
|
966
|
+
class MsGraphAuthProvider {
|
|
1144
967
|
/**
|
|
1145
968
|
* Constructor of MsGraphAuthProvider.
|
|
1146
969
|
*
|
|
@@ -1153,9 +976,9 @@ var MsGraphAuthProvider = /** @class */ (function () {
|
|
|
1153
976
|
*
|
|
1154
977
|
* @beta
|
|
1155
978
|
*/
|
|
1156
|
-
|
|
979
|
+
constructor(credential, scopes) {
|
|
1157
980
|
this.credential = credential;
|
|
1158
|
-
|
|
981
|
+
let scopesStr = defaultScope;
|
|
1159
982
|
if (scopes) {
|
|
1160
983
|
validateScopesType(scopes);
|
|
1161
984
|
scopesStr = typeof scopes === "string" ? scopes : scopes.join(" ");
|
|
@@ -1163,7 +986,7 @@ var MsGraphAuthProvider = /** @class */ (function () {
|
|
|
1163
986
|
scopesStr = defaultScope;
|
|
1164
987
|
}
|
|
1165
988
|
}
|
|
1166
|
-
internalLogger.info(
|
|
989
|
+
internalLogger.info(`Create Microsoft Graph Authentication Provider with scopes: '${scopesStr}'`);
|
|
1167
990
|
this.scopes = scopesStr;
|
|
1168
991
|
}
|
|
1169
992
|
/**
|
|
@@ -1178,32 +1001,23 @@ var MsGraphAuthProvider = /** @class */ (function () {
|
|
|
1178
1001
|
* @returns Access token from the credential.
|
|
1179
1002
|
*
|
|
1180
1003
|
*/
|
|
1181
|
-
|
|
1182
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
resolve(accessToken.token);
|
|
1194
|
-
}
|
|
1195
|
-
else {
|
|
1196
|
-
var errorMsg = "Graph access token is undefined or empty";
|
|
1197
|
-
internalLogger.error(errorMsg);
|
|
1198
|
-
reject(new ErrorWithCode(errorMsg, ErrorCode.InternalError));
|
|
1199
|
-
}
|
|
1200
|
-
})];
|
|
1004
|
+
getAccessToken() {
|
|
1005
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1006
|
+
internalLogger.info(`Get Graph Access token with scopes: '${this.scopes}'`);
|
|
1007
|
+
const accessToken = yield this.credential.getToken(this.scopes);
|
|
1008
|
+
return new Promise((resolve, reject) => {
|
|
1009
|
+
if (accessToken) {
|
|
1010
|
+
resolve(accessToken.token);
|
|
1011
|
+
}
|
|
1012
|
+
else {
|
|
1013
|
+
const errorMsg = "Graph access token is undefined or empty";
|
|
1014
|
+
internalLogger.error(errorMsg);
|
|
1015
|
+
reject(new ErrorWithCode(errorMsg, ErrorCode.InternalError));
|
|
1201
1016
|
}
|
|
1202
1017
|
});
|
|
1203
1018
|
});
|
|
1204
|
-
}
|
|
1205
|
-
|
|
1206
|
-
}());
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1207
1021
|
|
|
1208
1022
|
// Copyright (c) Microsoft Corporation.
|
|
1209
1023
|
/**
|
|
@@ -1259,9 +1073,9 @@ var MsGraphAuthProvider = /** @class */ (function () {
|
|
|
1259
1073
|
*/
|
|
1260
1074
|
function createMicrosoftGraphClient(credential, scopes) {
|
|
1261
1075
|
internalLogger.info("Create Microsoft Graph Client");
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
authProvider
|
|
1076
|
+
const authProvider = new MsGraphAuthProvider(credential, scopes);
|
|
1077
|
+
const graphClient = Client.initWithMiddleware({
|
|
1078
|
+
authProvider,
|
|
1265
1079
|
});
|
|
1266
1080
|
return graphClient;
|
|
1267
1081
|
}
|
|
@@ -1272,8 +1086,8 @@ function createMicrosoftGraphClient(credential, scopes) {
|
|
|
1272
1086
|
* Only works in in server side.
|
|
1273
1087
|
* @beta
|
|
1274
1088
|
*/
|
|
1275
|
-
|
|
1276
|
-
|
|
1089
|
+
class DefaultTediousConnectionConfiguration {
|
|
1090
|
+
constructor() {
|
|
1277
1091
|
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "DefaultTediousConnectionConfiguration"), ErrorCode.RuntimeNotSupported);
|
|
1278
1092
|
}
|
|
1279
1093
|
/**
|
|
@@ -1282,15 +1096,12 @@ var DefaultTediousConnectionConfiguration = /** @class */ (function () {
|
|
|
1282
1096
|
* Only works in in server side.
|
|
1283
1097
|
* @beta
|
|
1284
1098
|
*/
|
|
1285
|
-
|
|
1286
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1287
|
-
|
|
1288
|
-
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "DefaultTediousConnectionConfiguration"), ErrorCode.RuntimeNotSupported);
|
|
1289
|
-
});
|
|
1099
|
+
getConfig(databaseName) {
|
|
1100
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1101
|
+
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "DefaultTediousConnectionConfiguration"), ErrorCode.RuntimeNotSupported);
|
|
1290
1102
|
});
|
|
1291
|
-
}
|
|
1292
|
-
|
|
1293
|
-
}());
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1294
1105
|
|
|
1295
1106
|
// Copyright (c) Microsoft Corporation.
|
|
1296
1107
|
/**
|
|
@@ -1344,7 +1155,7 @@ var DefaultTediousConnectionConfiguration = /** @class */ (function () {
|
|
|
1344
1155
|
*
|
|
1345
1156
|
* @beta
|
|
1346
1157
|
*/
|
|
1347
|
-
|
|
1158
|
+
class TeamsBotSsoPrompt {
|
|
1348
1159
|
/**
|
|
1349
1160
|
* Constructor of TeamsBotSsoPrompt.
|
|
1350
1161
|
*
|
|
@@ -1356,7 +1167,7 @@ var TeamsBotSsoPrompt = /** @class */ (function () {
|
|
|
1356
1167
|
*
|
|
1357
1168
|
* @beta
|
|
1358
1169
|
*/
|
|
1359
|
-
|
|
1170
|
+
constructor(dialogId, settings) {
|
|
1360
1171
|
this.settings = settings;
|
|
1361
1172
|
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "TeamsBotSsoPrompt"), ErrorCode.RuntimeNotSupported);
|
|
1362
1173
|
}
|
|
@@ -1376,13 +1187,11 @@ var TeamsBotSsoPrompt = /** @class */ (function () {
|
|
|
1376
1187
|
*
|
|
1377
1188
|
* @beta
|
|
1378
1189
|
*/
|
|
1379
|
-
|
|
1380
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1381
|
-
|
|
1382
|
-
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "TeamsBotSsoPrompt"), ErrorCode.RuntimeNotSupported);
|
|
1383
|
-
});
|
|
1190
|
+
beginDialog(dc) {
|
|
1191
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1192
|
+
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "TeamsBotSsoPrompt"), ErrorCode.RuntimeNotSupported);
|
|
1384
1193
|
});
|
|
1385
|
-
}
|
|
1194
|
+
}
|
|
1386
1195
|
/**
|
|
1387
1196
|
* Called when a prompt dialog is the active dialog and the user replied with a new activity.
|
|
1388
1197
|
*
|
|
@@ -1401,15 +1210,12 @@ var TeamsBotSsoPrompt = /** @class */ (function () {
|
|
|
1401
1210
|
*
|
|
1402
1211
|
* @beta
|
|
1403
1212
|
*/
|
|
1404
|
-
|
|
1405
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1406
|
-
|
|
1407
|
-
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "TeamsBotSsoPrompt"), ErrorCode.RuntimeNotSupported);
|
|
1408
|
-
});
|
|
1213
|
+
continueDialog(dc) {
|
|
1214
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1215
|
+
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "TeamsBotSsoPrompt"), ErrorCode.RuntimeNotSupported);
|
|
1409
1216
|
});
|
|
1410
|
-
}
|
|
1411
|
-
|
|
1412
|
-
}());
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1413
1219
|
|
|
1414
1220
|
export { DefaultTediousConnectionConfiguration, ErrorCode, ErrorWithCode, LogLevel, M365TenantCredential, MsGraphAuthProvider, OnBehalfOfUserCredential, ResourceType, TeamsBotSsoPrompt, TeamsUserCredential, createMicrosoftGraphClient, getAuthenticationConfiguration, getLogLevel, getResourceConfiguration, loadConfiguration, setLogFunction, setLogLevel, setLogger };
|
|
1415
1221
|
//# sourceMappingURL=index.esm5.js.map
|