@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.
- 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 +85 -45
- 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 +127 -99
- 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
|
/**
|
@@ -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 =
|
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 =
|
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
|
-
|
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
|
-
|
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",
|
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
|
-
|
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
|
4579
|
-
|
4580
|
-
try
|
4581
|
-
|
4582
|
-
|
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
|
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",
|
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.");
|