@microsoft/teamsfx 2.2.3-alpha.9b38c38b5.0 → 2.2.3-alpha.ebba7eb40.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.
- package/README.md +162 -113
- package/dist/index.esm2017.js +84 -62
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +80 -44
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +66 -108
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +122 -98
- package/dist/index.node.cjs.js.map +1 -1
- package/package.json +3 -4
- package/types/teamsfx.d.ts +32 -2
package/dist/index.esm2017.mjs
CHANGED
@@ -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
|
-
|
717
|
-
|
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
|
-
|
725
|
-
|
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
|
-
|
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: " +
|
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
|
-
|
1551
|
+
AddAuthenticationInfo(config) {
|
1532
1552
|
if (config.headers && config.headers["Authorization"]) {
|
1533
|
-
|
1553
|
+
return Promise.reject(new ErrorWithCode(ErrorMessage.AuthorizationHeaderAlreadyExists, ErrorCode.AuthorizationInfoAlreadyExists));
|
1534
1554
|
}
|
1535
1555
|
if (config.auth) {
|
1536
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
/**
|
@@ -2719,7 +2741,7 @@ class Channel$1 {
|
|
2719
2741
|
async sendMessage(text, onError) {
|
2720
2742
|
const response = {};
|
2721
2743
|
await this.parent.adapter.continueConversation(this.parent.conversationReference, async (context) => {
|
2722
|
-
const conversation =
|
2744
|
+
const conversation = this.newConversation(context);
|
2723
2745
|
await this.parent.adapter.continueConversation(conversation, async (ctx) => {
|
2724
2746
|
try {
|
2725
2747
|
const res = await ctx.sendActivity(text);
|
@@ -2748,7 +2770,7 @@ class Channel$1 {
|
|
2748
2770
|
async sendAdaptiveCard(card, onError) {
|
2749
2771
|
const response = {};
|
2750
2772
|
await this.parent.adapter.continueConversation(this.parent.conversationReference, async (context) => {
|
2751
|
-
const conversation =
|
2773
|
+
const conversation = this.newConversation(context);
|
2752
2774
|
await this.parent.adapter.continueConversation(conversation, async (ctx) => {
|
2753
2775
|
try {
|
2754
2776
|
const res = await ctx.sendActivity({
|
@@ -2771,7 +2793,7 @@ class Channel$1 {
|
|
2771
2793
|
/**
|
2772
2794
|
* @internal
|
2773
2795
|
*/
|
2774
|
-
|
2796
|
+
newConversation(context) {
|
2775
2797
|
const reference = TurnContext.getConversationReference(context.activity);
|
2776
2798
|
const channelConversation = cloneConversation(reference);
|
2777
2799
|
channelConversation.conversation.id = this.info.id || "";
|
@@ -3481,8 +3503,7 @@ class DefaultBotSsoExecutionActivityHandler extends TeamsActivityHandler {
|
|
3481
3503
|
timeout: (_h = (_g = ssoConfig.dialog) === null || _g === void 0 ? void 0 : _g.ssoPromptConfig) === null || _h === void 0 ? void 0 : _h.timeout,
|
3482
3504
|
endOnInvalidMessage: (_k = (_j = ssoConfig.dialog) === null || _j === void 0 ? void 0 : _j.ssoPromptConfig) === null || _k === void 0 ? void 0 : _k.endOnInvalidMessage,
|
3483
3505
|
};
|
3484
|
-
|
3485
|
-
this.ssoExecutionDialog = new BotSsoExecutionDialog(dedupStorage, settings, teamsfx);
|
3506
|
+
this.ssoExecutionDialog = new BotSsoExecutionDialog(dedupStorage, settings, customConfig, customConfig.initiateLoginEndpoint);
|
3486
3507
|
this.conversationState = conversationState;
|
3487
3508
|
this.dialogState = conversationState.createProperty("DialogState");
|
3488
3509
|
this.userState = userState;
|
@@ -3924,6 +3945,7 @@ async function executionWithTokenAndConfig(context, authConfig, initiateLoginEnd
|
|
3924
3945
|
}
|
3925
3946
|
/**
|
3926
3947
|
* execution in message extension with SSO token.
|
3948
|
+
* @deprecated Use {@link executionWithTokenAndConfig} instead.
|
3927
3949
|
*
|
3928
3950
|
* @param {TurnContext} context - The context object for the current turn.
|
3929
3951
|
* @param {AuthenticationConfiguration} config - User custom the message extension authentication configuration.
|
@@ -3972,7 +3994,7 @@ async function executionWithToken(context, config, scopes, logic) {
|
|
3972
3994
|
// eslint-disable-next-line no-secrets/no-secrets
|
3973
3995
|
/**
|
3974
3996
|
* Users execute query in message extension with SSO or access token.
|
3975
|
-
*
|
3997
|
+
* @deprecated Use {@link handleMessageExtensionQueryWithSSO} instead.
|
3976
3998
|
*
|
3977
3999
|
* @param {TurnContext} context - The context object for the current turn.
|
3978
4000
|
* @param {AuthenticationConfiguration} config - User custom the message extension authentication configuration.
|
@@ -4245,11 +4267,11 @@ class Channel {
|
|
4245
4267
|
/**
|
4246
4268
|
* @internal
|
4247
4269
|
*/
|
4248
|
-
|
4270
|
+
newConversation(context) {
|
4249
4271
|
const reference = TurnContext.getConversationReference(context.activity);
|
4250
4272
|
const channelConversation = cloneConversation(reference);
|
4251
4273
|
channelConversation.conversation.id = this.info.id || "";
|
4252
|
-
return channelConversation;
|
4274
|
+
return Promise.resolve(channelConversation);
|
4253
4275
|
}
|
4254
4276
|
}
|
4255
4277
|
/**
|
@@ -4556,6 +4578,27 @@ class NotificationBot {
|
|
4556
4578
|
}
|
4557
4579
|
return new TeamsBotInstallation(this.adapter, conversationReference, this.botAppId);
|
4558
4580
|
}
|
4581
|
+
/**
|
4582
|
+
* Validate the installation by getting paged memebers.
|
4583
|
+
*
|
4584
|
+
* @param conversationReference The bound `ConversationReference`.
|
4585
|
+
* @returns Returns false if recieves `BotNotInConversationRoster` error, otherwise returns true.
|
4586
|
+
*/
|
4587
|
+
async validateInstallation(conversationReference) {
|
4588
|
+
let isValid = true;
|
4589
|
+
await this.adapter.continueConversationAsync(this.botAppId, conversationReference, async (context) => {
|
4590
|
+
try {
|
4591
|
+
// try get member to see if the installation is still valid
|
4592
|
+
await TeamsInfo.getPagedMembers(context, 1);
|
4593
|
+
}
|
4594
|
+
catch (error) {
|
4595
|
+
if (error.code === "BotNotInConversationRoster") {
|
4596
|
+
isValid = false;
|
4597
|
+
}
|
4598
|
+
}
|
4599
|
+
});
|
4600
|
+
return isValid;
|
4601
|
+
}
|
4559
4602
|
/**
|
4560
4603
|
* Gets a pagined list of targets where the bot is installed.
|
4561
4604
|
*
|
@@ -4567,7 +4610,7 @@ class NotificationBot {
|
|
4567
4610
|
*
|
4568
4611
|
* @returns An array of {@link TeamsBotInstallation} with paged data and continuation token.
|
4569
4612
|
*/
|
4570
|
-
async getPagedInstallations(pageSize, continuationToken) {
|
4613
|
+
async getPagedInstallations(pageSize, continuationToken, validationEnabled = true) {
|
4571
4614
|
if (this.conversationReferenceStore === undefined || this.adapter === undefined) {
|
4572
4615
|
throw new Error("NotificationBot has not been initialized.");
|
4573
4616
|
}
|
@@ -4575,19 +4618,12 @@ class NotificationBot {
|
|
4575
4618
|
const targets = [];
|
4576
4619
|
for (const reference of references.data) {
|
4577
4620
|
// validate connection
|
4578
|
-
let valid
|
4579
|
-
|
4580
|
-
try
|
4581
|
-
|
4582
|
-
|
4583
|
-
|
4584
|
-
catch (error) {
|
4585
|
-
if (error.code === "BotNotInConversationRoster") {
|
4586
|
-
valid = false;
|
4587
|
-
}
|
4588
|
-
}
|
4589
|
-
});
|
4590
|
-
if (valid) {
|
4621
|
+
let valid;
|
4622
|
+
if (validationEnabled) {
|
4623
|
+
// try get member to see if the installation is still valid
|
4624
|
+
valid = await this.validateInstallation(reference);
|
4625
|
+
}
|
4626
|
+
if (!validationEnabled || (validationEnabled && valid)) {
|
4591
4627
|
targets.push(new TeamsBotInstallation(this.adapter, reference, this.botAppId));
|
4592
4628
|
}
|
4593
4629
|
else {
|
@@ -4849,9 +4885,9 @@ class ConversationBot {
|
|
4849
4885
|
// the default error handler
|
4850
4886
|
adapter.onTurnError = async (context, error) => {
|
4851
4887
|
// This check writes out errors to console.
|
4852
|
-
console.error(`[onTurnError] unhandled error
|
4888
|
+
console.error(`[onTurnError] unhandled error`, error);
|
4853
4889
|
// Send a trace activity, which will be displayed in Bot Framework Emulator
|
4854
|
-
await context.sendTraceActivity("OnTurnError Trace",
|
4890
|
+
await context.sendTraceActivity("OnTurnError Trace", error instanceof Error ? error.message : error, "https://www.botframework.com/schemas/error", "TurnError");
|
4855
4891
|
// Send a message to the user
|
4856
4892
|
await context.sendActivity(`The bot encountered unhandled error: ${error.message}`);
|
4857
4893
|
await context.sendActivity("To continue to run this bot, please fix the bot source code.");
|