@microsoft/teamsfx 2.2.3-alpha.81508f111.0 → 2.2.3-alpha.8b06251e7.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.
@@ -396,6 +396,7 @@ function getAuthority(authorityHost, tenantId) {
396
396
  return normalizedAuthorityHost + "/" + tenantId;
397
397
  }
398
398
 
399
+ // Copyright (c) Microsoft Corporation.
399
400
  /**
400
401
  * @internal
401
402
  */
@@ -713,16 +714,16 @@ class TeamsUserCredential {
713
714
  * @remarks
714
715
  * Can only be used within Teams.
715
716
  */
716
- async login(scopes, resources) {
717
- throw new ErrorWithCode(formatString(ErrorMessage.NodejsRuntimeNotSupported, "TeamsUserCredential"), ErrorCode.RuntimeNotSupported);
717
+ login(scopes, resources) {
718
+ return Promise.reject(new ErrorWithCode(formatString(ErrorMessage.NodejsRuntimeNotSupported, "TeamsUserCredential"), ErrorCode.RuntimeNotSupported));
718
719
  }
719
720
  /**
720
721
  * Get access token from credential.
721
722
  * @remarks
722
723
  * Can only be used within Teams.
723
724
  */
724
- async getToken(scopes, options) {
725
- throw new ErrorWithCode(formatString(ErrorMessage.NodejsRuntimeNotSupported, "TeamsUserCredential"), ErrorCode.RuntimeNotSupported);
725
+ getToken(scopes, options) {
726
+ return Promise.reject(new ErrorWithCode(formatString(ErrorMessage.NodejsRuntimeNotSupported, "TeamsUserCredential"), ErrorCode.RuntimeNotSupported));
726
727
  }
727
728
  /**
728
729
  * Get basic user info from SSO token
@@ -733,14 +734,16 @@ class TeamsUserCredential {
733
734
  * Can only be used within Teams.
734
735
  */
735
736
  getUserInfo(resources) {
736
- throw new ErrorWithCode(formatString(ErrorMessage.NodejsRuntimeNotSupported, "TeamsUserCredential"), ErrorCode.RuntimeNotSupported);
737
+ return Promise.reject(new ErrorWithCode(formatString(ErrorMessage.NodejsRuntimeNotSupported, "TeamsUserCredential"), ErrorCode.RuntimeNotSupported));
737
738
  }
738
739
  }
739
740
 
740
741
  // Copyright (c) Microsoft Corporation.
741
742
  const defaultScope = "https://graph.microsoft.com/.default";
743
+ // eslint-disable-next-line no-secrets/no-secrets
742
744
  /**
743
745
  * Microsoft Graph auth provider for Teams Framework
746
+ * @deprecated Use `TokenCredentialAuthenticationProvider` from `@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials` instead.
744
747
  */
745
748
  class MsGraphAuthProvider {
746
749
  constructor(credentialOrTeamsFx, scopes) {
@@ -769,7 +772,7 @@ class MsGraphAuthProvider {
769
772
  *
770
773
  */
771
774
  async getAccessToken() {
772
- internalLogger.info(`Get Graph Access token with scopes: '${this.scopes}'`);
775
+ internalLogger.info(`Get Graph Access token with scopes: '${this.scopes.toString()}'`);
773
776
  let accessToken;
774
777
  if (this.credentialOrTeamsFx.getCredential) {
775
778
  accessToken = await this.credentialOrTeamsFx
@@ -795,6 +798,14 @@ class MsGraphAuthProvider {
795
798
  // Copyright (c) Microsoft Corporation.
796
799
  /**
797
800
  * Get Microsoft graph client.
801
+ * @deprecated Use `TokenCredentialAuthenticationProvider` and `Client.initWithMiddleware` instead.
802
+ * ```typescript
803
+ * const authProvider = new TokenCredentialAuthenticationProvider(credential, { scopes: scope });
804
+ * const graph = Client.initWithMiddleware({
805
+ * authProvider: authProvider,
806
+ * });
807
+ * ```
808
+ *
798
809
  * @example
799
810
  * Get Microsoft graph client by TokenCredential
800
811
  * ```typescript
@@ -852,6 +863,14 @@ function createMicrosoftGraphClient(teamsfx, scopes) {
852
863
  // eslint-disable-next-line no-secrets/no-secrets
853
864
  /**
854
865
  * Get Microsoft graph client.
866
+ * @deprecated Use `TokenCredentialAuthenticationProvider` and `Client.initWithMiddleware` instead.
867
+ * ```typescript
868
+ * const authProvider = new TokenCredentialAuthenticationProvider(credential, { scopes: scope });
869
+ * const graph = Client.initWithMiddleware({
870
+ * authProvider: authProvider,
871
+ * });
872
+ * ```
873
+ *
855
874
  * @example
856
875
  * Get Microsoft graph client by TokenCredential
857
876
  * ```typescript
@@ -1007,7 +1026,7 @@ function isMsiAuthentication(teamsfx) {
1007
1026
  function generateDefaultConfig(teamsfx, databaseName) {
1008
1027
  internalLogger.verbose(`SQL server ${teamsfx.getConfig("sqlServerEndpoint")}
1009
1028
  , user name ${teamsfx.getConfig("sqlUsername")}
1010
- , database name ${databaseName}`);
1029
+ , database name ${databaseName ? databaseName : ""}`);
1011
1030
  const config = {
1012
1031
  server: teamsfx.getConfig("sqlServerEndpoint"),
1013
1032
  authentication: {
@@ -1060,7 +1079,7 @@ async function generateTokenConfig(teamsfx, databaseName) {
1060
1079
  };
1061
1080
  internalLogger.verbose(`Generate token configuration success
1062
1081
  , server endpoint is ${teamsfx.getConfig("sqlServerEndpoint")}
1063
- , database name is ${databaseName}`);
1082
+ , database name is ${databaseName ? databaseName : ""}`);
1064
1083
  return config;
1065
1084
  }
1066
1085
  internalLogger.error(`Generate token configuration
@@ -1328,7 +1347,8 @@ class TeamsBotSsoPrompt extends Dialog {
1328
1347
  async sendOAuthCardAsync(context) {
1329
1348
  internalLogger.verbose("Send OAuth card to get SSO token");
1330
1349
  const account = await TeamsInfo.getMember(context, context.activity.from.id);
1331
- internalLogger.verbose("Get Teams member account user principal name: " + account.userPrincipalName);
1350
+ internalLogger.verbose("Get Teams member account user principal name: " +
1351
+ (account.userPrincipalName ? account.userPrincipalName : ""));
1332
1352
  const loginHint = account.userPrincipalName ? account.userPrincipalName : "";
1333
1353
  const signInResource = this.getSignInResource(loginHint);
1334
1354
  const card = CardFactory.oauthCard("", "Teams SSO Sign In", "Sign In", signInResource.signInLink, signInResource.tokenExchangeResource);
@@ -1528,18 +1548,18 @@ class BasicAuthProvider {
1528
1548
  * @throws {@link ErrorCode|AuthorizationInfoAlreadyExists} - when Authorization header or auth property already exists in request configuration.
1529
1549
  * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
1530
1550
  */
1531
- async AddAuthenticationInfo(config) {
1551
+ AddAuthenticationInfo(config) {
1532
1552
  if (config.headers && config.headers["Authorization"]) {
1533
- throw new ErrorWithCode(ErrorMessage.AuthorizationHeaderAlreadyExists, ErrorCode.AuthorizationInfoAlreadyExists);
1553
+ return Promise.reject(new ErrorWithCode(ErrorMessage.AuthorizationHeaderAlreadyExists, ErrorCode.AuthorizationInfoAlreadyExists));
1534
1554
  }
1535
1555
  if (config.auth) {
1536
- throw new ErrorWithCode(ErrorMessage.BasicCredentialAlreadyExists, ErrorCode.AuthorizationInfoAlreadyExists);
1556
+ return Promise.reject(new ErrorWithCode(ErrorMessage.BasicCredentialAlreadyExists, ErrorCode.AuthorizationInfoAlreadyExists));
1537
1557
  }
1538
1558
  config.auth = {
1539
1559
  username: this.userName,
1540
1560
  password: this.password,
1541
1561
  };
1542
- return config;
1562
+ return Promise.resolve(config);
1543
1563
  }
1544
1564
  }
1545
1565
 
@@ -1579,14 +1599,14 @@ class ApiKeyProvider {
1579
1599
  * @throws {@link ErrorCode|AuthorizationInfoAlreadyExists} - when API key already exists in request header or url query parameter.
1580
1600
  * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
1581
1601
  */
1582
- async AddAuthenticationInfo(config) {
1602
+ AddAuthenticationInfo(config) {
1583
1603
  switch (this.keyLocation) {
1584
1604
  case ApiKeyLocation.Header:
1585
1605
  if (!config.headers) {
1586
1606
  config.headers = {};
1587
1607
  }
1588
1608
  if (config.headers[this.keyName]) {
1589
- throw new ErrorWithCode(formatString(ErrorMessage.DuplicateApiKeyInHeader, this.keyName), ErrorCode.AuthorizationInfoAlreadyExists);
1609
+ return Promise.reject(new ErrorWithCode(formatString(ErrorMessage.DuplicateApiKeyInHeader, this.keyName), ErrorCode.AuthorizationInfoAlreadyExists));
1590
1610
  }
1591
1611
  config.headers[this.keyName] = this.keyValue;
1592
1612
  break;
@@ -1600,12 +1620,12 @@ class ApiKeyProvider {
1600
1620
  urlHasDefinedApiKey = url.searchParams.has(this.keyName);
1601
1621
  }
1602
1622
  if (config.params[this.keyName] || urlHasDefinedApiKey) {
1603
- throw new ErrorWithCode(formatString(ErrorMessage.DuplicateApiKeyInQueryParam, this.keyName), ErrorCode.AuthorizationInfoAlreadyExists);
1623
+ return Promise.reject(new ErrorWithCode(formatString(ErrorMessage.DuplicateApiKeyInQueryParam, this.keyName), ErrorCode.AuthorizationInfoAlreadyExists));
1604
1624
  }
1605
1625
  config.params[this.keyName] = this.keyValue;
1606
1626
  break;
1607
1627
  }
1608
- return config;
1628
+ return Promise.resolve(config);
1609
1629
  }
1610
1630
  }
1611
1631
  /**
@@ -1652,7 +1672,7 @@ class CertificateAuthProvider {
1652
1672
  *
1653
1673
  * @throws {@link ErrorCode|InvalidParameter} - when custom httpsAgent in the request has duplicate properties with certOption provided in constructor.
1654
1674
  */
1655
- async AddAuthenticationInfo(config) {
1675
+ AddAuthenticationInfo(config) {
1656
1676
  if (!config.httpsAgent) {
1657
1677
  config.httpsAgent = new Agent(this.certOption);
1658
1678
  }
@@ -1660,12 +1680,12 @@ class CertificateAuthProvider {
1660
1680
  const existingProperties = new Set(Object.keys(config.httpsAgent.options));
1661
1681
  for (const property of Object.keys(this.certOption)) {
1662
1682
  if (existingProperties.has(property)) {
1663
- throw new ErrorWithCode(formatString(ErrorMessage.DuplicateHttpsOptionProperty, property), ErrorCode.InvalidParameter);
1683
+ return Promise.reject(new ErrorWithCode(formatString(ErrorMessage.DuplicateHttpsOptionProperty, property), ErrorCode.InvalidParameter));
1664
1684
  }
1665
1685
  }
1666
1686
  Object.assign(config.httpsAgent.options, this.certOption);
1667
1687
  }
1668
- return config;
1688
+ return Promise.resolve(config);
1669
1689
  }
1670
1690
  }
1671
1691
  /**
@@ -1734,6 +1754,8 @@ const ReservedKey = new Set([
1734
1754
  ]);
1735
1755
  /**
1736
1756
  * A class providing credential and configuration.
1757
+ * @deprecated Please use {@link TeamsUserCredential}
1758
+ * in browser environment and {@link OnBehalfOfUserCredential} or {@link AppCredential} in NodeJS.
1737
1759
  */
1738
1760
  class TeamsFx {
1739
1761
  /**
@@ -2402,6 +2424,7 @@ function cloneConversation(conversation) {
2402
2424
  */
2403
2425
  function getKey(reference) {
2404
2426
  var _a, _b;
2427
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
2405
2428
  return `_${(_a = reference.conversation) === null || _a === void 0 ? void 0 : _a.tenantId}_${(_b = reference.conversation) === null || _b === void 0 ? void 0 : _b.id}`;
2406
2429
  }
2407
2430
  /**
@@ -2719,7 +2742,7 @@ class Channel$1 {
2719
2742
  async sendMessage(text, onError) {
2720
2743
  const response = {};
2721
2744
  await this.parent.adapter.continueConversation(this.parent.conversationReference, async (context) => {
2722
- const conversation = await this.newConversation(context);
2745
+ const conversation = this.newConversation(context);
2723
2746
  await this.parent.adapter.continueConversation(conversation, async (ctx) => {
2724
2747
  try {
2725
2748
  const res = await ctx.sendActivity(text);
@@ -2748,7 +2771,7 @@ class Channel$1 {
2748
2771
  async sendAdaptiveCard(card, onError) {
2749
2772
  const response = {};
2750
2773
  await this.parent.adapter.continueConversation(this.parent.conversationReference, async (context) => {
2751
- const conversation = await this.newConversation(context);
2774
+ const conversation = this.newConversation(context);
2752
2775
  await this.parent.adapter.continueConversation(conversation, async (ctx) => {
2753
2776
  try {
2754
2777
  const res = await ctx.sendActivity({
@@ -2771,7 +2794,7 @@ class Channel$1 {
2771
2794
  /**
2772
2795
  * @internal
2773
2796
  */
2774
- async newConversation(context) {
2797
+ newConversation(context) {
2775
2798
  const reference = TurnContext.getConversationReference(context.activity);
2776
2799
  const channelConversation = cloneConversation(reference);
2777
2800
  channelConversation.conversation.id = this.info.id || "";
@@ -3481,8 +3504,7 @@ class DefaultBotSsoExecutionActivityHandler extends TeamsActivityHandler {
3481
3504
  timeout: (_h = (_g = ssoConfig.dialog) === null || _g === void 0 ? void 0 : _g.ssoPromptConfig) === null || _h === void 0 ? void 0 : _h.timeout,
3482
3505
  endOnInvalidMessage: (_k = (_j = ssoConfig.dialog) === null || _j === void 0 ? void 0 : _j.ssoPromptConfig) === null || _k === void 0 ? void 0 : _k.endOnInvalidMessage,
3483
3506
  };
3484
- const teamsfx = new TeamsFx(IdentityType.User, Object.assign({}, customConfig));
3485
- this.ssoExecutionDialog = new BotSsoExecutionDialog(dedupStorage, settings, teamsfx);
3507
+ this.ssoExecutionDialog = new BotSsoExecutionDialog(dedupStorage, settings, customConfig, customConfig.initiateLoginEndpoint);
3486
3508
  this.conversationState = conversationState;
3487
3509
  this.dialogState = conversationState.createProperty("DialogState");
3488
3510
  this.userState = userState;
@@ -3643,9 +3665,12 @@ class ConversationBot$1 {
3643
3665
  // the default error handler
3644
3666
  adapter.onTurnError = async (context, error) => {
3645
3667
  // This check writes out errors to console.
3668
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
3646
3669
  console.error(`[onTurnError] unhandled error: ${error}`);
3647
3670
  // Send a trace activity, which will be displayed in Bot Framework Emulator
3648
- await context.sendTraceActivity("OnTurnError Trace", `${error}`, "https://www.botframework.com/schemas/error", "TurnError");
3671
+ await context.sendTraceActivity("OnTurnError Trace",
3672
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
3673
+ `${error}`, "https://www.botframework.com/schemas/error", "TurnError");
3649
3674
  // Send a message to the user
3650
3675
  await context.sendActivity(`The bot encountered unhandled error: ${error.message}`);
3651
3676
  await context.sendActivity("To continue to run this bot, please fix the bot source code.");
@@ -3924,6 +3949,7 @@ async function executionWithTokenAndConfig(context, authConfig, initiateLoginEnd
3924
3949
  }
3925
3950
  /**
3926
3951
  * execution in message extension with SSO token.
3952
+ * @deprecated Use {@link executionWithTokenAndConfig} instead.
3927
3953
  *
3928
3954
  * @param {TurnContext} context - The context object for the current turn.
3929
3955
  * @param {AuthenticationConfiguration} config - User custom the message extension authentication configuration.
@@ -3972,7 +3998,7 @@ async function executionWithToken(context, config, scopes, logic) {
3972
3998
  // eslint-disable-next-line no-secrets/no-secrets
3973
3999
  /**
3974
4000
  * Users execute query in message extension with SSO or access token.
3975
- *
4001
+ * @deprecated Use {@link handleMessageExtensionQueryWithSSO} instead.
3976
4002
  *
3977
4003
  * @param {TurnContext} context - The context object for the current turn.
3978
4004
  * @param {AuthenticationConfiguration} config - User custom the message extension authentication configuration.
@@ -4245,11 +4271,11 @@ class Channel {
4245
4271
  /**
4246
4272
  * @internal
4247
4273
  */
4248
- async newConversation(context) {
4274
+ newConversation(context) {
4249
4275
  const reference = TurnContext.getConversationReference(context.activity);
4250
4276
  const channelConversation = cloneConversation(reference);
4251
4277
  channelConversation.conversation.id = this.info.id || "";
4252
- return channelConversation;
4278
+ return Promise.resolve(channelConversation);
4253
4279
  }
4254
4280
  }
4255
4281
  /**
@@ -4556,6 +4582,27 @@ class NotificationBot {
4556
4582
  }
4557
4583
  return new TeamsBotInstallation(this.adapter, conversationReference, this.botAppId);
4558
4584
  }
4585
+ /**
4586
+ * Validate the installation by getting paged memebers.
4587
+ *
4588
+ * @param conversationReference The bound `ConversationReference`.
4589
+ * @returns Returns false if recieves `BotNotInConversationRoster` error, otherwise returns true.
4590
+ */
4591
+ async validateInstallation(conversationReference) {
4592
+ let isValid = true;
4593
+ await this.adapter.continueConversationAsync(this.botAppId, conversationReference, async (context) => {
4594
+ try {
4595
+ // try get member to see if the installation is still valid
4596
+ await TeamsInfo.getPagedMembers(context, 1);
4597
+ }
4598
+ catch (error) {
4599
+ if (error.code === "BotNotInConversationRoster") {
4600
+ isValid = false;
4601
+ }
4602
+ }
4603
+ });
4604
+ return isValid;
4605
+ }
4559
4606
  /**
4560
4607
  * Gets a pagined list of targets where the bot is installed.
4561
4608
  *
@@ -4567,7 +4614,7 @@ class NotificationBot {
4567
4614
  *
4568
4615
  * @returns An array of {@link TeamsBotInstallation} with paged data and continuation token.
4569
4616
  */
4570
- async getPagedInstallations(pageSize, continuationToken) {
4617
+ async getPagedInstallations(pageSize, continuationToken, validationEnabled = true) {
4571
4618
  if (this.conversationReferenceStore === undefined || this.adapter === undefined) {
4572
4619
  throw new Error("NotificationBot has not been initialized.");
4573
4620
  }
@@ -4575,19 +4622,12 @@ class NotificationBot {
4575
4622
  const targets = [];
4576
4623
  for (const reference of references.data) {
4577
4624
  // validate connection
4578
- let valid = true;
4579
- await this.adapter.continueConversationAsync(this.botAppId, reference, async (context) => {
4580
- try {
4581
- // try get member to see if the installation is still valid
4582
- await TeamsInfo.getPagedMembers(context, 1);
4583
- }
4584
- catch (error) {
4585
- if (error.code === "BotNotInConversationRoster") {
4586
- valid = false;
4587
- }
4588
- }
4589
- });
4590
- if (valid) {
4625
+ let valid;
4626
+ if (validationEnabled) {
4627
+ // try get member to see if the installation is still valid
4628
+ valid = await this.validateInstallation(reference);
4629
+ }
4630
+ if (!validationEnabled || (validationEnabled && valid)) {
4591
4631
  targets.push(new TeamsBotInstallation(this.adapter, reference, this.botAppId));
4592
4632
  }
4593
4633
  else {
@@ -4849,9 +4889,9 @@ class ConversationBot {
4849
4889
  // the default error handler
4850
4890
  adapter.onTurnError = async (context, error) => {
4851
4891
  // This check writes out errors to console.
4852
- console.error(`[onTurnError] unhandled error: ${error}`);
4892
+ console.error(`[onTurnError] unhandled error`, error);
4853
4893
  // Send a trace activity, which will be displayed in Bot Framework Emulator
4854
- await context.sendTraceActivity("OnTurnError Trace", `${error}`, "https://www.botframework.com/schemas/error", "TurnError");
4894
+ await context.sendTraceActivity("OnTurnError Trace", error instanceof Error ? error.message : error, "https://www.botframework.com/schemas/error", "TurnError");
4855
4895
  // Send a message to the user
4856
4896
  await context.sendActivity(`The bot encountered unhandled error: ${error.message}`);
4857
4897
  await context.sendActivity("To continue to run this bot, please fix the bot source code.");