@microsoft/teamsfx 0.4.1 → 0.4.2-alpha.01a113d2.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.
@@ -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 axios from 'axios';
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
  /**
@@ -56,6 +55,10 @@ var ErrorCode;
56
55
  * Operation failed.
57
56
  */
58
57
  ErrorCode["FailedOperation"] = "FailedOperation";
58
+ /**
59
+ * Version of SDK and project does not match.
60
+ */
61
+ ErrorCode["ProjectNeedUpgrade"] = "ProjectNeedUpgrade";
59
62
  })(ErrorCode || (ErrorCode = {}));
60
63
  /**
61
64
  * @internal
@@ -176,7 +179,7 @@ function getLogLevel() {
176
179
  return internalLogger.level;
177
180
  }
178
181
  var InternalLogger = /** @class */ (function () {
179
- function InternalLogger() {
182
+ function InternalLogger(name, logLevel) {
180
183
  this.level = undefined;
181
184
  this.defaultLogger = {
182
185
  verbose: console.debug,
@@ -184,6 +187,8 @@ var InternalLogger = /** @class */ (function () {
184
187
  warn: console.warn,
185
188
  error: console.error,
186
189
  };
190
+ this.name = name;
191
+ this.level = logLevel;
187
192
  }
188
193
  InternalLogger.prototype.error = function (message) {
189
194
  this.log(LogLevel.Error, function (x) { return x.error; }, message);
@@ -202,7 +207,13 @@ var InternalLogger = /** @class */ (function () {
202
207
  return;
203
208
  }
204
209
  var timestamp = new Date().toUTCString();
205
- var logHeader = "[" + timestamp + "] : @microsoft/teamsfx : " + LogLevel[logLevel] + " - ";
210
+ var logHeader;
211
+ if (this.name) {
212
+ logHeader = "[" + timestamp + "] : @microsoft/teamsfx - " + this.name + " : " + LogLevel[logLevel] + " - ";
213
+ }
214
+ else {
215
+ logHeader = "[" + timestamp + "] : @microsoft/teamsfx : " + LogLevel[logLevel] + " - ";
216
+ }
206
217
  var logMessage = "" + logHeader + message;
207
218
  if (this.level !== undefined && this.level <= logLevel) {
208
219
  if (this.customLogger) {
@@ -311,6 +322,57 @@ function getUserInfoFromSsoToken(ssoToken) {
311
322
  }
312
323
  return userInfo;
313
324
  }
325
+ /**
326
+ * @internal
327
+ */
328
+ function getTenantIdAndLoginHintFromSsoToken(ssoToken) {
329
+ if (!ssoToken) {
330
+ var errorMsg = "SSO token is undefined.";
331
+ internalLogger.error(errorMsg);
332
+ throw new ErrorWithCode(errorMsg, ErrorCode.InvalidParameter);
333
+ }
334
+ var tokenObject = parseJwt(ssoToken);
335
+ var userInfo = {
336
+ tid: tokenObject.tid,
337
+ loginHint: tokenObject.ver === "2.0"
338
+ ? tokenObject.preferred_username
339
+ : tokenObject.upn,
340
+ };
341
+ return userInfo;
342
+ }
343
+ /**
344
+ * @internal
345
+ */
346
+ function parseAccessTokenFromAuthCodeTokenResponse(tokenResponse) {
347
+ try {
348
+ var tokenResponseObject = typeof tokenResponse == "string"
349
+ ? JSON.parse(tokenResponse)
350
+ : tokenResponse;
351
+ if (!tokenResponseObject || !tokenResponseObject.accessToken) {
352
+ var errorMsg = "Get empty access token from Auth Code token response.";
353
+ internalLogger.error(errorMsg);
354
+ throw new Error(errorMsg);
355
+ }
356
+ var token = tokenResponseObject.accessToken;
357
+ var tokenObject = parseJwt(token);
358
+ if (tokenObject.ver !== "1.0" && tokenObject.ver !== "2.0") {
359
+ var errorMsg = "SSO token is not valid with an unknown version: " + tokenObject.ver;
360
+ internalLogger.error(errorMsg);
361
+ throw new Error(errorMsg);
362
+ }
363
+ var accessToken = {
364
+ token: token,
365
+ expiresOnTimestamp: tokenObject.exp * 1000,
366
+ };
367
+ return accessToken;
368
+ }
369
+ catch (error) {
370
+ var errorMsg = "Parse access token failed from Auth Code token response in node env with error: " +
371
+ error.message;
372
+ internalLogger.error(errorMsg);
373
+ throw new ErrorWithCode(errorMsg, ErrorCode.InternalError);
374
+ }
375
+ }
314
376
  /**
315
377
  * Format string template with replacements
316
378
  *
@@ -565,46 +627,10 @@ var OnBehalfOfUserCredential = /** @class */ (function () {
565
627
  }());
566
628
 
567
629
  // 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
630
  var tokenRefreshTimeSpanInMillisecond = 5 * 60 * 1000;
603
631
  var initializeTeamsSdkTimeoutInMillisecond = 5000;
604
632
  var loginPageWidth = 600;
605
633
  var loginPageHeight = 535;
606
- var maxRetryCount = 3;
607
- var retryTimeSpanInMillisecond = 3000;
608
634
  /**
609
635
  * Represent Teams current user's identity, and it is used within Teams tab application.
610
636
  *
@@ -622,7 +648,6 @@ var TeamsUserCredential = /** @class */ (function () {
622
648
  * ```typescript
623
649
  * const config = {
624
650
  * authentication: {
625
- * runtimeConnectorEndpoint: "https://xxx.xxx.com",
626
651
  * initiateLoginEndpoint: "https://localhost:3000/auth-start.html",
627
652
  * clientId: "xxx"
628
653
  * }
@@ -640,6 +665,7 @@ var TeamsUserCredential = /** @class */ (function () {
640
665
  internalLogger.info("Create teams user credential");
641
666
  this.config = this.loadAndValidateConfig();
642
667
  this.ssoToken = null;
668
+ this.initialized = false;
643
669
  }
644
670
  /**
645
671
  * Popup login page to get user's access token with specific scopes.
@@ -657,7 +683,6 @@ var TeamsUserCredential = /** @class */ (function () {
657
683
  * @param scopes - The list of scopes for which the token will have access, before that, we will request user to consent.
658
684
  *
659
685
  * @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
686
  * @throws {@link ErrorCode|ConsentFailed} when user canceled or failed to consent.
662
687
  * @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
663
688
  * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is nodeJS.
@@ -669,51 +694,65 @@ var TeamsUserCredential = /** @class */ (function () {
669
694
  var scopesStr;
670
695
  var _this = this;
671
696
  return __generator(this, function (_a) {
672
- validateScopesType(scopes);
673
- scopesStr = typeof scopes === "string" ? scopes : scopes.join(" ");
674
- internalLogger.info("Popup login page to get user's access token with scopes: " + scopesStr);
675
- return [2 /*return*/, new Promise(function (resolve, reject) {
676
- microsoftTeams.initialize(function () {
677
- microsoftTeams.authentication.authenticate({
678
- url: _this.config.initiateLoginEndpoint + "?clientId=" + _this.config.clientId + "&scope=" + encodeURI(scopesStr),
679
- width: loginPageWidth,
680
- height: loginPageHeight,
681
- successCallback: function (result) { return __awaiter(_this, void 0, void 0, function () {
682
- var errorMsg, authCodeResult, err_1;
683
- return __generator(this, function (_a) {
684
- switch (_a.label) {
685
- case 0:
686
- if (!result) {
687
- errorMsg = "Get empty authentication result from Teams";
688
- internalLogger.error(errorMsg);
689
- reject(new ErrorWithCode(errorMsg, ErrorCode.InternalError));
690
- return [2 /*return*/];
691
- }
692
- authCodeResult = JSON.parse(result);
693
- _a.label = 1;
694
- case 1:
695
- _a.trys.push([1, 3, , 4]);
696
- return [4 /*yield*/, this.exchangeAccessTokenFromSimpleAuthServer(scopesStr, authCodeResult)];
697
- case 2:
698
- _a.sent();
697
+ switch (_a.label) {
698
+ case 0:
699
+ validateScopesType(scopes);
700
+ scopesStr = typeof scopes === "string" ? scopes : scopes.join(" ");
701
+ internalLogger.info("Popup login page to get user's access token with scopes: " + scopesStr);
702
+ if (!!this.initialized) return [3 /*break*/, 2];
703
+ return [4 /*yield*/, this.init()];
704
+ case 1:
705
+ _a.sent();
706
+ _a.label = 2;
707
+ case 2: return [2 /*return*/, new Promise(function (resolve, reject) {
708
+ microsoftTeams.initialize(function () {
709
+ microsoftTeams.authentication.authenticate({
710
+ url: _this.config.initiateLoginEndpoint + "?clientId=" + _this.config.clientId + "&scope=" + encodeURI(scopesStr) + "&loginHint=" + _this.loginHint,
711
+ width: loginPageWidth,
712
+ height: loginPageHeight,
713
+ successCallback: function (result) { return __awaiter(_this, void 0, void 0, function () {
714
+ var errorMsg, resultJson, failedToParseResult, helpLink, usingPreviousAuthPage;
715
+ return __generator(this, function (_a) {
716
+ if (!result) {
717
+ errorMsg = "Get empty authentication result from MSAL";
718
+ internalLogger.error(errorMsg);
719
+ reject(new ErrorWithCode(errorMsg, ErrorCode.InternalError));
720
+ return [2 /*return*/];
721
+ }
722
+ resultJson = {};
723
+ try {
724
+ resultJson = JSON.parse(result);
725
+ }
726
+ catch (error) {
727
+ failedToParseResult = "Failed to parse result to Json.";
728
+ internalLogger.verbose(failedToParseResult);
699
729
  resolve();
700
- return [3 /*break*/, 4];
701
- case 3:
702
- err_1 = _a.sent();
703
- reject(this.generateAuthServerError(err_1));
704
- return [3 /*break*/, 4];
705
- case 4: return [2 /*return*/];
706
- }
707
- });
708
- }); },
709
- failureCallback: function (reason) {
710
- var errorMsg = "Consent failed for the scope " + scopesStr + " with error: " + reason;
711
- internalLogger.error(errorMsg);
712
- reject(new ErrorWithCode(errorMsg, ErrorCode.ConsentFailed));
713
- },
730
+ return [2 /*return*/];
731
+ }
732
+ // If code exists in result, user may using previous auth-start and auth-end page.
733
+ if (resultJson.code) {
734
+ helpLink = "https://aka.ms/teamsfx-auth-code-flow";
735
+ usingPreviousAuthPage = "Found auth code in response. You may be using the latest TeamsFx SDK on an old project." +
736
+ ("Please refer to the help link for how to fix the issue: " + helpLink + ".");
737
+ reject(new ErrorWithCode(usingPreviousAuthPage, ErrorCode.ProjectNeedUpgrade));
738
+ }
739
+ // If sessionStorage exists in result, set the values in current session storage.
740
+ if (resultJson.sessionStorage) {
741
+ this.setSessionStorage(resultJson.sessionStorage);
742
+ }
743
+ resolve();
744
+ return [2 /*return*/];
745
+ });
746
+ }); },
747
+ failureCallback: function (reason) {
748
+ var errorMsg = "Consent failed for the scope " + scopesStr + " with error: " + reason;
749
+ internalLogger.error(errorMsg);
750
+ reject(new ErrorWithCode(errorMsg, ErrorCode.ConsentFailed));
751
+ },
752
+ });
714
753
  });
715
- });
716
- })];
754
+ })];
755
+ }
717
756
  });
718
757
  });
719
758
  };
@@ -741,7 +780,6 @@ var TeamsUserCredential = /** @class */ (function () {
741
780
  *
742
781
  * @throws {@link ErrorCode|InternalError} when failed to get access token with unknown error.
743
782
  * @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
783
  * @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
746
784
  * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is nodeJS.
747
785
  *
@@ -754,7 +792,7 @@ var TeamsUserCredential = /** @class */ (function () {
754
792
  */
755
793
  TeamsUserCredential.prototype.getToken = function (scopes, options) {
756
794
  return __awaiter(this, void 0, void 0, function () {
757
- var ssoToken, scopeStr, cachedKey, cachedToken, accessToken;
795
+ var ssoToken, scopeStr, tokenResponse, scopesArray, domain, account, scopesRequestForAcquireTokenSilent, error_1, acquireTokenSilentFailedMessage, scopesRequestForSsoSilent, error_2, ssoSilentFailedMessage, errorMsg, accessToken;
758
796
  return __generator(this, function (_a) {
759
797
  switch (_a.label) {
760
798
  case 0:
@@ -768,25 +806,59 @@ var TeamsUserCredential = /** @class */ (function () {
768
806
  return [2 /*return*/, ssoToken];
769
807
  case 2:
770
808
  internalLogger.info("Get access token with scopes: " + scopeStr);
771
- return [4 /*yield*/, this.getAccessTokenCacheKey(scopeStr)];
809
+ if (!!this.initialized) return [3 /*break*/, 4];
810
+ return [4 /*yield*/, this.init()];
772
811
  case 3:
773
- cachedKey = _a.sent();
774
- cachedToken = this.getTokenCache(cachedKey);
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)];
812
+ _a.sent();
813
+ _a.label = 4;
788
814
  case 4:
789
- accessToken = _a.sent();
815
+ tokenResponse = void 0;
816
+ scopesArray = typeof scopes === "string" ? scopes.split(" ") : scopes;
817
+ domain = window.location.origin;
818
+ _a.label = 5;
819
+ case 5:
820
+ _a.trys.push([5, 7, , 8]);
821
+ account = this.msalInstance.getAccountByUsername(this.loginHint);
822
+ scopesRequestForAcquireTokenSilent = {
823
+ scopes: scopesArray,
824
+ account: account !== null && account !== void 0 ? account : undefined,
825
+ redirectUri: domain + "/blank-auth-end.html",
826
+ };
827
+ return [4 /*yield*/, this.msalInstance.acquireTokenSilent(scopesRequestForAcquireTokenSilent)];
828
+ case 6:
829
+ tokenResponse = _a.sent();
830
+ return [3 /*break*/, 8];
831
+ case 7:
832
+ error_1 = _a.sent();
833
+ acquireTokenSilentFailedMessage = "Failed to call acquireTokenSilent. Reason: " + (error_1 === null || error_1 === void 0 ? void 0 : error_1.message) + ". ";
834
+ internalLogger.verbose(acquireTokenSilentFailedMessage);
835
+ return [3 /*break*/, 8];
836
+ case 8:
837
+ if (!!tokenResponse) return [3 /*break*/, 12];
838
+ _a.label = 9;
839
+ case 9:
840
+ _a.trys.push([9, 11, , 12]);
841
+ scopesRequestForSsoSilent = {
842
+ scopes: scopesArray,
843
+ loginHint: this.loginHint,
844
+ redirectUri: domain + "/blank-auth-end.html",
845
+ };
846
+ return [4 /*yield*/, this.msalInstance.ssoSilent(scopesRequestForSsoSilent)];
847
+ case 10:
848
+ tokenResponse = _a.sent();
849
+ return [3 /*break*/, 12];
850
+ case 11:
851
+ error_2 = _a.sent();
852
+ ssoSilentFailedMessage = "Failed to call ssoSilent. Reason: " + (error_2 === null || error_2 === void 0 ? void 0 : error_2.message) + ". ";
853
+ internalLogger.verbose(ssoSilentFailedMessage);
854
+ return [3 /*break*/, 12];
855
+ case 12:
856
+ if (!tokenResponse) {
857
+ errorMsg = "Failed to get access token cache silently, please login first: you need login first before get access token.";
858
+ internalLogger.error(errorMsg);
859
+ throw new ErrorWithCode(errorMsg, ErrorCode.UiRequiredError);
860
+ }
861
+ accessToken = parseAccessTokenFromAuthCodeTokenResponse(tokenResponse);
790
862
  return [2 /*return*/, accessToken];
791
863
  }
792
864
  });
@@ -823,92 +895,29 @@ var TeamsUserCredential = /** @class */ (function () {
823
895
  });
824
896
  });
825
897
  };
826
- TeamsUserCredential.prototype.exchangeAccessTokenFromSimpleAuthServer = function (scopesStr, authCodeResult) {
827
- var _a, _b;
898
+ TeamsUserCredential.prototype.init = function () {
828
899
  return __awaiter(this, void 0, void 0, function () {
829
- var axiosInstance, retryCount, response, tokenResult, key, err_2;
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;
900
+ var ssoToken, info, msalConfig;
884
901
  return __generator(this, function (_a) {
885
902
  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()];
903
+ case 0: return [4 /*yield*/, this.getSSOToken()];
890
904
  case 1:
891
- axiosInstance = _a.sent();
892
- return [4 /*yield*/, axiosInstance.post("/auth/token", {
893
- scope: scopesStr,
894
- grant_type: GrantType.ssoToken,
895
- })];
896
- case 2:
897
- response = _a.sent();
898
- accessTokenResult = response.data;
899
- accessToken = {
900
- token: accessTokenResult.access_token,
901
- expiresOnTimestamp: accessTokenResult.expires_on,
905
+ ssoToken = _a.sent();
906
+ info = getTenantIdAndLoginHintFromSsoToken(ssoToken.token);
907
+ this.loginHint = info.loginHint;
908
+ this.tid = info.tid;
909
+ msalConfig = {
910
+ auth: {
911
+ clientId: this.config.clientId,
912
+ authority: "https://login.microsoftonline.com/" + this.tid,
913
+ },
914
+ cache: {
915
+ cacheLocation: "sessionStorage",
916
+ },
902
917
  };
903
- return [4 /*yield*/, this.getAccessTokenCacheKey(scopesStr)];
904
- case 3:
905
- cacheKey = _a.sent();
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*/];
918
+ this.msalInstance = new PublicClientApplication(msalConfig);
919
+ this.initialized = true;
920
+ return [2 /*return*/];
912
921
  }
913
922
  });
914
923
  });
@@ -982,16 +991,13 @@ var TeamsUserCredential = /** @class */ (function () {
982
991
  internalLogger.error(ErrorMessage.AuthenticationConfigurationNotExists);
983
992
  throw new ErrorWithCode(ErrorMessage.AuthenticationConfigurationNotExists, ErrorCode.InvalidConfiguration);
984
993
  }
985
- if (config.initiateLoginEndpoint && config.simpleAuthEndpoint && config.clientId) {
994
+ if (config.initiateLoginEndpoint && config.clientId) {
986
995
  return config;
987
996
  }
988
997
  var missingValues = [];
989
998
  if (!config.initiateLoginEndpoint) {
990
999
  missingValues.push("initiateLoginEndpoint");
991
1000
  }
992
- if (!config.simpleAuthEndpoint) {
993
- missingValues.push("simpleAuthEndpoint");
994
- }
995
1001
  if (!config.clientId) {
996
1002
  missingValues.push("clientId");
997
1003
  }
@@ -999,129 +1005,20 @@ var TeamsUserCredential = /** @class */ (function () {
999
1005
  internalLogger.error(errorMsg);
1000
1006
  throw new ErrorWithCode(errorMsg, ErrorCode.InvalidConfiguration);
1001
1007
  };
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) {
1008
+ TeamsUserCredential.prototype.setSessionStorage = function (sessonStorageValues) {
1053
1009
  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
- }
1010
+ var sessionStorageKeys = Object.keys(sessonStorageValues);
1011
+ sessionStorageKeys.forEach(function (key) {
1012
+ sessionStorage.setItem(key, sessonStorageValues[key]);
1089
1013
  });
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
1014
  }
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
- }
1015
+ catch (error) {
1016
+ // Values in result.sessionStorage can not be set into session storage.
1017
+ // Throw error since this may block user.
1018
+ var errorMessage = "Failed to set values in session storage. Error: " + error.message;
1019
+ internalLogger.error(errorMessage);
1020
+ throw new ErrorWithCode(errorMessage, ErrorCode.InternalError);
1119
1021
  }
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
1022
  };
1126
1023
  return TeamsUserCredential;
1127
1024
  }());
@@ -1259,201 +1156,31 @@ function createMicrosoftGraphClient(credential, scopes) {
1259
1156
  return graphClient;
1260
1157
  }
1261
1158
 
1262
- // Copyright (c) Microsoft Corporation.
1263
1159
  /**
1264
- * SQL connection configuration instance.
1160
+ * Generate connection configuration consumed by tedious.
1265
1161
  * @remarks
1266
1162
  * Only works in in server side.
1267
- *
1268
1163
  * @beta
1269
- *
1270
1164
  */
1271
1165
  var DefaultTediousConnectionConfiguration = /** @class */ (function () {
1272
1166
  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/";
1167
+ throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "DefaultTediousConnectionConfiguration"), ErrorCode.RuntimeNotSupported);
1278
1168
  }
1279
1169
  /**
1280
1170
  * Generate connection configuration consumed by tedious.
1281
- *
1282
- * @returns Connection configuration of tedious for the SQL.
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
- *
1171
+ * @remarks
1172
+ * Only works in in server side.
1288
1173
  * @beta
1289
1174
  */
1290
- DefaultTediousConnectionConfiguration.prototype.getConfig = function () {
1291
- 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) {
1175
+ DefaultTediousConnectionConfiguration.prototype.getConfig = function (databaseName) {
1402
1176
  return __awaiter(this, void 0, void 0, function () {
1403
- var token, credential, errMsg, config;
1404
1177
  return __generator(this, function (_a) {
1405
- switch (_a.label) {
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
- }
1178
+ throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "DefaultTediousConnectionConfiguration"), ErrorCode.RuntimeNotSupported);
1442
1179
  });
1443
1180
  });
1444
1181
  };
1445
1182
  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 = {}));
1183
+ }());
1457
1184
 
1458
1185
  // Copyright (c) Microsoft Corporation.
1459
1186
  /**