@microsoft/teamsfx 0.4.1-rc.0 → 0.4.2-alpha.eb4575da.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/dist/index.esm2017.js +132 -382
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +10 -2
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +183 -490
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +10 -2
- package/dist/index.node.cjs.js.map +1 -1
- package/package.json +6 -6
- package/types/teamsfx.d.ts +1 -1
package/dist/index.esm5.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { __extends, __awaiter, __generator } from 'tslib';
|
|
2
2
|
import jwt_decode from 'jwt-decode';
|
|
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
|
-
import { ManagedIdentityCredential } from '@azure/identity';
|
|
7
6
|
|
|
8
7
|
// Copyright (c) Microsoft Corporation.
|
|
9
8
|
/**
|
|
@@ -176,7 +175,7 @@ function getLogLevel() {
|
|
|
176
175
|
return internalLogger.level;
|
|
177
176
|
}
|
|
178
177
|
var InternalLogger = /** @class */ (function () {
|
|
179
|
-
function InternalLogger() {
|
|
178
|
+
function InternalLogger(name, logLevel) {
|
|
180
179
|
this.level = undefined;
|
|
181
180
|
this.defaultLogger = {
|
|
182
181
|
verbose: console.debug,
|
|
@@ -184,6 +183,8 @@ var InternalLogger = /** @class */ (function () {
|
|
|
184
183
|
warn: console.warn,
|
|
185
184
|
error: console.error,
|
|
186
185
|
};
|
|
186
|
+
this.name = name;
|
|
187
|
+
this.level = logLevel;
|
|
187
188
|
}
|
|
188
189
|
InternalLogger.prototype.error = function (message) {
|
|
189
190
|
this.log(LogLevel.Error, function (x) { return x.error; }, message);
|
|
@@ -202,7 +203,13 @@ var InternalLogger = /** @class */ (function () {
|
|
|
202
203
|
return;
|
|
203
204
|
}
|
|
204
205
|
var timestamp = new Date().toUTCString();
|
|
205
|
-
var logHeader
|
|
206
|
+
var logHeader;
|
|
207
|
+
if (this.name) {
|
|
208
|
+
logHeader = "[" + timestamp + "] : @microsoft/teamsfx - " + this.name + " : " + LogLevel[logLevel] + " - ";
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
logHeader = "[" + timestamp + "] : @microsoft/teamsfx : " + LogLevel[logLevel] + " - ";
|
|
212
|
+
}
|
|
206
213
|
var logMessage = "" + logHeader + message;
|
|
207
214
|
if (this.level !== undefined && this.level <= logLevel) {
|
|
208
215
|
if (this.customLogger) {
|
|
@@ -311,6 +318,57 @@ function getUserInfoFromSsoToken(ssoToken) {
|
|
|
311
318
|
}
|
|
312
319
|
return userInfo;
|
|
313
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* @internal
|
|
323
|
+
*/
|
|
324
|
+
function getTenantIdAndLoginHintFromSsoToken(ssoToken) {
|
|
325
|
+
if (!ssoToken) {
|
|
326
|
+
var errorMsg = "SSO token is undefined.";
|
|
327
|
+
internalLogger.error(errorMsg);
|
|
328
|
+
throw new ErrorWithCode(errorMsg, ErrorCode.InvalidParameter);
|
|
329
|
+
}
|
|
330
|
+
var tokenObject = parseJwt(ssoToken);
|
|
331
|
+
var userInfo = {
|
|
332
|
+
tid: tokenObject.tid,
|
|
333
|
+
loginHint: tokenObject.ver === "2.0"
|
|
334
|
+
? tokenObject.preferred_username
|
|
335
|
+
: tokenObject.upn,
|
|
336
|
+
};
|
|
337
|
+
return userInfo;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* @internal
|
|
341
|
+
*/
|
|
342
|
+
function parseAccessTokenFromAuthCodeTokenResponse(tokenResponse) {
|
|
343
|
+
try {
|
|
344
|
+
var tokenResponseObject = typeof tokenResponse == "string"
|
|
345
|
+
? JSON.parse(tokenResponse)
|
|
346
|
+
: tokenResponse;
|
|
347
|
+
if (!tokenResponseObject || !tokenResponseObject.accessToken) {
|
|
348
|
+
var errorMsg = "Get empty access token from Auth Code token response.";
|
|
349
|
+
internalLogger.error(errorMsg);
|
|
350
|
+
throw new Error(errorMsg);
|
|
351
|
+
}
|
|
352
|
+
var token = tokenResponseObject.accessToken;
|
|
353
|
+
var tokenObject = parseJwt(token);
|
|
354
|
+
if (tokenObject.ver !== "1.0" && tokenObject.ver !== "2.0") {
|
|
355
|
+
var errorMsg = "SSO token is not valid with an unknown version: " + tokenObject.ver;
|
|
356
|
+
internalLogger.error(errorMsg);
|
|
357
|
+
throw new Error(errorMsg);
|
|
358
|
+
}
|
|
359
|
+
var accessToken = {
|
|
360
|
+
token: token,
|
|
361
|
+
expiresOnTimestamp: tokenObject.exp * 1000,
|
|
362
|
+
};
|
|
363
|
+
return accessToken;
|
|
364
|
+
}
|
|
365
|
+
catch (error) {
|
|
366
|
+
var errorMsg = "Parse access token failed from Auth Code token response in node env with error: " +
|
|
367
|
+
error.message;
|
|
368
|
+
internalLogger.error(errorMsg);
|
|
369
|
+
throw new ErrorWithCode(errorMsg, ErrorCode.InternalError);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
314
372
|
/**
|
|
315
373
|
* Format string template with replacements
|
|
316
374
|
*
|
|
@@ -565,46 +623,10 @@ var OnBehalfOfUserCredential = /** @class */ (function () {
|
|
|
565
623
|
}());
|
|
566
624
|
|
|
567
625
|
// Copyright (c) Microsoft Corporation.
|
|
568
|
-
// Licensed under the MIT license.
|
|
569
|
-
/**
|
|
570
|
-
* Configuration used in initialization.
|
|
571
|
-
* @internal
|
|
572
|
-
*/
|
|
573
|
-
var Cache = /** @class */ (function () {
|
|
574
|
-
function Cache() {
|
|
575
|
-
}
|
|
576
|
-
Cache.get = function (key) {
|
|
577
|
-
return sessionStorage.getItem(key);
|
|
578
|
-
};
|
|
579
|
-
Cache.set = function (key, value) {
|
|
580
|
-
sessionStorage.setItem(key, value);
|
|
581
|
-
};
|
|
582
|
-
Cache.remove = function (key) {
|
|
583
|
-
sessionStorage.removeItem(key);
|
|
584
|
-
};
|
|
585
|
-
return Cache;
|
|
586
|
-
}());
|
|
587
|
-
|
|
588
|
-
// Copyright (c) Microsoft Corporation.
|
|
589
|
-
// Licensed under the MIT license.
|
|
590
|
-
/**
|
|
591
|
-
* @internal
|
|
592
|
-
*/
|
|
593
|
-
var GrantType;
|
|
594
|
-
(function (GrantType) {
|
|
595
|
-
GrantType["authCode"] = "authorization_code";
|
|
596
|
-
GrantType["ssoToken"] = "sso_token";
|
|
597
|
-
})(GrantType || (GrantType = {}));
|
|
598
|
-
|
|
599
|
-
// Copyright (c) Microsoft Corporation.
|
|
600
|
-
var accessTokenCacheKeyPrefix = "accessToken";
|
|
601
|
-
var separator = "-";
|
|
602
626
|
var tokenRefreshTimeSpanInMillisecond = 5 * 60 * 1000;
|
|
603
627
|
var initializeTeamsSdkTimeoutInMillisecond = 5000;
|
|
604
628
|
var loginPageWidth = 600;
|
|
605
629
|
var loginPageHeight = 535;
|
|
606
|
-
var maxRetryCount = 3;
|
|
607
|
-
var retryTimeSpanInMillisecond = 3000;
|
|
608
630
|
/**
|
|
609
631
|
* Represent Teams current user's identity, and it is used within Teams tab application.
|
|
610
632
|
*
|
|
@@ -622,7 +644,6 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
622
644
|
* ```typescript
|
|
623
645
|
* const config = {
|
|
624
646
|
* authentication: {
|
|
625
|
-
* runtimeConnectorEndpoint: "https://xxx.xxx.com",
|
|
626
647
|
* initiateLoginEndpoint: "https://localhost:3000/auth-start.html",
|
|
627
648
|
* clientId: "xxx"
|
|
628
649
|
* }
|
|
@@ -640,6 +661,7 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
640
661
|
internalLogger.info("Create teams user credential");
|
|
641
662
|
this.config = this.loadAndValidateConfig();
|
|
642
663
|
this.ssoToken = null;
|
|
664
|
+
this.initialized = false;
|
|
643
665
|
}
|
|
644
666
|
/**
|
|
645
667
|
* Popup login page to get user's access token with specific scopes.
|
|
@@ -657,7 +679,6 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
657
679
|
* @param scopes - The list of scopes for which the token will have access, before that, we will request user to consent.
|
|
658
680
|
*
|
|
659
681
|
* @throws {@link ErrorCode|InternalError} when failed to login with unknown error.
|
|
660
|
-
* @throws {@link ErrorCode|ServiceError} when simple auth server failed to exchange access token.
|
|
661
682
|
* @throws {@link ErrorCode|ConsentFailed} when user canceled or failed to consent.
|
|
662
683
|
* @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
|
|
663
684
|
* @throws {@link ErrorCode|RuntimeNotSupported} when runtime is nodeJS.
|
|
@@ -669,51 +690,50 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
669
690
|
var scopesStr;
|
|
670
691
|
var _this = this;
|
|
671
692
|
return __generator(this, function (_a) {
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
resolve();
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
},
|
|
693
|
+
switch (_a.label) {
|
|
694
|
+
case 0:
|
|
695
|
+
validateScopesType(scopes);
|
|
696
|
+
scopesStr = typeof scopes === "string" ? scopes : scopes.join(" ");
|
|
697
|
+
internalLogger.info("Popup login page to get user's access token with scopes: " + scopesStr);
|
|
698
|
+
if (!!this.initialized) return [3 /*break*/, 2];
|
|
699
|
+
return [4 /*yield*/, this.init()];
|
|
700
|
+
case 1:
|
|
701
|
+
_a.sent();
|
|
702
|
+
_a.label = 2;
|
|
703
|
+
case 2: return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
704
|
+
microsoftTeams.initialize(function () {
|
|
705
|
+
microsoftTeams.authentication.authenticate({
|
|
706
|
+
url: _this.config.initiateLoginEndpoint + "?clientId=" + _this.config.clientId + "&scope=" + encodeURI(scopesStr) + "&loginHint=" + _this.loginHint,
|
|
707
|
+
width: loginPageWidth,
|
|
708
|
+
height: loginPageHeight,
|
|
709
|
+
successCallback: function (result) { return __awaiter(_this, void 0, void 0, function () {
|
|
710
|
+
var errorMsg, accessToken;
|
|
711
|
+
return __generator(this, function (_a) {
|
|
712
|
+
if (!result) {
|
|
713
|
+
errorMsg = "Get empty authentication result from MSAL";
|
|
714
|
+
internalLogger.error(errorMsg);
|
|
715
|
+
reject(new ErrorWithCode(errorMsg, ErrorCode.InternalError));
|
|
716
|
+
return [2 /*return*/];
|
|
717
|
+
}
|
|
718
|
+
try {
|
|
719
|
+
accessToken = parseAccessTokenFromAuthCodeTokenResponse(result);
|
|
720
|
+
resolve(accessToken);
|
|
721
|
+
}
|
|
722
|
+
catch (error) {
|
|
723
|
+
reject(error);
|
|
724
|
+
}
|
|
725
|
+
return [2 /*return*/];
|
|
726
|
+
});
|
|
727
|
+
}); },
|
|
728
|
+
failureCallback: function (reason) {
|
|
729
|
+
var errorMsg = "Consent failed for the scope " + scopesStr + " with error: " + reason;
|
|
730
|
+
internalLogger.error(errorMsg);
|
|
731
|
+
reject(new ErrorWithCode(errorMsg, ErrorCode.ConsentFailed));
|
|
732
|
+
},
|
|
733
|
+
});
|
|
714
734
|
});
|
|
715
|
-
});
|
|
716
|
-
|
|
735
|
+
})];
|
|
736
|
+
}
|
|
717
737
|
});
|
|
718
738
|
});
|
|
719
739
|
};
|
|
@@ -741,7 +761,6 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
741
761
|
*
|
|
742
762
|
* @throws {@link ErrorCode|InternalError} when failed to get access token with unknown error.
|
|
743
763
|
* @throws {@link ErrorCode|UiRequiredError} when need user consent to get access token.
|
|
744
|
-
* @throws {@link ErrorCode|ServiceError} when failed to get access token from simple auth server.
|
|
745
764
|
* @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
|
|
746
765
|
* @throws {@link ErrorCode|RuntimeNotSupported} when runtime is nodeJS.
|
|
747
766
|
*
|
|
@@ -754,7 +773,7 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
754
773
|
*/
|
|
755
774
|
TeamsUserCredential.prototype.getToken = function (scopes, options) {
|
|
756
775
|
return __awaiter(this, void 0, void 0, function () {
|
|
757
|
-
var ssoToken, scopeStr,
|
|
776
|
+
var ssoToken, scopeStr, tokenResponse, scopesArray, domain, account, scopesRequestForAcquireTokenSilent, error_1, acquireTokenSilentFailedMessage, scopesRequestForSsoSilent, error_2, ssoSilentFailedMessage, errorMsg, accessToken;
|
|
758
777
|
return __generator(this, function (_a) {
|
|
759
778
|
switch (_a.label) {
|
|
760
779
|
case 0:
|
|
@@ -768,25 +787,59 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
768
787
|
return [2 /*return*/, ssoToken];
|
|
769
788
|
case 2:
|
|
770
789
|
internalLogger.info("Get access token with scopes: " + scopeStr);
|
|
771
|
-
return [
|
|
790
|
+
if (!!this.initialized) return [3 /*break*/, 4];
|
|
791
|
+
return [4 /*yield*/, this.init()];
|
|
772
792
|
case 3:
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
if (cachedToken) {
|
|
776
|
-
if (!this.isAccessTokenNearExpired(cachedToken)) {
|
|
777
|
-
internalLogger.verbose("Get access token from cache");
|
|
778
|
-
return [2 /*return*/, cachedToken];
|
|
779
|
-
}
|
|
780
|
-
else {
|
|
781
|
-
internalLogger.verbose("Cached access token is expired");
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
else {
|
|
785
|
-
internalLogger.verbose("No cached access token");
|
|
786
|
-
}
|
|
787
|
-
return [4 /*yield*/, this.getAndCacheAccessTokenFromSimpleAuthServer(scopeStr)];
|
|
793
|
+
_a.sent();
|
|
794
|
+
_a.label = 4;
|
|
788
795
|
case 4:
|
|
789
|
-
|
|
796
|
+
tokenResponse = void 0;
|
|
797
|
+
scopesArray = typeof scopes === "string" ? scopes.split(" ") : scopes;
|
|
798
|
+
domain = window.location.origin;
|
|
799
|
+
_a.label = 5;
|
|
800
|
+
case 5:
|
|
801
|
+
_a.trys.push([5, 7, , 8]);
|
|
802
|
+
account = this.msalInstance.getAccountByUsername(this.loginHint);
|
|
803
|
+
scopesRequestForAcquireTokenSilent = {
|
|
804
|
+
scopes: scopesArray,
|
|
805
|
+
account: account !== null && account !== void 0 ? account : undefined,
|
|
806
|
+
redirectUri: domain + "/blank-auth-end.html",
|
|
807
|
+
};
|
|
808
|
+
return [4 /*yield*/, this.msalInstance.acquireTokenSilent(scopesRequestForAcquireTokenSilent)];
|
|
809
|
+
case 6:
|
|
810
|
+
tokenResponse = _a.sent();
|
|
811
|
+
return [3 /*break*/, 8];
|
|
812
|
+
case 7:
|
|
813
|
+
error_1 = _a.sent();
|
|
814
|
+
acquireTokenSilentFailedMessage = "Failed to call acquireTokenSilent. Reason: " + (error_1 === null || error_1 === void 0 ? void 0 : error_1.message) + ". ";
|
|
815
|
+
internalLogger.verbose(acquireTokenSilentFailedMessage);
|
|
816
|
+
return [3 /*break*/, 8];
|
|
817
|
+
case 8:
|
|
818
|
+
if (!!tokenResponse) return [3 /*break*/, 12];
|
|
819
|
+
_a.label = 9;
|
|
820
|
+
case 9:
|
|
821
|
+
_a.trys.push([9, 11, , 12]);
|
|
822
|
+
scopesRequestForSsoSilent = {
|
|
823
|
+
scopes: scopesArray,
|
|
824
|
+
loginHint: this.loginHint,
|
|
825
|
+
redirectUri: domain + "/blank-auth-end.html",
|
|
826
|
+
};
|
|
827
|
+
return [4 /*yield*/, this.msalInstance.ssoSilent(scopesRequestForSsoSilent)];
|
|
828
|
+
case 10:
|
|
829
|
+
tokenResponse = _a.sent();
|
|
830
|
+
return [3 /*break*/, 12];
|
|
831
|
+
case 11:
|
|
832
|
+
error_2 = _a.sent();
|
|
833
|
+
ssoSilentFailedMessage = "Failed to call ssoSilent. Reason: " + (error_2 === null || error_2 === void 0 ? void 0 : error_2.message) + ". ";
|
|
834
|
+
internalLogger.verbose(ssoSilentFailedMessage);
|
|
835
|
+
return [3 /*break*/, 12];
|
|
836
|
+
case 12:
|
|
837
|
+
if (!tokenResponse) {
|
|
838
|
+
errorMsg = "Failed to get access token cache silently, please login first: you need login first before get access token.";
|
|
839
|
+
internalLogger.error(errorMsg);
|
|
840
|
+
throw new ErrorWithCode(errorMsg, ErrorCode.UiRequiredError);
|
|
841
|
+
}
|
|
842
|
+
accessToken = parseAccessTokenFromAuthCodeTokenResponse(tokenResponse);
|
|
790
843
|
return [2 /*return*/, accessToken];
|
|
791
844
|
}
|
|
792
845
|
});
|
|
@@ -823,92 +876,29 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
823
876
|
});
|
|
824
877
|
});
|
|
825
878
|
};
|
|
826
|
-
TeamsUserCredential.prototype.
|
|
827
|
-
var _a, _b;
|
|
879
|
+
TeamsUserCredential.prototype.init = function () {
|
|
828
880
|
return __awaiter(this, void 0, void 0, function () {
|
|
829
|
-
var
|
|
830
|
-
return __generator(this, function (_c) {
|
|
831
|
-
switch (_c.label) {
|
|
832
|
-
case 0: return [4 /*yield*/, this.getAxiosInstance()];
|
|
833
|
-
case 1:
|
|
834
|
-
axiosInstance = _c.sent();
|
|
835
|
-
retryCount = 0;
|
|
836
|
-
_c.label = 2;
|
|
837
|
-
case 2:
|
|
838
|
-
_c.label = 3;
|
|
839
|
-
case 3:
|
|
840
|
-
_c.trys.push([3, 6, , 9]);
|
|
841
|
-
return [4 /*yield*/, axiosInstance.post("/auth/token", {
|
|
842
|
-
scope: scopesStr,
|
|
843
|
-
code: authCodeResult.code,
|
|
844
|
-
code_verifier: authCodeResult.codeVerifier,
|
|
845
|
-
redirect_uri: authCodeResult.redirectUri,
|
|
846
|
-
grant_type: GrantType.authCode,
|
|
847
|
-
})];
|
|
848
|
-
case 4:
|
|
849
|
-
response = _c.sent();
|
|
850
|
-
tokenResult = response.data;
|
|
851
|
-
return [4 /*yield*/, this.getAccessTokenCacheKey(scopesStr)];
|
|
852
|
-
case 5:
|
|
853
|
-
key = _c.sent();
|
|
854
|
-
// Important: tokens are stored in sessionStorage, read more here: https://aka.ms/teamsfx-session-storage-notice
|
|
855
|
-
this.setTokenCache(key, {
|
|
856
|
-
token: tokenResult.access_token,
|
|
857
|
-
expiresOnTimestamp: tokenResult.expires_on,
|
|
858
|
-
});
|
|
859
|
-
return [2 /*return*/];
|
|
860
|
-
case 6:
|
|
861
|
-
err_2 = _c.sent();
|
|
862
|
-
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];
|
|
863
|
-
internalLogger.warn("Exchange access token failed, retry...");
|
|
864
|
-
if (!(retryCount < maxRetryCount)) return [3 /*break*/, 8];
|
|
865
|
-
return [4 /*yield*/, this.sleep(retryTimeSpanInMillisecond)];
|
|
866
|
-
case 7:
|
|
867
|
-
_c.sent();
|
|
868
|
-
retryCount++;
|
|
869
|
-
return [3 /*break*/, 2];
|
|
870
|
-
case 8: throw err_2;
|
|
871
|
-
case 9: return [3 /*break*/, 2];
|
|
872
|
-
case 10: return [2 /*return*/];
|
|
873
|
-
}
|
|
874
|
-
});
|
|
875
|
-
});
|
|
876
|
-
};
|
|
877
|
-
/**
|
|
878
|
-
* Get access token cache from authentication server
|
|
879
|
-
* @returns Access token
|
|
880
|
-
*/
|
|
881
|
-
TeamsUserCredential.prototype.getAndCacheAccessTokenFromSimpleAuthServer = function (scopesStr) {
|
|
882
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
883
|
-
var axiosInstance, response, accessTokenResult, accessToken, cacheKey, err_3;
|
|
881
|
+
var ssoToken, info, msalConfig;
|
|
884
882
|
return __generator(this, function (_a) {
|
|
885
883
|
switch (_a.label) {
|
|
886
|
-
case 0:
|
|
887
|
-
_a.trys.push([0, 4, , 5]);
|
|
888
|
-
internalLogger.verbose("Get access token from authentication server with scopes: " + scopesStr);
|
|
889
|
-
return [4 /*yield*/, this.getAxiosInstance()];
|
|
884
|
+
case 0: return [4 /*yield*/, this.getSSOToken()];
|
|
890
885
|
case 1:
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
886
|
+
ssoToken = _a.sent();
|
|
887
|
+
info = getTenantIdAndLoginHintFromSsoToken(ssoToken.token);
|
|
888
|
+
this.loginHint = info.loginHint;
|
|
889
|
+
this.tid = info.tid;
|
|
890
|
+
msalConfig = {
|
|
891
|
+
auth: {
|
|
892
|
+
clientId: this.config.clientId,
|
|
893
|
+
authority: "https://login.microsoftonline.com/" + this.tid,
|
|
894
|
+
},
|
|
895
|
+
cache: {
|
|
896
|
+
cacheLocation: "sessionStorage",
|
|
897
|
+
},
|
|
902
898
|
};
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
this.setTokenCache(cacheKey, accessToken);
|
|
907
|
-
return [2 /*return*/, accessToken];
|
|
908
|
-
case 4:
|
|
909
|
-
err_3 = _a.sent();
|
|
910
|
-
throw this.generateAuthServerError(err_3);
|
|
911
|
-
case 5: return [2 /*return*/];
|
|
899
|
+
this.msalInstance = new PublicClientApplication(msalConfig);
|
|
900
|
+
this.initialized = true;
|
|
901
|
+
return [2 /*return*/];
|
|
912
902
|
}
|
|
913
903
|
});
|
|
914
904
|
});
|
|
@@ -982,16 +972,13 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
982
972
|
internalLogger.error(ErrorMessage.AuthenticationConfigurationNotExists);
|
|
983
973
|
throw new ErrorWithCode(ErrorMessage.AuthenticationConfigurationNotExists, ErrorCode.InvalidConfiguration);
|
|
984
974
|
}
|
|
985
|
-
if (config.initiateLoginEndpoint && config.
|
|
975
|
+
if (config.initiateLoginEndpoint && config.clientId) {
|
|
986
976
|
return config;
|
|
987
977
|
}
|
|
988
978
|
var missingValues = [];
|
|
989
979
|
if (!config.initiateLoginEndpoint) {
|
|
990
980
|
missingValues.push("initiateLoginEndpoint");
|
|
991
981
|
}
|
|
992
|
-
if (!config.simpleAuthEndpoint) {
|
|
993
|
-
missingValues.push("simpleAuthEndpoint");
|
|
994
|
-
}
|
|
995
982
|
if (!config.clientId) {
|
|
996
983
|
missingValues.push("clientId");
|
|
997
984
|
}
|
|
@@ -999,130 +986,6 @@ var TeamsUserCredential = /** @class */ (function () {
|
|
|
999
986
|
internalLogger.error(errorMsg);
|
|
1000
987
|
throw new ErrorWithCode(errorMsg, ErrorCode.InvalidConfiguration);
|
|
1001
988
|
};
|
|
1002
|
-
/**
|
|
1003
|
-
* Get axios instance with sso token bearer header
|
|
1004
|
-
* @returns AxiosInstance
|
|
1005
|
-
*/
|
|
1006
|
-
TeamsUserCredential.prototype.getAxiosInstance = function () {
|
|
1007
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1008
|
-
var ssoToken, axiosInstance;
|
|
1009
|
-
return __generator(this, function (_a) {
|
|
1010
|
-
switch (_a.label) {
|
|
1011
|
-
case 0: return [4 /*yield*/, this.getSSOToken()];
|
|
1012
|
-
case 1:
|
|
1013
|
-
ssoToken = _a.sent();
|
|
1014
|
-
axiosInstance = axios.create({
|
|
1015
|
-
baseURL: this.config.simpleAuthEndpoint,
|
|
1016
|
-
});
|
|
1017
|
-
axiosInstance.interceptors.request.use(function (config) {
|
|
1018
|
-
config.headers.Authorization = "Bearer " + ssoToken.token;
|
|
1019
|
-
return config;
|
|
1020
|
-
});
|
|
1021
|
-
return [2 /*return*/, axiosInstance];
|
|
1022
|
-
}
|
|
1023
|
-
});
|
|
1024
|
-
});
|
|
1025
|
-
};
|
|
1026
|
-
/**
|
|
1027
|
-
* Set access token to cache
|
|
1028
|
-
* @param key
|
|
1029
|
-
* @param token
|
|
1030
|
-
*/
|
|
1031
|
-
TeamsUserCredential.prototype.setTokenCache = function (key, token) {
|
|
1032
|
-
Cache.set(key, JSON.stringify(token));
|
|
1033
|
-
};
|
|
1034
|
-
/**
|
|
1035
|
-
* Get access token from cache.
|
|
1036
|
-
* If there is no cache or cannot be parsed, then it will return null
|
|
1037
|
-
* @param key
|
|
1038
|
-
* @returns Access token or null
|
|
1039
|
-
*/
|
|
1040
|
-
TeamsUserCredential.prototype.getTokenCache = function (key) {
|
|
1041
|
-
var value = Cache.get(key);
|
|
1042
|
-
if (value === null) {
|
|
1043
|
-
return null;
|
|
1044
|
-
}
|
|
1045
|
-
var accessToken = this.validateAndParseJson(value);
|
|
1046
|
-
return accessToken;
|
|
1047
|
-
};
|
|
1048
|
-
/**
|
|
1049
|
-
* Parses passed value as JSON access token, if value is not a valid json string JSON.parse() will throw an error.
|
|
1050
|
-
* @param jsonValue
|
|
1051
|
-
*/
|
|
1052
|
-
TeamsUserCredential.prototype.validateAndParseJson = function (jsonValue) {
|
|
1053
|
-
try {
|
|
1054
|
-
var parsedJson = JSON.parse(jsonValue);
|
|
1055
|
-
/**
|
|
1056
|
-
* There are edge cases in which JSON.parse will successfully parse a non-valid JSON object
|
|
1057
|
-
* (e.g. JSON.parse will parse an escaped string into an unescaped string), so adding a type check
|
|
1058
|
-
* of the parsed value is necessary in order to be certain that the string represents a valid JSON object.
|
|
1059
|
-
*
|
|
1060
|
-
*/
|
|
1061
|
-
return parsedJson && typeof parsedJson === "object" ? parsedJson : null;
|
|
1062
|
-
}
|
|
1063
|
-
catch (error) {
|
|
1064
|
-
return null;
|
|
1065
|
-
}
|
|
1066
|
-
};
|
|
1067
|
-
/**
|
|
1068
|
-
* Generate cache key
|
|
1069
|
-
* @param scopesStr
|
|
1070
|
-
* @returns Access token cache key, a key example: accessToken-userId-clientId-tenantId-scopes
|
|
1071
|
-
*/
|
|
1072
|
-
TeamsUserCredential.prototype.getAccessTokenCacheKey = function (scopesStr) {
|
|
1073
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1074
|
-
var ssoToken, ssoTokenObj, clientId, userObjectId, tenantId, key;
|
|
1075
|
-
return __generator(this, function (_a) {
|
|
1076
|
-
switch (_a.label) {
|
|
1077
|
-
case 0: return [4 /*yield*/, this.getSSOToken()];
|
|
1078
|
-
case 1:
|
|
1079
|
-
ssoToken = _a.sent();
|
|
1080
|
-
ssoTokenObj = parseJwt(ssoToken.token);
|
|
1081
|
-
clientId = this.config.clientId;
|
|
1082
|
-
userObjectId = ssoTokenObj.oid;
|
|
1083
|
-
tenantId = ssoTokenObj.tid;
|
|
1084
|
-
key = [accessTokenCacheKeyPrefix, userObjectId, clientId, tenantId, scopesStr]
|
|
1085
|
-
.join(separator)
|
|
1086
|
-
.replace(/" "/g, "_");
|
|
1087
|
-
return [2 /*return*/, key];
|
|
1088
|
-
}
|
|
1089
|
-
});
|
|
1090
|
-
});
|
|
1091
|
-
};
|
|
1092
|
-
/**
|
|
1093
|
-
* Check whether the token is about to expire (within 5 minutes)
|
|
1094
|
-
* @returns Boolean value indicate whether the token is about to expire
|
|
1095
|
-
*/
|
|
1096
|
-
TeamsUserCredential.prototype.isAccessTokenNearExpired = function (token) {
|
|
1097
|
-
var expireDate = new Date(token.expiresOnTimestamp);
|
|
1098
|
-
if (expireDate.getTime() - Date.now() > tokenRefreshTimeSpanInMillisecond) {
|
|
1099
|
-
return false;
|
|
1100
|
-
}
|
|
1101
|
-
return true;
|
|
1102
|
-
};
|
|
1103
|
-
TeamsUserCredential.prototype.generateAuthServerError = function (err) {
|
|
1104
|
-
var _a, _b;
|
|
1105
|
-
var errorMessage = err.message;
|
|
1106
|
-
if ((_b = (_a = err.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.type) {
|
|
1107
|
-
errorMessage = err.response.data.detail;
|
|
1108
|
-
if (err.response.data.type === "AadUiRequiredException") {
|
|
1109
|
-
var fullErrorMsg_1 = "Failed to get access token from authentication server, please login first: " +
|
|
1110
|
-
errorMessage;
|
|
1111
|
-
internalLogger.warn(fullErrorMsg_1);
|
|
1112
|
-
return new ErrorWithCode(fullErrorMsg_1, ErrorCode.UiRequiredError);
|
|
1113
|
-
}
|
|
1114
|
-
else {
|
|
1115
|
-
var fullErrorMsg_2 = "Failed to get access token from authentication server: " + errorMessage;
|
|
1116
|
-
internalLogger.error(fullErrorMsg_2);
|
|
1117
|
-
return new ErrorWithCode(fullErrorMsg_2, ErrorCode.ServiceError);
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
var fullErrorMsg = "Failed to get access token with error: " + errorMessage;
|
|
1121
|
-
return new ErrorWithCode(fullErrorMsg, ErrorCode.InternalError);
|
|
1122
|
-
};
|
|
1123
|
-
TeamsUserCredential.prototype.sleep = function (ms) {
|
|
1124
|
-
return new Promise(function (resolve) { return setTimeout(resolve, ms); });
|
|
1125
|
-
};
|
|
1126
989
|
return TeamsUserCredential;
|
|
1127
990
|
}());
|
|
1128
991
|
|
|
@@ -1259,201 +1122,31 @@ function createMicrosoftGraphClient(credential, scopes) {
|
|
|
1259
1122
|
return graphClient;
|
|
1260
1123
|
}
|
|
1261
1124
|
|
|
1262
|
-
// Copyright (c) Microsoft Corporation.
|
|
1263
1125
|
/**
|
|
1264
|
-
*
|
|
1126
|
+
* Generate connection configuration consumed by tedious.
|
|
1265
1127
|
* @remarks
|
|
1266
1128
|
* Only works in in server side.
|
|
1267
|
-
*
|
|
1268
1129
|
* @beta
|
|
1269
|
-
*
|
|
1270
1130
|
*/
|
|
1271
1131
|
var DefaultTediousConnectionConfiguration = /** @class */ (function () {
|
|
1272
1132
|
function DefaultTediousConnectionConfiguration() {
|
|
1273
|
-
|
|
1274
|
-
* MSSQL default scope
|
|
1275
|
-
* https://docs.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-connect-msi
|
|
1276
|
-
*/
|
|
1277
|
-
this.defaultSQLScope = "https://database.windows.net/";
|
|
1133
|
+
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "DefaultTediousConnectionConfiguration"), ErrorCode.RuntimeNotSupported);
|
|
1278
1134
|
}
|
|
1279
1135
|
/**
|
|
1280
1136
|
* Generate connection configuration consumed by tedious.
|
|
1281
|
-
*
|
|
1282
|
-
*
|
|
1283
|
-
*
|
|
1284
|
-
* @throws {@link ErrorCode|InvalidConfiguration} when SQL config resource configuration is invalid.
|
|
1285
|
-
* @throws {@link ErrorCode|InternalError} when get user MSI token failed or MSI token is invalid.
|
|
1286
|
-
* @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
|
|
1287
|
-
*
|
|
1137
|
+
* @remarks
|
|
1138
|
+
* Only works in in server side.
|
|
1288
1139
|
* @beta
|
|
1289
1140
|
*/
|
|
1290
1141
|
DefaultTediousConnectionConfiguration.prototype.getConfig = function () {
|
|
1291
1142
|
return __awaiter(this, void 0, void 0, function () {
|
|
1292
|
-
var configuration, errMsg, configWithUPS, configWithToken, error_1;
|
|
1293
|
-
return __generator(this, function (_a) {
|
|
1294
|
-
switch (_a.label) {
|
|
1295
|
-
case 0:
|
|
1296
|
-
internalLogger.info("Get SQL configuration");
|
|
1297
|
-
configuration = getResourceConfiguration(ResourceType.SQL);
|
|
1298
|
-
if (!configuration) {
|
|
1299
|
-
errMsg = "SQL resource configuration not exist";
|
|
1300
|
-
internalLogger.error(errMsg);
|
|
1301
|
-
throw new ErrorWithCode(errMsg, ErrorCode.InvalidConfiguration);
|
|
1302
|
-
}
|
|
1303
|
-
try {
|
|
1304
|
-
this.isSQLConfigurationValid(configuration);
|
|
1305
|
-
}
|
|
1306
|
-
catch (err) {
|
|
1307
|
-
throw err;
|
|
1308
|
-
}
|
|
1309
|
-
if (!this.isMsiAuthentication()) {
|
|
1310
|
-
configWithUPS = this.generateDefaultConfig(configuration);
|
|
1311
|
-
internalLogger.verbose("SQL configuration with username and password generated");
|
|
1312
|
-
return [2 /*return*/, configWithUPS];
|
|
1313
|
-
}
|
|
1314
|
-
_a.label = 1;
|
|
1315
|
-
case 1:
|
|
1316
|
-
_a.trys.push([1, 3, , 4]);
|
|
1317
|
-
return [4 /*yield*/, this.generateTokenConfig(configuration)];
|
|
1318
|
-
case 2:
|
|
1319
|
-
configWithToken = _a.sent();
|
|
1320
|
-
internalLogger.verbose("SQL configuration with MSI token generated");
|
|
1321
|
-
return [2 /*return*/, configWithToken];
|
|
1322
|
-
case 3:
|
|
1323
|
-
error_1 = _a.sent();
|
|
1324
|
-
throw error_1;
|
|
1325
|
-
case 4: return [2 /*return*/];
|
|
1326
|
-
}
|
|
1327
|
-
});
|
|
1328
|
-
});
|
|
1329
|
-
};
|
|
1330
|
-
/**
|
|
1331
|
-
* Check SQL use MSI identity or username and password.
|
|
1332
|
-
*
|
|
1333
|
-
* @returns false - login with SQL MSI identity, true - login with username and password.
|
|
1334
|
-
* @internal
|
|
1335
|
-
*/
|
|
1336
|
-
DefaultTediousConnectionConfiguration.prototype.isMsiAuthentication = function () {
|
|
1337
|
-
internalLogger.verbose("Check connection config using MSI access token or username and password");
|
|
1338
|
-
var configuration = getResourceConfiguration(ResourceType.SQL);
|
|
1339
|
-
if ((configuration === null || configuration === void 0 ? void 0 : configuration.sqlUsername) != null && (configuration === null || configuration === void 0 ? void 0 : configuration.sqlPassword) != null) {
|
|
1340
|
-
internalLogger.verbose("Login with username and password");
|
|
1341
|
-
return false;
|
|
1342
|
-
}
|
|
1343
|
-
internalLogger.verbose("Login with MSI identity");
|
|
1344
|
-
return true;
|
|
1345
|
-
};
|
|
1346
|
-
/**
|
|
1347
|
-
* check configuration is an available configurations.
|
|
1348
|
-
* @param { SqlConfiguration } sqlConfig
|
|
1349
|
-
*
|
|
1350
|
-
* @returns true - SQL configuration has a valid SQL endpoints, SQL username with password or identity ID.
|
|
1351
|
-
* false - configuration is not valid.
|
|
1352
|
-
* @internal
|
|
1353
|
-
*/
|
|
1354
|
-
DefaultTediousConnectionConfiguration.prototype.isSQLConfigurationValid = function (sqlConfig) {
|
|
1355
|
-
internalLogger.verbose("Check SQL configuration if valid");
|
|
1356
|
-
if (!sqlConfig.sqlServerEndpoint) {
|
|
1357
|
-
internalLogger.error("SQL configuration is not valid without SQL server endpoint exist");
|
|
1358
|
-
throw new ErrorWithCode("SQL configuration error without SQL server endpoint exist", ErrorCode.InvalidConfiguration);
|
|
1359
|
-
}
|
|
1360
|
-
if (!(sqlConfig.sqlUsername && sqlConfig.sqlPassword) && !sqlConfig.sqlIdentityId) {
|
|
1361
|
-
var errMsg = "SQL configuration is not valid without " + (sqlConfig.sqlIdentityId ? "" : "identity id ") + " " + (sqlConfig.sqlUsername ? "" : "SQL username ") + " " + (sqlConfig.sqlPassword ? "" : "SQL password") + " exist";
|
|
1362
|
-
internalLogger.error(errMsg);
|
|
1363
|
-
throw new ErrorWithCode(errMsg, ErrorCode.InvalidConfiguration);
|
|
1364
|
-
}
|
|
1365
|
-
internalLogger.verbose("SQL configuration is valid");
|
|
1366
|
-
};
|
|
1367
|
-
/**
|
|
1368
|
-
* Generate tedious connection configuration with default authentication type.
|
|
1369
|
-
*
|
|
1370
|
-
* @param { SqlConfiguration } SQL configuration with username and password.
|
|
1371
|
-
*
|
|
1372
|
-
* @returns Tedious connection configuration with username and password.
|
|
1373
|
-
* @internal
|
|
1374
|
-
*/
|
|
1375
|
-
DefaultTediousConnectionConfiguration.prototype.generateDefaultConfig = function (sqlConfig) {
|
|
1376
|
-
internalLogger.verbose("SQL server " + sqlConfig.sqlServerEndpoint + ", user name " + sqlConfig.sqlUsername + ", database name " + sqlConfig.sqlDatabaseName);
|
|
1377
|
-
var config = {
|
|
1378
|
-
server: sqlConfig.sqlServerEndpoint,
|
|
1379
|
-
authentication: {
|
|
1380
|
-
type: TediousAuthenticationType.default,
|
|
1381
|
-
options: {
|
|
1382
|
-
userName: sqlConfig.sqlUsername,
|
|
1383
|
-
password: sqlConfig.sqlPassword,
|
|
1384
|
-
},
|
|
1385
|
-
},
|
|
1386
|
-
options: {
|
|
1387
|
-
database: sqlConfig.sqlDatabaseName,
|
|
1388
|
-
encrypt: true,
|
|
1389
|
-
},
|
|
1390
|
-
};
|
|
1391
|
-
return config;
|
|
1392
|
-
};
|
|
1393
|
-
/**
|
|
1394
|
-
* Generate tedious connection configuration with azure-active-directory-access-token authentication type.
|
|
1395
|
-
*
|
|
1396
|
-
* @param { SqlConfiguration } SQL configuration with AAD access token.
|
|
1397
|
-
*
|
|
1398
|
-
* @returns Tedious connection configuration with access token.
|
|
1399
|
-
* @internal
|
|
1400
|
-
*/
|
|
1401
|
-
DefaultTediousConnectionConfiguration.prototype.generateTokenConfig = function (sqlConfig) {
|
|
1402
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1403
|
-
var token, credential, errMsg, config;
|
|
1404
1143
|
return __generator(this, function (_a) {
|
|
1405
|
-
|
|
1406
|
-
case 0:
|
|
1407
|
-
internalLogger.verbose("Generate tedious config with MSI token");
|
|
1408
|
-
_a.label = 1;
|
|
1409
|
-
case 1:
|
|
1410
|
-
_a.trys.push([1, 3, , 4]);
|
|
1411
|
-
credential = new ManagedIdentityCredential(sqlConfig.sqlIdentityId);
|
|
1412
|
-
return [4 /*yield*/, credential.getToken(this.defaultSQLScope)];
|
|
1413
|
-
case 2:
|
|
1414
|
-
token = _a.sent();
|
|
1415
|
-
return [3 /*break*/, 4];
|
|
1416
|
-
case 3:
|
|
1417
|
-
_a.sent();
|
|
1418
|
-
errMsg = "Get user MSI token failed";
|
|
1419
|
-
internalLogger.error(errMsg);
|
|
1420
|
-
throw new ErrorWithCode(errMsg, ErrorCode.InternalError);
|
|
1421
|
-
case 4:
|
|
1422
|
-
if (token) {
|
|
1423
|
-
config = {
|
|
1424
|
-
server: sqlConfig.sqlServerEndpoint,
|
|
1425
|
-
authentication: {
|
|
1426
|
-
type: TediousAuthenticationType.MSI,
|
|
1427
|
-
options: {
|
|
1428
|
-
token: token.token,
|
|
1429
|
-
},
|
|
1430
|
-
},
|
|
1431
|
-
options: {
|
|
1432
|
-
database: sqlConfig.sqlDatabaseName,
|
|
1433
|
-
encrypt: true,
|
|
1434
|
-
},
|
|
1435
|
-
};
|
|
1436
|
-
internalLogger.verbose("Generate token configuration success, server endpoint is " + sqlConfig.sqlServerEndpoint + ", database name is " + sqlConfig.sqlDatabaseName);
|
|
1437
|
-
return [2 /*return*/, config];
|
|
1438
|
-
}
|
|
1439
|
-
internalLogger.error("Generate token configuration, server endpoint is " + sqlConfig.sqlServerEndpoint + ", MSI token is not valid");
|
|
1440
|
-
throw new ErrorWithCode("MSI token is not valid", ErrorCode.InternalError);
|
|
1441
|
-
}
|
|
1144
|
+
throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "DefaultTediousConnectionConfiguration"), ErrorCode.RuntimeNotSupported);
|
|
1442
1145
|
});
|
|
1443
1146
|
});
|
|
1444
1147
|
};
|
|
1445
1148
|
return DefaultTediousConnectionConfiguration;
|
|
1446
|
-
}());
|
|
1447
|
-
/**
|
|
1448
|
-
* tedious connection config authentication type.
|
|
1449
|
-
* https://tediousjs.github.io/tedious/api-connection.html
|
|
1450
|
-
* @internal
|
|
1451
|
-
*/
|
|
1452
|
-
var TediousAuthenticationType;
|
|
1453
|
-
(function (TediousAuthenticationType) {
|
|
1454
|
-
TediousAuthenticationType["default"] = "default";
|
|
1455
|
-
TediousAuthenticationType["MSI"] = "azure-active-directory-access-token";
|
|
1456
|
-
})(TediousAuthenticationType || (TediousAuthenticationType = {}));
|
|
1149
|
+
}());
|
|
1457
1150
|
|
|
1458
1151
|
// Copyright (c) Microsoft Corporation.
|
|
1459
1152
|
/**
|