@microsoft/teamsfx 0.4.2-alpha.e84c0d19.0 → 0.5.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,7 +45,6 @@ Please note that you need to load configuration before using any credentials.
45
45
  loadConfiguration({
46
46
  authentication: {
47
47
  initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
48
- simpleAuthEndpoint: process.env.REACT_APP_TEAMSFX_ENDPOINT,
49
48
  clientId: process.env.REACT_APP_CLIENT_ID,
50
49
  },
51
50
  });
@@ -67,7 +66,6 @@ Use the snippet below:
67
66
  loadConfiguration({
68
67
  authentication: {
69
68
  initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
70
- simpleAuthEndpoint: process.env.REACT_APP_TEAMSFX_ENDPOINT,
71
69
  clientId: process.env.REACT_APP_CLIENT_ID,
72
70
  },
73
71
  });
@@ -165,7 +163,6 @@ Use `TeamsUserCredential` and `createMicrosoftGraphClient`.
165
163
  loadConfiguration({
166
164
  authentication: {
167
165
  initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
168
- simpleAuthEndpoint: process.env.REACT_APP_TEAMSFX_ENDPOINT,
169
166
  clientId: process.env.REACT_APP_CLIENT_ID,
170
167
  },
171
168
  });
@@ -182,7 +179,6 @@ Use `axios` library to make HTTP request to Azure Function.
182
179
  loadConfiguration({
183
180
  authentication: {
184
181
  initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
185
- simpleAuthEndpoint: process.env.REACT_APP_TEAMSFX_ENDPOINT,
186
182
  clientId: process.env.REACT_APP_CLIENT_ID,
187
183
  },
188
184
  });
