@microsoft/teamsfx 2.2.3-alpha.9b38c38b5.0 → 2.2.3-alpha.dea6b9e8a.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,7 +734,7 @@ 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
 
@@ -769,7 +770,7 @@ class MsGraphAuthProvider {
769
770
  *
770
771
  */
771
772
  async getAccessToken() {
772
- internalLogger.info(`Get Graph Access token with scopes: '${this.scopes}'`);
773
+ internalLogger.info(`Get Graph Access token with scopes: '${this.scopes.toString()}'`);
773
774
  let accessToken;
774
775
  if (this.credentialOrTeamsFx.getCredential) {
775
776
  accessToken = await this.credentialOrTeamsFx
@@ -1007,7 +1008,7 @@ function isMsiAuthentication(teamsfx) {
1007
1008
  function generateDefaultConfig(teamsfx, databaseName) {
1008
1009
  internalLogger.verbose(`SQL server ${teamsfx.getConfig("sqlServerEndpoint")}
1009
1010
  , user name ${teamsfx.getConfig("sqlUsername")}
1010
- , database name ${databaseName}`);
1011
+ , database name ${databaseName ? databaseName : ""}`);
1011
1012
  const config = {
1012
1013
  server: teamsfx.getConfig("sqlServerEndpoint"),
1013
1014
  authentication: {
@@ -1060,7 +1061,7 @@ async function generateTokenConfig(teamsfx, databaseName) {
1060
1061
  };
1061
1062
  internalLogger.verbose(`Generate token configuration success
1062
1063
  , server endpoint is ${teamsfx.getConfig("sqlServerEndpoint")}
1063
- , database name is ${databaseName}`);
1064
+ , database name is ${databaseName ? databaseName : ""}`);
1064
1065
  return config;
1065
1066
  }
1066
1067
  internalLogger.error(`Generate token configuration
@@ -1328,7 +1329,8 @@ class TeamsBotSsoPrompt extends Dialog {
1328
1329
  async sendOAuthCardAsync(context) {
1329
1330
  internalLogger.verbose("Send OAuth card to get SSO token");
1330
1331
  const account = await TeamsInfo.getMember(context, context.activity.from.id);
1331
- internalLogger.verbose("Get Teams member account user principal name: " + account.userPrincipalName);
1332
+ internalLogger.verbose("Get Teams member account user principal name: " +
1333
+ (account.userPrincipalName ? account.userPrincipalName : ""));
1332
1334
  const loginHint = account.userPrincipalName ? account.userPrincipalName : "";
1333
1335
  const signInResource = this.getSignInResource(loginHint);
1334
1336
  const card = CardFactory.oauthCard("", "Teams SSO Sign In", "Sign In", signInResource.signInLink, signInResource.tokenExchangeResource);
@@ -1528,18 +1530,18 @@ class BasicAuthProvider {
1528
1530
  * @throws {@link ErrorCode|AuthorizationInfoAlreadyExists} - when Authorization header or auth property already exists in request configuration.
1529
1531
  * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
1530
1532
  */
1531
- async AddAuthenticationInfo(config) {
1533
+ AddAuthenticationInfo(config) {
1532
1534
  if (config.headers && config.headers["Authorization"]) {
1533
- throw new ErrorWithCode(ErrorMessage.AuthorizationHeaderAlreadyExists, ErrorCode.AuthorizationInfoAlreadyExists);
1535
+ return Promise.reject(new ErrorWithCode(ErrorMessage.AuthorizationHeaderAlreadyExists, ErrorCode.AuthorizationInfoAlreadyExists));
1534
1536
  }
1535
1537
  if (config.auth) {
1536
- throw new ErrorWithCode(ErrorMessage.BasicCredentialAlreadyExists, ErrorCode.AuthorizationInfoAlreadyExists);
1538
+ return Promise.reject(new ErrorWithCode(ErrorMessage.BasicCredentialAlreadyExists, ErrorCode.AuthorizationInfoAlreadyExists));
1537
1539
  }
1538
1540
  config.auth = {
1539
1541
  username: this.userName,
1540
1542
  password: this.password,
1541
1543
  };
1542
- return config;
1544
+ return Promise.resolve(config);
1543
1545
  }
1544
1546
  }
1545
1547
 
@@ -1579,14 +1581,14 @@ class ApiKeyProvider {
1579
1581
  * @throws {@link ErrorCode|AuthorizationInfoAlreadyExists} - when API key already exists in request header or url query parameter.
1580
1582
  * @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
1581
1583
  */
1582
- async AddAuthenticationInfo(config) {
1584
+ AddAuthenticationInfo(config) {
1583
1585
  switch (this.keyLocation) {
1584
1586
  case ApiKeyLocation.Header:
1585
1587
  if (!config.headers) {
1586
1588
  config.headers = {};
1587
1589
  }
1588
1590
  if (config.headers[this.keyName]) {
1589
- throw new ErrorWithCode(formatString(ErrorMessage.DuplicateApiKeyInHeader, this.keyName), ErrorCode.AuthorizationInfoAlreadyExists);
1591
+ return Promise.reject(new ErrorWithCode(formatString(ErrorMessage.DuplicateApiKeyInHeader, this.keyName), ErrorCode.AuthorizationInfoAlreadyExists));
1590
1592
  }
1591
1593
  config.headers[this.keyName] = this.keyValue;
1592
1594
  break;
@@ -1600,12 +1602,12 @@ class ApiKeyProvider {
1600
1602
  urlHasDefinedApiKey = url.searchParams.has(this.keyName);
1601
1603
  }
1602
1604
  if (config.params[this.keyName] || urlHasDefinedApiKey) {
1603
- throw new ErrorWithCode(formatString(ErrorMessage.DuplicateApiKeyInQueryParam, this.keyName), ErrorCode.AuthorizationInfoAlreadyExists);
1605
+ return Promise.reject(new ErrorWithCode(formatString(ErrorMessage.DuplicateApiKeyInQueryParam, this.keyName), ErrorCode.AuthorizationInfoAlreadyExists));
1604
1606
  }
1605
1607
  config.params[this.keyName] = this.keyValue;
1606
1608
  break;
1607
1609
  }
1608
- return config;
1610
+ return Promise.resolve(config);
1609
1611
  }
1610
1612
  }
1611
1613
  /**
@@ -1652,7 +1654,7 @@ class CertificateAuthProvider {
1652
1654
  *
1653
1655
  * @throws {@link ErrorCode|InvalidParameter} - when custom httpsAgent in the request has duplicate properties with certOption provided in constructor.
1654
1656
  */
1655
- async AddAuthenticationInfo(config) {
1657
+ AddAuthenticationInfo(config) {
1656
1658
  if (!config.httpsAgent) {
1657
1659
  config.httpsAgent = new Agent(this.certOption);
1658
1660
  }
@@ -1660,12 +1662,12 @@ class CertificateAuthProvider {
1660
1662
  const existingProperties = new Set(Object.keys(config.httpsAgent.options));
1661
1663
  for (const property of Object.keys(this.certOption)) {
1662
1664
  if (existingProperties.has(property)) {
1663
- throw new ErrorWithCode(formatString(ErrorMessage.DuplicateHttpsOptionProperty, property), ErrorCode.InvalidParameter);
1665
+ return Promise.reject(new ErrorWithCode(formatString(ErrorMessage.DuplicateHttpsOptionProperty, property), ErrorCode.InvalidParameter));
1664
1666
  }
1665
1667
  }
1666
1668
  Object.assign(config.httpsAgent.options, this.certOption);
1667
1669
  }
1668
- return config;
1670
+ return Promise.resolve(config);
1669
1671
  }
1670
1672
  }
1671
1673
  /**
@@ -2719,7 +2721,7 @@ class Channel$1 {
2719
2721
  async sendMessage(text, onError) {
2720
2722
  const response = {};
2721
2723
  await this.parent.adapter.continueConversation(this.parent.conversationReference, async (context) => {
2722
- const conversation = await this.newConversation(context);
2724
+ const conversation = this.newConversation(context);
2723
2725
  await this.parent.adapter.continueConversation(conversation, async (ctx) => {
2724
2726
  try {
2725
2727
  const res = await ctx.sendActivity(text);
@@ -2748,7 +2750,7 @@ class Channel$1 {
2748
2750
  async sendAdaptiveCard(card, onError) {
2749
2751
  const response = {};
2750
2752
  await this.parent.adapter.continueConversation(this.parent.conversationReference, async (context) => {
2751
- const conversation = await this.newConversation(context);
2753
+ const conversation = this.newConversation(context);
2752
2754
  await this.parent.adapter.continueConversation(conversation, async (ctx) => {
2753
2755
  try {
2754
2756
  const res = await ctx.sendActivity({
@@ -2771,7 +2773,7 @@ class Channel$1 {
2771
2773
  /**
2772
2774
  * @internal
2773
2775
  */
2774
- async newConversation(context) {
2776
+ newConversation(context) {
2775
2777
  const reference = TurnContext.getConversationReference(context.activity);
2776
2778
  const channelConversation = cloneConversation(reference);
2777
2779
  channelConversation.conversation.id = this.info.id || "";
@@ -4245,11 +4247,11 @@ class Channel {
4245
4247
  /**
4246
4248
  * @internal
4247
4249
  */
4248
- async newConversation(context) {
4250
+ newConversation(context) {
4249
4251
  const reference = TurnContext.getConversationReference(context.activity);
4250
4252
  const channelConversation = cloneConversation(reference);
4251
4253
  channelConversation.conversation.id = this.info.id || "";
4252
- return channelConversation;
4254
+ return Promise.resolve(channelConversation);
4253
4255
  }
4254
4256
  }
4255
4257
  /**
@@ -4556,6 +4558,27 @@ class NotificationBot {
4556
4558
  }
4557
4559
  return new TeamsBotInstallation(this.adapter, conversationReference, this.botAppId);
4558
4560
  }
4561
+ /**
4562
+ * Validate the installation by getting paged memebers.
4563
+ *
4564
+ * @param conversationReference The bound `ConversationReference`.
4565
+ * @returns Returns false if recieves `BotNotInConversationRoster` error, otherwise returns true.
4566
+ */
4567
+ async validateInstallation(conversationReference) {
4568
+ let isValid = true;
4569
+ await this.adapter.continueConversationAsync(this.botAppId, conversationReference, async (context) => {
4570
+ try {
4571
+ // try get member to see if the installation is still valid
4572
+ await TeamsInfo.getPagedMembers(context, 1);
4573
+ }
4574
+ catch (error) {
4575
+ if (error.code === "BotNotInConversationRoster") {
4576
+ isValid = false;
4577
+ }
4578
+ }
4579
+ });
4580
+ return isValid;
4581
+ }
4559
4582
  /**
4560
4583
  * Gets a pagined list of targets where the bot is installed.
4561
4584
  *
@@ -4567,7 +4590,7 @@ class NotificationBot {
4567
4590
  *
4568
4591
  * @returns An array of {@link TeamsBotInstallation} with paged data and continuation token.
4569
4592
  */
4570
- async getPagedInstallations(pageSize, continuationToken) {
4593
+ async getPagedInstallations(pageSize, continuationToken, validationEnabled = true) {
4571
4594
  if (this.conversationReferenceStore === undefined || this.adapter === undefined) {
4572
4595
  throw new Error("NotificationBot has not been initialized.");
4573
4596
  }
@@ -4575,19 +4598,12 @@ class NotificationBot {
4575
4598
  const targets = [];
4576
4599
  for (const reference of references.data) {
4577
4600
  // 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) {
4601
+ let valid;
4602
+ if (validationEnabled) {
4603
+ // try get member to see if the installation is still valid
4604
+ valid = await this.validateInstallation(reference);
4605
+ }
4606
+ if (!validationEnabled || (validationEnabled && valid)) {
4591
4607
  targets.push(new TeamsBotInstallation(this.adapter, reference, this.botAppId));
4592
4608
  }
4593
4609
  else {
@@ -4849,9 +4865,9 @@ class ConversationBot {
4849
4865
  // the default error handler
4850
4866
  adapter.onTurnError = async (context, error) => {
4851
4867
  // This check writes out errors to console.
4852
- console.error(`[onTurnError] unhandled error: ${error}`);
4868
+ console.error(`[onTurnError] unhandled error`, error);
4853
4869
  // 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");
4870
+ await context.sendTraceActivity("OnTurnError Trace", error instanceof Error ? error.message : error, "https://www.botframework.com/schemas/error", "TurnError");
4855
4871
  // Send a message to the user
4856
4872
  await context.sendActivity(`The bot encountered unhandled error: ${error.message}`);
4857
4873
  await context.sendActivity("To continue to run this bot, please fix the bot source code.");