@microsoft/teamsfx 2.0.1-alpha.f43656338.0 → 2.0.1-rc.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.
@@ -483,17 +483,6 @@ function parseCertificate(certificateContent) {
483
483
  * Only works in in server side.
484
484
  */
485
485
  class AppCredential {
486
- /**
487
- * Constructor of AppCredential.
488
- *
489
- * @remarks
490
- * Only works in in server side.
491
- *
492
- * @param {AuthenticationConfiguration} authConfig - The authentication configuration. Use environment variables if not provided.
493
- *
494
- * @throws {@link ErrorCode|InvalidConfiguration} when client id, client secret or tenant id is not found in config.
495
- * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is nodeJS.
496
- */
497
486
  constructor(authConfig) {
498
487
  internalLogger.info("Create M365 tenant credential");
499
488
  const config = this.loadAndValidateConfig(authConfig);
@@ -601,19 +590,6 @@ class AppCredential {
601
590
  * Can only be used in server side.
602
591
  */
603
592
  class OnBehalfOfUserCredential {
604
- /**
605
- * Constructor of OnBehalfOfUserCredential
606
- *
607
- * @remarks
608
- * Only works in in server side.
609
- *
610
- * @param {string} ssoToken - User token provided by Teams SSO feature.
611
- * @param {AuthenticationConfiguration} config - The authentication configuration. Use environment variables if not provided.
612
- *
613
- * @throws {@link ErrorCode|InvalidConfiguration} when client id, client secret, certificate content, authority host or tenant id is not found in config.
614
- * @throws {@link ErrorCode|InternalError} when SSO token is not valid.
615
- * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
616
- */
617
593
  constructor(ssoToken, config) {
618
594
  internalLogger.info("Get on behalf of user credential");
619
595
  const missingConfigurations = [];
@@ -758,11 +734,6 @@ class OnBehalfOfUserCredential {
758
734
  * Can only be used within Teams.
759
735
  */
760
736
  class TeamsUserCredential {
761
- /**
762
- * Constructor of TeamsUserCredential.
763
- * @remarks
764
- * Can only be used within Teams.
765
- */
766
737
  constructor(authConfig) {
767
738
  throw new ErrorWithCode(formatString(ErrorMessage.NodejsRuntimeNotSupported, "TeamsUserCredential"), exports.ErrorCode.RuntimeNotSupported);
768
739
  }
@@ -808,18 +779,8 @@ const defaultScope = "https://graph.microsoft.com/.default";
808
779
  * Microsoft Graph auth provider for Teams Framework
809
780
  */
810
781
  class MsGraphAuthProvider {
811
- /**
812
- * Constructor of MsGraphAuthProvider.
813
- *
814
- * @param {TeamsFx} teamsfx - Used to provide configuration and auth.
815
- * @param {string | string[]} scopes - The list of scopes for which the token will have access.
816
- *
817
- * @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
818
- *
819
- * @returns An instance of MsGraphAuthProvider.
820
- */
821
- constructor(teamsfx, scopes) {
822
- this.teamsfx = teamsfx;
782
+ constructor(credentialOrTeamsFx, scopes) {
783
+ this.credentialOrTeamsFx = credentialOrTeamsFx;
823
784
  let scopesStr = defaultScope;
824
785
  if (scopes) {
825
786
  validateScopesType(scopes);
@@ -846,7 +807,15 @@ class MsGraphAuthProvider {
846
807
  getAccessToken() {
847
808
  return tslib.__awaiter(this, void 0, void 0, function* () {
848
809
  internalLogger.info(`Get Graph Access token with scopes: '${this.scopes}'`);
849
- const accessToken = yield this.teamsfx.getCredential().getToken(this.scopes);
810
+ let accessToken;
811
+ if (this.credentialOrTeamsFx.getCredential) {
812
+ accessToken = yield this.credentialOrTeamsFx
813
+ .getCredential()
814
+ .getToken(this.scopes);
815
+ }
816
+ else {
817
+ accessToken = yield this.credentialOrTeamsFx.getToken(this.scopes);
818
+ }
850
819
  return new Promise((resolve, reject) => {
851
820
  if (accessToken) {
852
821
  resolve(accessToken.token);
@@ -864,7 +833,6 @@ class MsGraphAuthProvider {
864
833
  // Copyright (c) Microsoft Corporation.
865
834
  /**
866
835
  * Get Microsoft graph client.
867
- *
868
836
  * @example
869
837
  * Get Microsoft graph client by TokenCredential
870
838
  * ```typescript
@@ -918,6 +886,66 @@ function createMicrosoftGraphClient(teamsfx, scopes) {
918
886
  authProvider,
919
887
  });
920
888
  return graphClient;
889
+ }
890
+ // eslint-disable-next-line no-secrets/no-secrets
891
+ /**
892
+ * Get Microsoft graph client.
893
+ * @example
894
+ * Get Microsoft graph client by TokenCredential
895
+ * ```typescript
896
+ * // In browser: TeamsUserCredential
897
+ * const authConfig: TeamsUserCredentialAuthConfig = {
898
+ * clientId: "xxx",
899
+ initiateLoginEndpoint: "https://xxx/auth-start.html",
900
+ * };
901
+
902
+ * const credential = new TeamsUserCredential(authConfig);
903
+
904
+ * const scope = "User.Read";
905
+ * await credential.login(scope);
906
+
907
+ * const client = createMicrosoftGraphClientWithCredential(credential, scope);
908
+
909
+ * // In node: OnBehalfOfUserCredential
910
+ * const oboAuthConfig: OnBehalfOfCredentialAuthConfig = {
911
+ * authorityHost: "xxx",
912
+ * clientId: "xxx",
913
+ * tenantId: "xxx",
914
+ * clientSecret: "xxx",
915
+ * };
916
+
917
+ * const oboCredential = new OnBehalfOfUserCredential(ssoToken, oboAuthConfig);
918
+ * const scope = "User.Read";
919
+ * const client = createMicrosoftGraphClientWithCredential(oboCredential, scope);
920
+
921
+ * // In node: AppCredential
922
+ * const appAuthConfig: AppCredentialAuthConfig = {
923
+ * authorityHost: "xxx",
924
+ * clientId: "xxx",
925
+ * tenantId: "xxx",
926
+ * clientSecret: "xxx",
927
+ * };
928
+ * const appCredential = new AppCredential(appAuthConfig);
929
+ * const scope = "User.Read";
930
+ * const client = createMicrosoftGraphClientWithCredential(appCredential, scope);
931
+ *
932
+ * const profile = await client.api("/me").get();
933
+ * ```
934
+ *
935
+ * @param {TokenCredential} credential - Used to provide configuration and auth.
936
+ * @param scopes - The array of Microsoft Token scope of access. Default value is `[.default]`.
937
+ *
938
+ * @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
939
+ *
940
+ * @returns Graph client with specified scopes.
941
+ */
942
+ function createMicrosoftGraphClientWithCredential(credential, scopes) {
943
+ internalLogger.info("Create Microsoft Graph Client");
944
+ const authProvider = new MsGraphAuthProvider(credential, scopes);
945
+ const graphClient = microsoftGraphClient.Client.initWithMiddleware({
946
+ authProvider,
947
+ });
948
+ return graphClient;
921
949
  }
922
950
 
923
951
  // Copyright (c) Microsoft Corporation.
@@ -1170,22 +1198,20 @@ class TokenExchangeInvokeResponse {
1170
1198
  * ```
1171
1199
  */
1172
1200
  class TeamsBotSsoPrompt extends botbuilderDialogs.Dialog {
1173
- /**
1174
- * Constructor of TeamsBotSsoPrompt.
1175
- *
1176
- * @param {TeamsFx} teamsfx - Used to provide configuration and auth
1177
- * @param dialogId Unique ID of the dialog within its parent `DialogSet` or `ComponentDialog`.
1178
- * @param settings Settings used to configure the prompt.
1179
- *
1180
- * @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
1181
- * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
1182
- */
1183
- constructor(teamsfx, dialogId, settings) {
1184
- super(dialogId);
1185
- this.teamsfx = teamsfx;
1186
- this.settings = settings;
1187
- validateScopesType(settings.scopes);
1188
- this.loadAndValidateConfig();
1201
+ constructor(authConfig, ...args) {
1202
+ super(arguments.length === 3 ? args[0] : args[1]);
1203
+ if (authConfig.getCredential) {
1204
+ const teamsfx = authConfig;
1205
+ this.authConfig = this.loadAndValidateConfig(teamsfx);
1206
+ this.initiateLoginEndpoint = teamsfx.getConfig("initiateLoginEndpoint");
1207
+ this.settings = args[1];
1208
+ }
1209
+ else {
1210
+ this.initiateLoginEndpoint = args[0];
1211
+ this.authConfig = authConfig;
1212
+ this.settings = args[2];
1213
+ }
1214
+ validateScopesType(this.settings.scopes);
1189
1215
  internalLogger.info("Create a new Teams Bot SSO Prompt");
1190
1216
  }
1191
1217
  /**
@@ -1286,20 +1312,20 @@ class TeamsBotSsoPrompt extends botbuilderDialogs.Dialog {
1286
1312
  }
1287
1313
  });
1288
1314
  }
1289
- loadAndValidateConfig() {
1290
- if (this.teamsfx.getIdentityType() !== exports.IdentityType.User) {
1291
- const errorMsg = formatString(ErrorMessage.IdentityTypeNotSupported, this.teamsfx.getIdentityType().toString(), "TeamsBotSsoPrompt");
1315
+ loadAndValidateConfig(teamsfx) {
1316
+ if (teamsfx.getIdentityType() !== exports.IdentityType.User) {
1317
+ const errorMsg = formatString(ErrorMessage.IdentityTypeNotSupported, teamsfx.getIdentityType().toString(), "TeamsBotSsoPrompt");
1292
1318
  internalLogger.error(errorMsg);
1293
1319
  throw new ErrorWithCode(errorMsg, exports.ErrorCode.IdentityTypeNotSupported);
1294
1320
  }
1295
1321
  const missingConfigurations = [];
1296
- if (!this.teamsfx.hasConfig("initiateLoginEndpoint")) {
1322
+ if (!teamsfx.hasConfig("initiateLoginEndpoint")) {
1297
1323
  missingConfigurations.push("initiateLoginEndpoint");
1298
1324
  }
1299
- if (!this.teamsfx.hasConfig("clientId")) {
1325
+ if (!teamsfx.hasConfig("clientId")) {
1300
1326
  missingConfigurations.push("clientId");
1301
1327
  }
1302
- if (!this.teamsfx.hasConfig("tenantId")) {
1328
+ if (!teamsfx.hasConfig("tenantId")) {
1303
1329
  missingConfigurations.push("tenantId");
1304
1330
  }
1305
1331
  if (missingConfigurations.length != 0) {
@@ -1307,6 +1333,24 @@ class TeamsBotSsoPrompt extends botbuilderDialogs.Dialog {
1307
1333
  internalLogger.error(errorMsg);
1308
1334
  throw new ErrorWithCode(errorMsg, exports.ErrorCode.InvalidConfiguration);
1309
1335
  }
1336
+ let authConfig;
1337
+ if (teamsfx.getConfig("clientSecret")) {
1338
+ authConfig = {
1339
+ authorityHost: teamsfx.getConfig("authorityHost"),
1340
+ clientId: teamsfx.getConfig("clientId"),
1341
+ tenantId: teamsfx.getConfig("tenantId"),
1342
+ clientSecret: teamsfx.getConfig("clientSecret"),
1343
+ };
1344
+ }
1345
+ else {
1346
+ authConfig = {
1347
+ authorityHost: teamsfx.getConfig("authorityHost"),
1348
+ clientId: teamsfx.getConfig("clientId"),
1349
+ tenantId: teamsfx.getConfig("tenantId"),
1350
+ certificateContent: teamsfx.getConfig("certificateContent"),
1351
+ };
1352
+ }
1353
+ return authConfig;
1310
1354
  }
1311
1355
  /**
1312
1356
  * Ensure bot is running in MS Teams since TeamsBotSsoPrompt is only supported in MS Teams channel.
@@ -1350,7 +1394,7 @@ class TeamsBotSsoPrompt extends botbuilderDialogs.Dialog {
1350
1394
  */
1351
1395
  getSignInResource(loginHint) {
1352
1396
  internalLogger.verbose("Get sign in authentication configuration");
1353
- const signInLink = `${this.teamsfx.getConfig("initiateLoginEndpoint")}?scope=${encodeURI(this.settings.scopes.join(" "))}&clientId=${this.teamsfx.getConfig("clientId")}&tenantId=${this.teamsfx.getConfig("tenantId")}&loginHint=${loginHint}`;
1397
+ const signInLink = `${this.initiateLoginEndpoint}?scope=${encodeURI(this.settings.scopes.join(" "))}&clientId=${this.authConfig.clientId}&tenantId=${this.authConfig.tenantId}&loginHint=${loginHint}`;
1354
1398
  internalLogger.verbose("Sign in link: " + signInLink);
1355
1399
  const tokenExchangeResource = {
1356
1400
  id: uuid.v4(),
@@ -1377,8 +1421,7 @@ class TeamsBotSsoPrompt extends botbuilderDialogs.Dialog {
1377
1421
  }
1378
1422
  else {
1379
1423
  const ssoToken = context.activity.value.token;
1380
- this.teamsfx.setSsoToken(ssoToken);
1381
- const credential = this.teamsfx.getCredential();
1424
+ const credential = new OnBehalfOfUserCredential(ssoToken, this.authConfig);
1382
1425
  let exchangedToken;
1383
1426
  try {
1384
1427
  exchangedToken = yield credential.getToken(this.settings.scopes);
@@ -3256,27 +3299,29 @@ let COMMAND_ROUTE_DIALOG = "CommandRouteDialog";
3256
3299
  * Sso execution dialog, use to handle sso command
3257
3300
  */
3258
3301
  class BotSsoExecutionDialog extends botbuilderDialogs.ComponentDialog {
3259
- /**
3260
- * Creates a new instance of the BotSsoExecutionDialog.
3261
- * @param dedupStorage Helper storage to remove duplicated messages
3262
- * @param settings The list of scopes for which the token will have access
3263
- * @param teamsfx {@link TeamsFx} instance for authentication
3264
- */
3265
- constructor(dedupStorage, ssoPromptSettings, teamsfx, dialogName) {
3266
- super(dialogName !== null && dialogName !== void 0 ? dialogName : DIALOG_NAME);
3302
+ constructor(dedupStorage, ssoPromptSettings, authConfig, ...args) {
3303
+ var _a;
3304
+ super((_a = (authConfig.getCredential ? args[0] : args[1])) !== null && _a !== void 0 ? _a : DIALOG_NAME);
3267
3305
  this.dedupStorageKeys = [];
3268
3306
  // Map to store the commandId and triggerPatterns, key: commandId, value: triggerPatterns
3269
3307
  this.commandMapping = new Map();
3308
+ const dialogName = authConfig.getCredential ? args[0] : args[1];
3270
3309
  if (dialogName) {
3271
3310
  DIALOG_NAME = dialogName;
3272
3311
  TEAMS_SSO_PROMPT_ID = dialogName + TEAMS_SSO_PROMPT_ID;
3273
3312
  COMMAND_ROUTE_DIALOG = dialogName + COMMAND_ROUTE_DIALOG;
3274
3313
  }
3314
+ let ssoDialog;
3315
+ if (authConfig.getCredential) {
3316
+ ssoDialog = new TeamsBotSsoPrompt(authConfig, TEAMS_SSO_PROMPT_ID, ssoPromptSettings);
3317
+ }
3318
+ else {
3319
+ ssoDialog = new TeamsBotSsoPrompt(authConfig, args[0], TEAMS_SSO_PROMPT_ID, ssoPromptSettings);
3320
+ }
3321
+ this.addDialog(ssoDialog);
3275
3322
  this.initialDialogId = COMMAND_ROUTE_DIALOG;
3276
3323
  this.dedupStorage = dedupStorage;
3277
3324
  this.dedupStorageKeys = [];
3278
- const ssoDialog = new TeamsBotSsoPrompt(teamsfx, TEAMS_SSO_PROMPT_ID, ssoPromptSettings);
3279
- this.addDialog(ssoDialog);
3280
3325
  const commandRouteDialog = new botbuilderDialogs.WaterfallDialog(COMMAND_ROUTE_DIALOG, [
3281
3326
  this.commandRouteStep.bind(this),
3282
3327
  ]);
@@ -3885,6 +3930,34 @@ class MessageBuilder {
3885
3930
  }
3886
3931
 
3887
3932
  // Copyright (c) Microsoft Corporation.
3933
+ /**
3934
+ * Retrieve the OAuth Sign in Link to use in the MessagingExtensionResult Suggested Actions.
3935
+ * This method only work on MessageExtension with Query now.
3936
+ *
3937
+ * @param {OnBehalfOfCredentialAuthConfig} authConfig - User custom the message extension authentication configuration.
3938
+ * @param {initiateLoginEndpoint} initiateLoginEndpoint - Login page for Teams to redirect to.
3939
+ * @param {string | string[]} scopes - The list of scopes for which the token will have access.
3940
+ *
3941
+ * @returns SignIn link CardAction with 200 status code.
3942
+ */
3943
+ function getSignInResponseForMessageExtensionWithAuthConfig(authConfig, initiateLoginEndpoint, scopes) {
3944
+ const scopesArray = getScopesArray(scopes);
3945
+ const signInLink = `${initiateLoginEndpoint}?scope=${encodeURI(scopesArray.join(" "))}&clientId=${authConfig.clientId}&tenantId=${authConfig.tenantId}`;
3946
+ return {
3947
+ composeExtension: {
3948
+ type: "silentAuth",
3949
+ suggestedActions: {
3950
+ actions: [
3951
+ {
3952
+ type: "openUrl",
3953
+ value: signInLink,
3954
+ title: "Message Extension OAuth",
3955
+ },
3956
+ ],
3957
+ },
3958
+ },
3959
+ };
3960
+ }
3888
3961
  /**
3889
3962
  * Retrieve the OAuth Sign in Link to use in the MessagingExtensionResult Suggested Actions.
3890
3963
  * This method only work on MessageExtension with Query now.
@@ -3912,6 +3985,56 @@ function getSignInResponseForMessageExtension(teamsfx, scopes) {
3912
3985
  },
3913
3986
  };
3914
3987
  }
3988
+ /**
3989
+ * execution in message extension with SSO token.
3990
+ *
3991
+ * @param {TurnContext} context - The context object for the current turn.
3992
+ * @param {OnBehalfOfCredentialAuthConfig} authConfig - User custom the message extension authentication configuration.
3993
+ * @param {initiateLoginEndpoint} initiateLoginEndpoint - Login page for Teams to redirect to.
3994
+ * @param {string[]} scopes - The list of scopes for which the token will have access.
3995
+ * @param {function} logic - Business logic when executing the query in message extension with SSO or access token.
3996
+ *
3997
+ * @throws {@link ErrorCode|InternalError} when failed to get access token with unknown error.
3998
+ * @throws {@link ErrorCode|TokenExpiredError} when SSO token has already expired.
3999
+ * @throws {@link ErrorCode|ServiceError} when failed to get access token from simple auth server.
4000
+ * @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
4001
+ * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is nodeJS.
4002
+ *
4003
+ * @returns A MessageExtension Response for the activity. If the logic not return any, return void instead.
4004
+ */
4005
+ function executionWithTokenAndConfig(context, authConfig, initiateLoginEndpoint, scopes, logic) {
4006
+ return tslib.__awaiter(this, void 0, void 0, function* () {
4007
+ const valueObj = context.activity.value;
4008
+ if (!valueObj.authentication || !valueObj.authentication.token) {
4009
+ internalLogger.verbose("No AccessToken in request, return silentAuth for AccessToken");
4010
+ return getSignInResponseForMessageExtensionWithAuthConfig(authConfig, initiateLoginEndpoint, scopes);
4011
+ }
4012
+ try {
4013
+ const credential = new OnBehalfOfUserCredential(valueObj.authentication.token, authConfig);
4014
+ const token = yield credential.getToken(scopes);
4015
+ const ssoTokenExpiration = parseJwt(valueObj.authentication.token).exp;
4016
+ const tokenRes = {
4017
+ ssoToken: valueObj.authentication.token,
4018
+ ssoTokenExpiration: new Date(ssoTokenExpiration * 1000).toISOString(),
4019
+ token: token.token,
4020
+ expiration: token.expiresOnTimestamp.toString(),
4021
+ connectionName: "",
4022
+ };
4023
+ if (logic) {
4024
+ return yield logic(tokenRes);
4025
+ }
4026
+ }
4027
+ catch (err) {
4028
+ if (err instanceof ErrorWithCode && err.code === exports.ErrorCode.UiRequiredError) {
4029
+ internalLogger.verbose("User not consent yet, return 412 to user consent first.");
4030
+ const response = { status: 412 };
4031
+ yield context.sendActivity({ value: response, type: botbuilder.ActivityTypes.InvokeResponse });
4032
+ return;
4033
+ }
4034
+ throw err;
4035
+ }
4036
+ });
4037
+ }
3915
4038
  /**
3916
4039
  * execution in message extension with SSO token.
3917
4040
  *
@@ -3961,9 +4084,11 @@ function executionWithToken(context, config, scopes, logic) {
3961
4084
  }
3962
4085
  });
3963
4086
  }
4087
+ // eslint-disable-next-line no-secrets/no-secrets
3964
4088
  /**
3965
4089
  * Users execute query in message extension with SSO or access token.
3966
4090
  *
4091
+ *
3967
4092
  * @param {TurnContext} context - The context object for the current turn.
3968
4093
  * @param {AuthenticationConfiguration} config - User custom the message extension authentication configuration.
3969
4094
  * @param {string| string[]} scopes - The list of scopes for which the token will have access.
@@ -3986,6 +4111,33 @@ function handleMessageExtensionQueryWithToken(context, config, scopes, logic) {
3986
4111
  }
3987
4112
  return yield executionWithToken(context, config !== null && config !== void 0 ? config : {}, scopes, logic);
3988
4113
  });
4114
+ }
4115
+ /**
4116
+ * Users execute query in message extension with SSO or access token.
4117
+ *
4118
+ * @param {TurnContext} context - The context object for the current turn.
4119
+ * @param {OnBehalfOfCredentialAuthConfig} config - User custom the message extension authentication configuration.
4120
+ * @param {initiateLoginEndpoint} initiateLoginEndpoint - Login page for Teams to redirect to.
4121
+ * @param {string| string[]} scopes - The list of scopes for which the token will have access.
4122
+ * @param {function} logic - Business logic when executing the query in message extension with SSO or access token.
4123
+ *
4124
+ * @throws {@link ErrorCode|InternalError} when User invoke not response to message extension query.
4125
+ * @throws {@link ErrorCode|InternalError} when failed to get access token with unknown error.
4126
+ * @throws {@link ErrorCode|TokenExpiredError} when SSO token has already expired.
4127
+ * @throws {@link ErrorCode|ServiceError} when failed to get access token from simple auth server.
4128
+ * @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
4129
+ * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is nodeJS.
4130
+ *
4131
+ * @returns A MessageExtension Response for the activity. If the logic not return any, return void instead.
4132
+ */
4133
+ function handleMessageExtensionQueryWithSSO(context, config, initiateLoginEndpoint, scopes, logic) {
4134
+ return tslib.__awaiter(this, void 0, void 0, function* () {
4135
+ if (context.activity.name != "composeExtension/query") {
4136
+ internalLogger.error(ErrorMessage.OnlySupportInQueryActivity);
4137
+ throw new ErrorWithCode(formatString(ErrorMessage.OnlySupportInQueryActivity), exports.ErrorCode.FailedOperation);
4138
+ }
4139
+ return yield executionWithTokenAndConfig(context, config !== null && config !== void 0 ? config : {}, initiateLoginEndpoint, scopes, logic);
4140
+ });
3989
4141
  }
3990
4142
 
3991
4143
  exports.ApiKeyProvider = ApiKeyProvider;
@@ -4011,10 +4163,12 @@ exports.TeamsFx = TeamsFx;
4011
4163
  exports.TeamsUserCredential = TeamsUserCredential;
4012
4164
  exports.createApiClient = createApiClient;
4013
4165
  exports.createMicrosoftGraphClient = createMicrosoftGraphClient;
4166
+ exports.createMicrosoftGraphClientWithCredential = createMicrosoftGraphClientWithCredential;
4014
4167
  exports.createPemCertOption = createPemCertOption;
4015
4168
  exports.createPfxCertOption = createPfxCertOption;
4016
4169
  exports.getLogLevel = getLogLevel;
4017
4170
  exports.getTediousConnectionConfig = getTediousConnectionConfig;
4171
+ exports.handleMessageExtensionQueryWithSSO = handleMessageExtensionQueryWithSSO;
4018
4172
  exports.handleMessageExtensionQueryWithToken = handleMessageExtensionQueryWithToken;
4019
4173
  exports.sendAdaptiveCard = sendAdaptiveCard;
4020
4174
  exports.sendMessage = sendMessage;