@microsoft/teamsfx 1.1.2-alpha.9bd0cb559.0 → 1.1.2-alpha.9d488528e.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/dist/index.esm2017.js +100 -60
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +255 -17
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +112 -68
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +269 -17
- package/dist/index.node.cjs.js.map +1 -1
- package/package.json +7 -5
- package/types/teamsfx.d.ts +105 -57
package/dist/index.node.cjs.js
CHANGED
|
@@ -167,6 +167,7 @@ ErrorMessage.EmptyParameter = "Parameter {0} is empty";
|
|
|
167
167
|
ErrorMessage.DuplicateHttpsOptionProperty = "Axios HTTPS agent already defined value for property {0}";
|
|
168
168
|
ErrorMessage.DuplicateApiKeyInHeader = "The request already defined api key in request header with name {0}.";
|
|
169
169
|
ErrorMessage.DuplicateApiKeyInQueryParam = "The request already defined api key in query parameter with name {0}.";
|
|
170
|
+
ErrorMessage.OnlySupportInQueryActivity = "The handleMessageExtensionQueryWithToken only support in handleTeamsMessagingExtensionQuery with composeExtension/query type.";
|
|
170
171
|
/**
|
|
171
172
|
* Error class with code and message thrown by the SDK.
|
|
172
173
|
*/
|
|
@@ -2250,7 +2251,6 @@ class CommandResponseMiddleware {
|
|
|
2250
2251
|
yield this.processResponse(context, response);
|
|
2251
2252
|
}), ssoHandler.triggerPatterns);
|
|
2252
2253
|
this.ssoCommandHandlers.push(ssoHandler);
|
|
2253
|
-
this.commandHandlers.push(ssoHandler);
|
|
2254
2254
|
this.hasSsoCommand = true;
|
|
2255
2255
|
}
|
|
2256
2256
|
onTurn(context, next) {
|
|
@@ -2259,23 +2259,29 @@ class CommandResponseMiddleware {
|
|
|
2259
2259
|
if (context.activity.type === botbuilder.ActivityTypes.Message) {
|
|
2260
2260
|
// Invoke corresponding command handler for the command response
|
|
2261
2261
|
const commandText = this.getActivityText(context.activity);
|
|
2262
|
+
let alreadyProcessed = false;
|
|
2262
2263
|
for (const handler of this.commandHandlers) {
|
|
2263
2264
|
const matchResult = this.shouldTrigger(handler.triggerPatterns, commandText);
|
|
2264
2265
|
// It is important to note that the command bot will stop processing handlers
|
|
2265
2266
|
// when the first command handler is matched.
|
|
2266
2267
|
if (!!matchResult) {
|
|
2267
|
-
|
|
2268
|
+
const message = {
|
|
2269
|
+
text: commandText,
|
|
2270
|
+
};
|
|
2271
|
+
message.matches = Array.isArray(matchResult) ? matchResult : void 0;
|
|
2272
|
+
const response = yield handler.handleCommandReceived(context, message);
|
|
2273
|
+
yield this.processResponse(context, response);
|
|
2274
|
+
alreadyProcessed = true;
|
|
2275
|
+
break;
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
if (!alreadyProcessed) {
|
|
2279
|
+
for (const handler of this.ssoCommandHandlers) {
|
|
2280
|
+
const matchResult = this.shouldTrigger(handler.triggerPatterns, commandText);
|
|
2281
|
+
if (!!matchResult) {
|
|
2268
2282
|
yield ((_a = this.ssoActivityHandler) === null || _a === void 0 ? void 0 : _a.run(context));
|
|
2283
|
+
break;
|
|
2269
2284
|
}
|
|
2270
|
-
else {
|
|
2271
|
-
const message = {
|
|
2272
|
-
text: commandText,
|
|
2273
|
-
};
|
|
2274
|
-
message.matches = Array.isArray(matchResult) ? matchResult : void 0;
|
|
2275
|
-
const response = yield handler.handleCommandReceived(context, message);
|
|
2276
|
-
yield this.processResponse(context, response);
|
|
2277
|
-
}
|
|
2278
|
-
break;
|
|
2279
2285
|
}
|
|
2280
2286
|
}
|
|
2281
2287
|
}
|
|
@@ -2300,9 +2306,6 @@ class CommandResponseMiddleware {
|
|
|
2300
2306
|
}
|
|
2301
2307
|
});
|
|
2302
2308
|
}
|
|
2303
|
-
isSsoExecutionHandler(handler) {
|
|
2304
|
-
return this.ssoCommandHandlers.indexOf(handler) >= 0;
|
|
2305
|
-
}
|
|
2306
2309
|
matchPattern(pattern, text) {
|
|
2307
2310
|
if (text) {
|
|
2308
2311
|
if (typeof pattern === "string") {
|
|
@@ -2912,6 +2915,10 @@ class TeamsBotInstallation {
|
|
|
2912
2915
|
*/
|
|
2913
2916
|
channels() {
|
|
2914
2917
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2918
|
+
const channels = [];
|
|
2919
|
+
if (this.type !== exports.NotificationTargetType.Channel) {
|
|
2920
|
+
return channels;
|
|
2921
|
+
}
|
|
2915
2922
|
let teamsChannels = [];
|
|
2916
2923
|
yield this.adapter.continueConversation(this.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2917
2924
|
const teamId = getTeamsBotInstallationId(context);
|
|
@@ -2919,7 +2926,6 @@ class TeamsBotInstallation {
|
|
|
2919
2926
|
teamsChannels = yield botbuilder.TeamsInfo.getTeamChannels(context, teamId);
|
|
2920
2927
|
}
|
|
2921
2928
|
}));
|
|
2922
|
-
const channels = [];
|
|
2923
2929
|
for (const channel of teamsChannels) {
|
|
2924
2930
|
channels.push(new Channel(this, channel));
|
|
2925
2931
|
}
|
|
@@ -2947,6 +2953,26 @@ class TeamsBotInstallation {
|
|
|
2947
2953
|
return members;
|
|
2948
2954
|
});
|
|
2949
2955
|
}
|
|
2956
|
+
/**
|
|
2957
|
+
* Get team details from this bot installation
|
|
2958
|
+
*
|
|
2959
|
+
* @returns the team details if bot is installed into a team, otherwise returns undefined.
|
|
2960
|
+
*/
|
|
2961
|
+
getTeamDetails() {
|
|
2962
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2963
|
+
if (this.type !== exports.NotificationTargetType.Channel) {
|
|
2964
|
+
return undefined;
|
|
2965
|
+
}
|
|
2966
|
+
let teamDetails;
|
|
2967
|
+
yield this.adapter.continueConversation(this.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2968
|
+
const teamId = getTeamsBotInstallationId(context);
|
|
2969
|
+
if (teamId !== undefined) {
|
|
2970
|
+
teamDetails = yield botbuilder.TeamsInfo.getTeamDetails(context, teamId);
|
|
2971
|
+
}
|
|
2972
|
+
}));
|
|
2973
|
+
return teamDetails;
|
|
2974
|
+
});
|
|
2975
|
+
}
|
|
2950
2976
|
}
|
|
2951
2977
|
/**
|
|
2952
2978
|
* Provide utilities to send notification to varies targets (e.g., member, group, channel).
|
|
@@ -3008,7 +3034,129 @@ class NotificationBot {
|
|
|
3008
3034
|
return targets;
|
|
3009
3035
|
});
|
|
3010
3036
|
}
|
|
3011
|
-
|
|
3037
|
+
/**
|
|
3038
|
+
* Returns the first {@link Member} where predicate is true, and undefined otherwise.
|
|
3039
|
+
*
|
|
3040
|
+
* @param predicate find calls predicate once for each member of the installation,
|
|
3041
|
+
* until it finds one where predicate returns true. If such a member is found, find
|
|
3042
|
+
* immediately returns that member. Otherwise, find returns undefined.
|
|
3043
|
+
* @param scope the scope to find members from the installations
|
|
3044
|
+
* (personal chat, group chat, Teams channel).
|
|
3045
|
+
* @returns the first {@link Member} where predicate is true, and undefined otherwise.
|
|
3046
|
+
*/
|
|
3047
|
+
findMember(predicate, scope) {
|
|
3048
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
3049
|
+
for (const target of yield this.installations()) {
|
|
3050
|
+
if (this.matchSearchScope(target, scope)) {
|
|
3051
|
+
for (const member of yield target.members()) {
|
|
3052
|
+
if (yield predicate(member)) {
|
|
3053
|
+
return member;
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
}
|
|
3057
|
+
}
|
|
3058
|
+
return;
|
|
3059
|
+
});
|
|
3060
|
+
}
|
|
3061
|
+
/**
|
|
3062
|
+
* Returns the first {@link Channel} where predicate is true, and undefined otherwise.
|
|
3063
|
+
*
|
|
3064
|
+
* @param predicate find calls predicate once for each channel of the installation,
|
|
3065
|
+
* until it finds one where predicate returns true. If such a channel is found, find
|
|
3066
|
+
* immediately returns that channel. Otherwise, find returns undefined.
|
|
3067
|
+
* @returns the first {@link Channel} where predicate is true, and undefined otherwise.
|
|
3068
|
+
*/
|
|
3069
|
+
findChannel(predicate) {
|
|
3070
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
3071
|
+
for (const target of yield this.installations()) {
|
|
3072
|
+
if (target.type === exports.NotificationTargetType.Channel) {
|
|
3073
|
+
const teamDetails = yield target.getTeamDetails();
|
|
3074
|
+
for (const channel of yield target.channels()) {
|
|
3075
|
+
if (yield predicate(channel, teamDetails)) {
|
|
3076
|
+
return channel;
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3079
|
+
}
|
|
3080
|
+
}
|
|
3081
|
+
return;
|
|
3082
|
+
});
|
|
3083
|
+
}
|
|
3084
|
+
/**
|
|
3085
|
+
* Returns all {@link Member} where predicate is true, and empty array otherwise.
|
|
3086
|
+
*
|
|
3087
|
+
* @param predicate find calls predicate for each member of the installation.
|
|
3088
|
+
* @param scope the scope to find members from the installations
|
|
3089
|
+
* (personal chat, group chat, Teams channel).
|
|
3090
|
+
* @returns an array of {@link Member} where predicate is true, and empty array otherwise.
|
|
3091
|
+
*/
|
|
3092
|
+
findAllMembers(predicate, scope) {
|
|
3093
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
3094
|
+
const members = [];
|
|
3095
|
+
for (const target of yield this.installations()) {
|
|
3096
|
+
if (this.matchSearchScope(target, scope)) {
|
|
3097
|
+
for (const member of yield target.members()) {
|
|
3098
|
+
if (yield predicate(member)) {
|
|
3099
|
+
members.push(member);
|
|
3100
|
+
}
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
}
|
|
3104
|
+
return members;
|
|
3105
|
+
});
|
|
3106
|
+
}
|
|
3107
|
+
/**
|
|
3108
|
+
* Returns all {@link Channel} where predicate is true, and empty array otherwise.
|
|
3109
|
+
*
|
|
3110
|
+
* @param predicate find calls predicate for each channel of the installation.
|
|
3111
|
+
* @returns an array of {@link Channel} where predicate is true, and empty array otherwise.
|
|
3112
|
+
*/
|
|
3113
|
+
findAllChannels(predicate) {
|
|
3114
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
3115
|
+
const channels = [];
|
|
3116
|
+
for (const target of yield this.installations()) {
|
|
3117
|
+
if (target.type === exports.NotificationTargetType.Channel) {
|
|
3118
|
+
const teamDetails = yield target.getTeamDetails();
|
|
3119
|
+
for (const channel of yield target.channels()) {
|
|
3120
|
+
if (yield predicate(channel, teamDetails)) {
|
|
3121
|
+
channels.push(channel);
|
|
3122
|
+
}
|
|
3123
|
+
}
|
|
3124
|
+
}
|
|
3125
|
+
}
|
|
3126
|
+
return channels;
|
|
3127
|
+
});
|
|
3128
|
+
}
|
|
3129
|
+
matchSearchScope(target, scope) {
|
|
3130
|
+
scope = scope !== null && scope !== void 0 ? scope : exports.SearchScope.All;
|
|
3131
|
+
return ((target.type === exports.NotificationTargetType.Channel && (scope & exports.SearchScope.Channel) !== 0) ||
|
|
3132
|
+
(target.type === exports.NotificationTargetType.Group && (scope & exports.SearchScope.Group) !== 0) ||
|
|
3133
|
+
(target.type === exports.NotificationTargetType.Person && (scope & exports.SearchScope.Person) !== 0));
|
|
3134
|
+
}
|
|
3135
|
+
}
|
|
3136
|
+
/**
|
|
3137
|
+
* The search scope when calling {@link NotificationBot.findMember} and {@link NotificationBot.findAllMembers}.
|
|
3138
|
+
* The search scope is a flagged enum and it can be combined with `|`.
|
|
3139
|
+
* For example, to search from personal chat and group chat, use `SearchScope.Person | SearchScope.Group`.
|
|
3140
|
+
*/
|
|
3141
|
+
exports.SearchScope = void 0;
|
|
3142
|
+
(function (SearchScope) {
|
|
3143
|
+
/**
|
|
3144
|
+
* Search members from the installations in personal chat only.
|
|
3145
|
+
*/
|
|
3146
|
+
SearchScope[SearchScope["Person"] = 1] = "Person";
|
|
3147
|
+
/**
|
|
3148
|
+
* Search members from the installations in group chat only.
|
|
3149
|
+
*/
|
|
3150
|
+
SearchScope[SearchScope["Group"] = 2] = "Group";
|
|
3151
|
+
/**
|
|
3152
|
+
* Search members from the installations in Teams channel only.
|
|
3153
|
+
*/
|
|
3154
|
+
SearchScope[SearchScope["Channel"] = 4] = "Channel";
|
|
3155
|
+
/**
|
|
3156
|
+
* Search members from all installations including personal chat, group chat and Teams channel.
|
|
3157
|
+
*/
|
|
3158
|
+
SearchScope[SearchScope["All"] = 7] = "All";
|
|
3159
|
+
})(exports.SearchScope || (exports.SearchScope = {}));
|
|
3012
3160
|
|
|
3013
3161
|
// Copyright (c) Microsoft Corporation.
|
|
3014
3162
|
let DIALOG_NAME = "BotSsoExecutionDialog";
|
|
@@ -3646,6 +3794,110 @@ class MessageBuilder {
|
|
|
3646
3794
|
}
|
|
3647
3795
|
}
|
|
3648
3796
|
|
|
3797
|
+
// Copyright (c) Microsoft Corporation.
|
|
3798
|
+
/**
|
|
3799
|
+
* Retrieve the OAuth Sign in Link to use in the MessagingExtensionResult Suggested Actions.
|
|
3800
|
+
* This method only work on MessageExtension with Query now.
|
|
3801
|
+
*
|
|
3802
|
+
* @param {TeamsFx} teamsfx - Used to provide configuration and auth.
|
|
3803
|
+
* @param {string | string[]} scopes - The list of scopes for which the token will have access.
|
|
3804
|
+
*
|
|
3805
|
+
* @returns SignIn link CardAction with 200 status code.
|
|
3806
|
+
*/
|
|
3807
|
+
function getSignInResponseForMessageExtension(teamsfx, scopes) {
|
|
3808
|
+
const scopesArray = getScopesArray(scopes);
|
|
3809
|
+
const signInLink = `${teamsfx.getConfig("initiateLoginEndpoint")}?scope=${encodeURI(scopesArray.join(" "))}&clientId=${teamsfx.getConfig("clientId")}&tenantId=${teamsfx.getConfig("tenantId")}`;
|
|
3810
|
+
return {
|
|
3811
|
+
composeExtension: {
|
|
3812
|
+
type: "silentAuth",
|
|
3813
|
+
suggestedActions: {
|
|
3814
|
+
actions: [
|
|
3815
|
+
{
|
|
3816
|
+
type: "openUrl",
|
|
3817
|
+
value: signInLink,
|
|
3818
|
+
title: "Message Extension OAuth",
|
|
3819
|
+
},
|
|
3820
|
+
],
|
|
3821
|
+
},
|
|
3822
|
+
},
|
|
3823
|
+
};
|
|
3824
|
+
}
|
|
3825
|
+
/**
|
|
3826
|
+
* execution in message extension with SSO token.
|
|
3827
|
+
*
|
|
3828
|
+
* @param {TurnContext} context - The context object for the current turn.
|
|
3829
|
+
* @param {AuthenticationConfiguration} config - User custom the message extension authentication configuration.
|
|
3830
|
+
* @param {string[]} scopes - The list of scopes for which the token will have access.
|
|
3831
|
+
* @param {function} logic - Business logic when executing the query in message extension with SSO or access token.
|
|
3832
|
+
*
|
|
3833
|
+
* @throws {@link ErrorCode|InternalError} when failed to get access token with unknown error.
|
|
3834
|
+
* @throws {@link ErrorCode|TokenExpiredError} when SSO token has already expired.
|
|
3835
|
+
* @throws {@link ErrorCode|ServiceError} when failed to get access token from simple auth server.
|
|
3836
|
+
* @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
|
|
3837
|
+
* @throws {@link ErrorCode|RuntimeNotSupported} when runtime is nodeJS.
|
|
3838
|
+
*
|
|
3839
|
+
* @returns A MessageExtension Response for the activity. If the logic not return any, return void instead.
|
|
3840
|
+
*/
|
|
3841
|
+
function executionWithToken(context, config, scopes, logic) {
|
|
3842
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
3843
|
+
const valueObj = context.activity.value;
|
|
3844
|
+
if (!valueObj.authentication || !valueObj.authentication.token) {
|
|
3845
|
+
internalLogger.verbose("No AccessToken in request, return silentAuth for AccessToken");
|
|
3846
|
+
return getSignInResponseForMessageExtension(new TeamsFx(exports.IdentityType.User, config), scopes);
|
|
3847
|
+
}
|
|
3848
|
+
try {
|
|
3849
|
+
const teamsfx = new TeamsFx(exports.IdentityType.User, config).setSsoToken(valueObj.authentication.token);
|
|
3850
|
+
const token = yield teamsfx.getCredential().getToken(scopes);
|
|
3851
|
+
const ssoTokenExpiration = parseJwt(valueObj.authentication.token).exp;
|
|
3852
|
+
const tokenRes = {
|
|
3853
|
+
ssoToken: valueObj.authentication.token,
|
|
3854
|
+
ssoTokenExpiration: new Date(ssoTokenExpiration * 1000).toISOString(),
|
|
3855
|
+
token: token.token,
|
|
3856
|
+
expiration: token.expiresOnTimestamp.toString(),
|
|
3857
|
+
connectionName: "",
|
|
3858
|
+
};
|
|
3859
|
+
if (logic) {
|
|
3860
|
+
return yield logic(tokenRes);
|
|
3861
|
+
}
|
|
3862
|
+
}
|
|
3863
|
+
catch (err) {
|
|
3864
|
+
if (err instanceof ErrorWithCode && err.code === exports.ErrorCode.UiRequiredError) {
|
|
3865
|
+
internalLogger.verbose("User not consent yet, return 412 to user consent first.");
|
|
3866
|
+
const response = { status: 412 };
|
|
3867
|
+
yield context.sendActivity({ value: response, type: botbuilder.ActivityTypes.InvokeResponse });
|
|
3868
|
+
return;
|
|
3869
|
+
}
|
|
3870
|
+
throw err;
|
|
3871
|
+
}
|
|
3872
|
+
});
|
|
3873
|
+
}
|
|
3874
|
+
/**
|
|
3875
|
+
* Users execute query in message extension with SSO or access token.
|
|
3876
|
+
*
|
|
3877
|
+
* @param {TurnContext} context - The context object for the current turn.
|
|
3878
|
+
* @param {AuthenticationConfiguration} config - User custom the message extension authentication configuration.
|
|
3879
|
+
* @param {string| string[]} scopes - The list of scopes for which the token will have access.
|
|
3880
|
+
* @param {function} logic - Business logic when executing the query in message extension with SSO or access token.
|
|
3881
|
+
*
|
|
3882
|
+
* @throws {@link ErrorCode|InternalError} when User invoke not response to message extension query.
|
|
3883
|
+
* @throws {@link ErrorCode|InternalError} when failed to get access token with unknown error.
|
|
3884
|
+
* @throws {@link ErrorCode|TokenExpiredError} when SSO token has already expired.
|
|
3885
|
+
* @throws {@link ErrorCode|ServiceError} when failed to get access token from simple auth server.
|
|
3886
|
+
* @throws {@link ErrorCode|InvalidParameter} when scopes is not a valid string or string array.
|
|
3887
|
+
* @throws {@link ErrorCode|RuntimeNotSupported} when runtime is nodeJS.
|
|
3888
|
+
*
|
|
3889
|
+
* @returns A MessageExtension Response for the activity. If the logic not return any, return void instead.
|
|
3890
|
+
*/
|
|
3891
|
+
function handleMessageExtensionQueryWithToken(context, config, scopes, logic) {
|
|
3892
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
3893
|
+
if (context.activity.name != "composeExtension/query") {
|
|
3894
|
+
internalLogger.error(ErrorMessage.OnlySupportInQueryActivity);
|
|
3895
|
+
throw new ErrorWithCode(formatString(ErrorMessage.OnlySupportInQueryActivity), exports.ErrorCode.FailedOperation);
|
|
3896
|
+
}
|
|
3897
|
+
return yield executionWithToken(context, config !== null && config !== void 0 ? config : {}, scopes, logic);
|
|
3898
|
+
});
|
|
3899
|
+
}
|
|
3900
|
+
|
|
3649
3901
|
exports.ApiKeyProvider = ApiKeyProvider;
|
|
3650
3902
|
exports.AppCredential = AppCredential;
|
|
3651
3903
|
exports.BasicAuthProvider = BasicAuthProvider;
|
|
@@ -3656,7 +3908,6 @@ exports.CertificateAuthProvider = CertificateAuthProvider;
|
|
|
3656
3908
|
exports.Channel = Channel;
|
|
3657
3909
|
exports.CommandBot = CommandBot;
|
|
3658
3910
|
exports.ConversationBot = ConversationBot;
|
|
3659
|
-
exports.DefaultBotSsoExecutionActivityHandler = DefaultBotSsoExecutionActivityHandler;
|
|
3660
3911
|
exports.ErrorWithCode = ErrorWithCode;
|
|
3661
3912
|
exports.InvokeResponseFactory = InvokeResponseFactory;
|
|
3662
3913
|
exports.Member = Member;
|
|
@@ -3674,6 +3925,7 @@ exports.createPemCertOption = createPemCertOption;
|
|
|
3674
3925
|
exports.createPfxCertOption = createPfxCertOption;
|
|
3675
3926
|
exports.getLogLevel = getLogLevel;
|
|
3676
3927
|
exports.getTediousConnectionConfig = getTediousConnectionConfig;
|
|
3928
|
+
exports.handleMessageExtensionQueryWithToken = handleMessageExtensionQueryWithToken;
|
|
3677
3929
|
exports.sendAdaptiveCard = sendAdaptiveCard;
|
|
3678
3930
|
exports.sendMessage = sendMessage;
|
|
3679
3931
|
exports.setLogFunction = setLogFunction;
|