@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.
@@ -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
  /**
@@ -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 = "[" + timestamp + "] : @microsoft/teamsfx : " + LogLevel[logLevel] + " - ";
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
- 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();
699
- 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
- },
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, cachedKey, cachedToken, accessToken;
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 [4 /*yield*/, this.getAccessTokenCacheKey(scopeStr)];
790
+ if (!!this.initialized) return [3 /*break*/, 4];
791
+ return [4 /*yield*/, this.init()];
772
792
  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)];
793
+ _a.sent();
794
+ _a.label = 4;
788
795
  case 4:
789
- accessToken = _a.sent();
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.exchangeAccessTokenFromSimpleAuthServer = function (scopesStr, authCodeResult) {
827
- var _a, _b;
879
+ TeamsUserCredential.prototype.init = function () {
828
880
  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;
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
- 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,
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
- 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*/];
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.simpleAuthEndpoint && config.clientId) {
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
- * SQL connection configuration instance.
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
- * @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
- *
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
- 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
- }
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
  /**