@@ -205,7 +201,10 @@ Apart from `tedious`, you can also compose connection config of other SQL librar
205
201
  ```ts
206
202
  loadConfiguration();
207
203
  const sqlConnectConfig = new DefaultTediousConnectionConfiguration();
204
+ // if there's only one SQL database
208
205
  const config = await sqlConnectConfig.getConfig();
206
+ // if there are multiple SQL databases
207
+ const config2 = await sqlConnectionConfig.getConfig("your database name");
209
208
  const connection = new Connection(config);
210
209
  connection.on("connect", (error) => {
211
210
  if (error) {
@@ -1,5 +1,5 @@
1
1
  import jwt_decode from 'jwt-decode';
2
- import * as microsoftTeams from '@microsoft/teams-js';
2
+ import { app, authentication } from '@microsoft/teams-js';
3
3
  import { PublicClientApplication } from '@azure/msal-browser';
4
4
  import { Client } from '@microsoft/microsoft-graph-client';
5
5
 
@@ -55,6 +55,10 @@ var ErrorCode;
55
55
  * Operation failed.
56
56
  */
57
57
  ErrorCode["FailedOperation"] = "FailedOperation";
58
+ /**
59
+ * Invalid response error.
60
+ */
61
+ ErrorCode["InvalidResponse"] = "InvalidResponse";
58
62
  })(ErrorCode || (ErrorCode = {}));
59
63
  /**
60
64
  * @internal
@@ -600,7 +604,6 @@ class OnBehalfOfUserCredential {
600
604
 
601
605
  // Copyright (c) Microsoft Corporation.
602
606
  const tokenRefreshTimeSpanInMillisecond = 5 * 60 * 1000;
603
- const initializeTeamsSdkTimeoutInMillisecond = 5000;
604
607
  const loginPageWidth = 600;
605
608
  const loginPageHeight = 535;
606
609
  /**
@@ -668,35 +671,48 @@ class TeamsUserCredential {
668
671
  if (!this.initialized) {
669
672
  await this.init();
670
673
  }
671
- return new Promise((resolve, reject) => {
672
- microsoftTeams.initialize(() => {
673
- microsoftTeams.authentication.authenticate({
674
- url: `${this.config.initiateLoginEndpoint}?clientId=${this.config.clientId}&scope=${encodeURI(scopesStr)}&loginHint=${this.loginHint}`,
675
- width: loginPageWidth,
676
- height: loginPageHeight,
677
- successCallback: async (result) => {
678
- if (!result) {
679
- const errorMsg = "Get empty authentication result from MSAL";
680
- internalLogger.error(errorMsg);
681
- reject(new ErrorWithCode(errorMsg, ErrorCode.InternalError));
682
- return;
683
- }
684
- try {
685
- const accessToken = parseAccessTokenFromAuthCodeTokenResponse(result);
686
- resolve(accessToken);
687
- }
688
- catch (error) {
689
- reject(error);
690
- }
691
- },
692
- failureCallback: (reason) => {
693
- const errorMsg = `Consent failed for the scope ${scopesStr} with error: ${reason}`;
694
- internalLogger.error(errorMsg);
695
- reject(new ErrorWithCode(errorMsg, ErrorCode.ConsentFailed));
696
- },
697
- });
698
- });
699
- });
674
+ await app.initialize();
675
+ let result;
676
+ try {
677
+ const params = {
678
+ url: `${this.config.initiateLoginEndpoint}?clientId=${this.config.clientId}&scope=${encodeURI(scopesStr)}&loginHint=${this.loginHint}`,
679
+ width: loginPageWidth,
680
+ height: loginPageHeight,
681
+ };
682
+ result = await authentication.authenticate(params);
683
+ if (!result) {
684
+ const errorMsg = "Get empty authentication result from MSAL";
685
+ internalLogger.error(errorMsg);
686
+ throw new ErrorWithCode(errorMsg, ErrorCode.InternalError);
687
+ }
688
+ }
689
+ catch (err) {
690
+ const errorMsg = `Consent failed for the scope ${scopesStr} with error: ${err.message}`;
691
+ internalLogger.error(errorMsg);
692
+ throw new ErrorWithCode(errorMsg, ErrorCode.ConsentFailed);
693
+ }
694
+ let resultJson = {};
695
+ try {
696
+ resultJson = JSON.parse(result);
697
+ }
698
+ catch (error) {
699
+ // If can not parse result as Json, will throw error.
700
+ const failedToParseResult = "Failed to parse response to Json.";
701
+ internalLogger.error(failedToParseResult);
702
+ throw new ErrorWithCode(failedToParseResult, ErrorCode.InvalidResponse);
703
+ }
704
+ // If code exists in result, user may using previous auth-start and auth-end page.
705
+ if (resultJson.code) {
706
+ const helpLink = "https://aka.ms/teamsfx-auth-code-flow";
707
+ const usingPreviousAuthPage = "Found auth code in response. Auth code is not support for current version of SDK. " +
708
+ `Please refer to the help link for how to fix the issue: ${helpLink}.`;
709
+ internalLogger.error(usingPreviousAuthPage);
710
+ throw new ErrorWithCode(usingPreviousAuthPage, ErrorCode.InvalidResponse);
711
+ }
712
+ // If sessionStorage exists in result, set the values in current session storage.
713
+ if (resultJson.sessionStorage) {
714
+ this.setSessionStorage(resultJson.sessionStorage);
715
+ }
700
716
  }
701
717
  /**
702
718
  * Get access token from credential.
@@ -829,57 +845,48 @@ class TeamsUserCredential {
829
845
  * It will try to get SSO token from memory first, if SSO token doesn't exist or about to expired, then it will using teams SDK to get SSO token
830
846
  * @returns SSO token
831
847
  */
832
- getSSOToken() {
833
- return new Promise((resolve, reject) => {
834
- if (this.ssoToken) {
835
- if (this.ssoToken.expiresOnTimestamp - Date.now() > tokenRefreshTimeSpanInMillisecond) {
836
- internalLogger.verbose("Get SSO token from memory cache");
837
- resolve(this.ssoToken);
838
- return;
839
- }
848
+ async getSSOToken() {
849
+ if (this.ssoToken) {
850
+ if (this.ssoToken.expiresOnTimestamp - Date.now() > tokenRefreshTimeSpanInMillisecond) {
851
+ internalLogger.verbose("Get SSO token from memory cache");
852
+ return this.ssoToken;
840
853
  }
841
- let initialized = false;
842
- microsoftTeams.initialize(() => {
843
- initialized = true;
844
- microsoftTeams.authentication.getAuthToken({
845
- successCallback: (token) => {
846
- if (!token) {
847
- const errorMsg = "Get empty SSO token from Teams";
848
- internalLogger.error(errorMsg);
849
- reject(new ErrorWithCode(errorMsg, ErrorCode.InternalError));
850
- return;
851
- }
852
- const tokenObject = parseJwt(token);
853
- if (tokenObject.ver !== "1.0" && tokenObject.ver !== "2.0") {
854
- const errorMsg = "SSO token is not valid with an unknown version: " + tokenObject.ver;
855
- internalLogger.error(errorMsg);
856
- reject(new ErrorWithCode(errorMsg, ErrorCode.InternalError));
857
- return;
858
- }
859
- const ssoToken = {
860
- token,
861
- expiresOnTimestamp: tokenObject.exp * 1000,
862
- };
863
- this.ssoToken = ssoToken;
864
- resolve(ssoToken);
865
- },
866
- failureCallback: (errMessage) => {
867
- const errorMsg = "Get SSO token failed with error: " + errMessage;
868
- internalLogger.error(errorMsg);
869
- reject(new ErrorWithCode(errorMsg, ErrorCode.InternalError));
870
- },
871
- resources: [],
872
- });
873
- });
874
- // If the code not running in Teams, the initialize callback function would never trigger
875
- setTimeout(() => {
876
- if (!initialized) {
877
- const errorMsg = "Initialize teams sdk timeout, maybe the code is not running inside Teams";
878
- internalLogger.error(errorMsg);
879
- reject(new ErrorWithCode(errorMsg, ErrorCode.InternalError));
880
- }
881
- }, initializeTeamsSdkTimeoutInMillisecond);
882
- });
854
+ }
855
+ if (this.checkInTeams()) {
856
+ const params = {};
857
+ let token;
858
+ try {
859
+ await app.initialize();
860
+ token = await authentication.getAuthToken(params);
861
+ }
862
+ catch (err) {
863
+ const errorMsg = "Get SSO token failed with error: " + err.message;
864
+ internalLogger.error(errorMsg);
865
+ throw new ErrorWithCode(errorMsg, ErrorCode.InternalError);
866
+ }
867
+ if (!token) {
868
+ const errorMsg = "Get empty SSO token from Teams";
869
+ internalLogger.error(errorMsg);
870
+ throw new ErrorWithCode(errorMsg, ErrorCode.InternalError);
871
+ }
872
+ const tokenObject = parseJwt(token);
873
+ if (tokenObject.ver !== "1.0" && tokenObject.ver !== "2.0") {
874
+ const errorMsg = "SSO token is not valid with an unknown version: " + tokenObject.ver;
875
+ internalLogger.error(errorMsg);
876
+ throw new ErrorWithCode(errorMsg, ErrorCode.InternalError);
877
+ }
878
+ const ssoToken = {
879
+ token,
880
+ expiresOnTimestamp: tokenObject.exp * 1000,
881
+ };
882
+ this.ssoToken = ssoToken;
883
+ return ssoToken;
884
+ }
885
+ else {
886
+ const errorMsg = "Initialize teams sdk failed due to not running inside Teams";
887
+ internalLogger.error(errorMsg);
888
+ throw new ErrorWithCode(errorMsg, ErrorCode.InternalError);
889
+ }
883
890
  }
884
891
  /**
885
892
  * Load and validate authentication configuration
@@ -906,6 +913,31 @@ class TeamsUserCredential {
906
913
  internalLogger.error(errorMsg);
907
914
  throw new ErrorWithCode(errorMsg, ErrorCode.InvalidConfiguration);
908
915
  }
916
+ setSessionStorage(sessionStorageValues) {
917
+ try {
918
+ const sessionStorageKeys = Object.keys(sessionStorageValues);
919
+ sessionStorageKeys.forEach((key) => {
920
+ sessionStorage.setItem(key, sessionStorageValues[key]);
921
+ });
922
+ }
923
+ catch (error) {
924
+ // Values in result.sessionStorage can not be set into session storage.
925
+ // Throw error since this may block user.
926
+ const errorMessage = `Failed to set values in session storage. Error: ${error.message}`;
927
+ internalLogger.error(errorMessage);
928
+ throw new ErrorWithCode(errorMessage, ErrorCode.InternalError);
929
+ }
930
+ }
931
+ // Come from here: https://github.com/wictorwilen/msteams-react-base-component/blob/master/src/useTeams.ts
932
+ checkInTeams() {
933
+ if ((window.parent === window.self && window.nativeInterface) ||
934
+ window.navigator.userAgent.includes("Teams/") ||
935
+ window.name === "embedded-page-container" ||
936
+ window.name === "extension-tab-frame") {
937
+ return true;
938
+ }
939
+ return false;
940
+ }
909
941
  }
910
942
 
911
943
  // Copyright (c) Microsoft Corporation.
@@ -1047,7 +1079,7 @@ class DefaultTediousConnectionConfiguration {
1047
1079
  * Only works in in server side.
1048
1080
  * @beta
1049
1081
  */
1050
- async getConfig() {
1082
+ async getConfig(databaseName) {
1051
1083
  throw new ErrorWithCode(formatString(ErrorMessage.BrowserRuntimeNotSupported, "DefaultTediousConnectionConfiguration"), ErrorCode.RuntimeNotSupported);
1052
1084
  }
1053
1085
  }