@microsoft/teamsfx 1.1.2-alpha.7eddd6cf4.0 → 1.1.2-alpha.9bd0cb559.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.
@@ -69,6 +69,30 @@ exports.ErrorCode = void 0;
69
69
  * Channel is not supported error.
70
70
  */
71
71
  ErrorCode["ChannelNotSupported"] = "ChannelNotSupported";
72
+ /**
73
+ * Failed to retrieve sso token
74
+ */
75
+ ErrorCode["FailedToRetrieveSsoToken"] = "FailedToRetrieveSsoToken";
76
+ /**
77
+ * Failed to process sso handler
78
+ */
79
+ ErrorCode["FailedToProcessSsoHandler"] = "FailedToProcessSsoHandler";
80
+ /**
81
+ * Cannot find command
82
+ */
83
+ ErrorCode["CannotFindCommand"] = "CannotFindCommand";
84
+ /**
85
+ * Failed to run sso step
86
+ */
87
+ ErrorCode["FailedToRunSsoStep"] = "FailedToRunSsoStep";
88
+ /**
89
+ * Failed to run dedup step
90
+ */
91
+ ErrorCode["FailedToRunDedupStep"] = "FailedToRunDedupStep";
92
+ /**
93
+ * Sso activity handler is undefined
94
+ */
95
+ ErrorCode["SsoActivityHandlerIsUndefined"] = "SsoActivityHandlerIsUndefined";
72
96
  /**
73
97
  * Runtime is not supported error.
74
98
  */
@@ -124,6 +148,15 @@ ErrorMessage.NodejsRuntimeNotSupported = "{0} is not supported in Node.";
124
148
  ErrorMessage.FailToAcquireTokenOnBehalfOfUser = "Failed to acquire access token on behalf of user: {0}";
125
149
  // ChannelNotSupported Error
126
150
  ErrorMessage.OnlyMSTeamsChannelSupported = "{0} is only supported in MS Teams Channel";
151
+ ErrorMessage.FailedToProcessSsoHandler = "Failed to process sso handler: {0}";
152
+ // FailedToRetrieveSsoToken Error
153
+ ErrorMessage.FailedToRetrieveSsoToken = "Failed to retrieve sso token, user failed to finish the AAD consent flow.";
154
+ // CannotFindCommand Error
155
+ ErrorMessage.CannotFindCommand = "Cannot find command: {0}";
156
+ ErrorMessage.FailedToRunSsoStep = "Failed to run dialog to retrieve sso token: {0}";
157
+ ErrorMessage.FailedToRunDedupStep = "Failed to run dialog to remove duplicated messages: {0}";
158
+ // SsoActivityHandlerIsUndefined Error
159
+ ErrorMessage.SsoActivityHandlerIsNull = "Sso command can only be used or added when sso activity handler is not undefined";
127
160
  // IdentityTypeNotSupported Error
128
161
  ErrorMessage.IdentityTypeNotSupported = "{0} identity is not supported in {1}";
129
162
  // AuthorizationInfoError
@@ -2192,43 +2225,84 @@ class CardActionBot {
2192
2225
  * @internal
2193
2226
  */
2194
2227
  class CommandResponseMiddleware {
2195
- constructor(handlers) {
2228
+ constructor(handlers, ssoHandlers, activityHandler) {
2196
2229
  this.commandHandlers = [];
2197
- if (handlers && handlers.length > 0) {
2198
- this.commandHandlers.push(...handlers);
2230
+ this.ssoCommandHandlers = [];
2231
+ handlers = handlers !== null && handlers !== void 0 ? handlers : [];
2232
+ ssoHandlers = ssoHandlers !== null && ssoHandlers !== void 0 ? ssoHandlers : [];
2233
+ this.hasSsoCommand = ssoHandlers.length > 0;
2234
+ this.ssoActivityHandler = activityHandler;
2235
+ if (this.hasSsoCommand && !this.ssoActivityHandler) {
2236
+ internalLogger.error(ErrorMessage.SsoActivityHandlerIsNull);
2237
+ throw new ErrorWithCode(ErrorMessage.SsoActivityHandlerIsNull, exports.ErrorCode.SsoActivityHandlerIsUndefined);
2238
+ }
2239
+ this.commandHandlers.push(...handlers);
2240
+ for (const ssoHandler of ssoHandlers) {
2241
+ this.addSsoCommand(ssoHandler);
2199
2242
  }
2200
2243
  }
2244
+ addSsoCommand(ssoHandler) {
2245
+ var _a;
2246
+ (_a = this.ssoActivityHandler) === null || _a === void 0 ? void 0 : _a.addCommand((context, tokenResponse, message) => tslib.__awaiter(this, void 0, void 0, function* () {
2247
+ const matchResult = this.shouldTrigger(ssoHandler.triggerPatterns, message.text);
2248
+ message.matches = Array.isArray(matchResult) ? matchResult : void 0;
2249
+ const response = yield ssoHandler.handleCommandReceived(context, message, tokenResponse);
2250
+ yield this.processResponse(context, response);
2251
+ }), ssoHandler.triggerPatterns);
2252
+ this.ssoCommandHandlers.push(ssoHandler);
2253
+ this.commandHandlers.push(ssoHandler);
2254
+ this.hasSsoCommand = true;
2255
+ }
2201
2256
  onTurn(context, next) {
2257
+ var _a, _b;
2202
2258
  return tslib.__awaiter(this, void 0, void 0, function* () {
2203
2259
  if (context.activity.type === botbuilder.ActivityTypes.Message) {
2204
2260
  // Invoke corresponding command handler for the command response
2205
2261
  const commandText = this.getActivityText(context.activity);
2206
- const message = {
2207
- text: commandText,
2208
- };
2209
2262
  for (const handler of this.commandHandlers) {
2210
2263
  const matchResult = this.shouldTrigger(handler.triggerPatterns, commandText);
2211
2264
  // It is important to note that the command bot will stop processing handlers
2212
2265
  // when the first command handler is matched.
2213
2266
  if (!!matchResult) {
2214
- message.matches = Array.isArray(matchResult) ? matchResult : void 0;
2215
- const response = yield handler.handleCommandReceived(context, message);
2216
- if (typeof response === "string") {
2217
- yield context.sendActivity(response);
2267
+ if (this.isSsoExecutionHandler(handler)) {
2268
+ yield ((_a = this.ssoActivityHandler) === null || _a === void 0 ? void 0 : _a.run(context));
2218
2269
  }
2219
2270
  else {
2220
- const replyActivity = response;
2221
- if (replyActivity) {
2222
- yield context.sendActivity(replyActivity);
2223
- }
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);
2224
2277
  }
2225
2278
  break;
2226
2279
  }
2227
2280
  }
2228
2281
  }
2282
+ else {
2283
+ if (this.hasSsoCommand) {
2284
+ yield ((_b = this.ssoActivityHandler) === null || _b === void 0 ? void 0 : _b.run(context));
2285
+ }
2286
+ }
2229
2287
  yield next();
2230
2288
  });
2231
2289
  }
2290
+ processResponse(context, response) {
2291
+ return tslib.__awaiter(this, void 0, void 0, function* () {
2292
+ if (typeof response === "string") {
2293
+ yield context.sendActivity(response);
2294
+ }
2295
+ else {
2296
+ const replyActivity = response;
2297
+ if (replyActivity) {
2298
+ yield context.sendActivity(replyActivity);
2299
+ }
2300
+ }
2301
+ });
2302
+ }
2303
+ isSsoExecutionHandler(handler) {
2304
+ return this.ssoCommandHandlers.indexOf(handler) >= 0;
2305
+ }
2232
2306
  matchPattern(pattern, text) {
2233
2307
  if (text) {
2234
2308
  if (typeof pattern === "string") {
@@ -2278,14 +2352,15 @@ class CommandBot {
2278
2352
  * @param adapter The bound `BotFrameworkAdapter`.
2279
2353
  * @param options - initialize options
2280
2354
  */
2281
- constructor(adapter, options) {
2282
- this.middleware = new CommandResponseMiddleware(options === null || options === void 0 ? void 0 : options.commands);
2355
+ constructor(adapter, options, ssoCommandActivityHandler, ssoConfig) {
2356
+ this.ssoConfig = ssoConfig;
2357
+ this.middleware = new CommandResponseMiddleware(options === null || options === void 0 ? void 0 : options.commands, options === null || options === void 0 ? void 0 : options.ssoCommands, ssoCommandActivityHandler);
2283
2358
  this.adapter = adapter.use(this.middleware);
2284
2359
  }
2285
2360
  /**
2286
2361
  * Registers a command into the command bot.
2287
2362
  *
2288
- * @param command The command to registered.
2363
+ * @param command The command to register.
2289
2364
  */
2290
2365
  registerCommand(command) {
2291
2366
  if (command) {
@@ -2295,13 +2370,41 @@ class CommandBot {
2295
2370
  /**
2296
2371
  * Registers commands into the command bot.
2297
2372
  *
2298
- * @param commands The command to registered.
2373
+ * @param commands The commands to register.
2299
2374
  */
2300
2375
  registerCommands(commands) {
2301
2376
  if (commands) {
2302
2377
  this.middleware.commandHandlers.push(...commands);
2303
2378
  }
2304
2379
  }
2380
+ /**
2381
+ * Registers a sso command into the command bot.
2382
+ *
2383
+ * @param command The command to register.
2384
+ */
2385
+ registerSsoCommand(ssoCommand) {
2386
+ this.validateSsoActivityHandler();
2387
+ this.middleware.addSsoCommand(ssoCommand);
2388
+ }
2389
+ /**
2390
+ * Registers commands into the command bot.
2391
+ *
2392
+ * @param commands The commands to register.
2393
+ */
2394
+ registerSsoCommands(ssoCommands) {
2395
+ if (ssoCommands.length > 0) {
2396
+ this.validateSsoActivityHandler();
2397
+ for (const ssoCommand of ssoCommands) {
2398
+ this.middleware.addSsoCommand(ssoCommand);
2399
+ }
2400
+ }
2401
+ }
2402
+ validateSsoActivityHandler() {
2403
+ if (!this.middleware.ssoActivityHandler) {
2404
+ internalLogger.error(ErrorMessage.SsoActivityHandlerIsNull);
2405
+ throw new ErrorWithCode(ErrorMessage.SsoActivityHandlerIsNull, exports.ErrorCode.SsoActivityHandlerIsUndefined);
2406
+ }
2407
+ }
2305
2408
  }
2306
2409
 
2307
2410
  // Copyright (c) Microsoft Corporation.
@@ -2907,6 +3010,366 @@ class NotificationBot {
2907
3010
  }
2908
3011
  }
2909
3012
 
3013
+ // Copyright (c) Microsoft Corporation.
3014
+ let DIALOG_NAME = "BotSsoExecutionDialog";
3015
+ let TEAMS_SSO_PROMPT_ID = "TeamsFxSsoPrompt";
3016
+ let COMMAND_ROUTE_DIALOG = "CommandRouteDialog";
3017
+ /**
3018
+ * Sso execution dialog, use to handle sso command
3019
+ */
3020
+ class BotSsoExecutionDialog extends botbuilderDialogs.ComponentDialog {
3021
+ /**
3022
+ * Creates a new instance of the BotSsoExecutionDialog.
3023
+ * @param dedupStorage Helper storage to remove duplicated messages
3024
+ * @param settings The list of scopes for which the token will have access
3025
+ * @param teamsfx {@link TeamsFx} instance for authentication
3026
+ */
3027
+ constructor(dedupStorage, ssoPromptSettings, teamsfx, dialogName) {
3028
+ super(dialogName !== null && dialogName !== void 0 ? dialogName : DIALOG_NAME);
3029
+ this.dedupStorageKeys = [];
3030
+ // Map to store the commandId and triggerPatterns, key: commandId, value: triggerPatterns
3031
+ this.commandMapping = new Map();
3032
+ if (dialogName) {
3033
+ DIALOG_NAME = dialogName;
3034
+ TEAMS_SSO_PROMPT_ID = dialogName + TEAMS_SSO_PROMPT_ID;
3035
+ COMMAND_ROUTE_DIALOG = dialogName + COMMAND_ROUTE_DIALOG;
3036
+ }
3037
+ this.initialDialogId = COMMAND_ROUTE_DIALOG;
3038
+ this.dedupStorage = dedupStorage;
3039
+ this.dedupStorageKeys = [];
3040
+ const ssoDialog = new TeamsBotSsoPrompt(teamsfx, TEAMS_SSO_PROMPT_ID, ssoPromptSettings);
3041
+ this.addDialog(ssoDialog);
3042
+ const commandRouteDialog = new botbuilderDialogs.WaterfallDialog(COMMAND_ROUTE_DIALOG, [
3043
+ this.commandRouteStep.bind(this),
3044
+ ]);
3045
+ this.addDialog(commandRouteDialog);
3046
+ }
3047
+ /**
3048
+ * Add TeamsFxBotSsoCommandHandler instance
3049
+ * @param handler {@link BotSsoExecutionDialogHandler} callback function
3050
+ * @param triggerPatterns The trigger pattern
3051
+ */
3052
+ addCommand(handler, triggerPatterns) {
3053
+ const commandId = this.getCommandHash(triggerPatterns);
3054
+ const dialog = new botbuilderDialogs.WaterfallDialog(commandId, [
3055
+ this.ssoStep.bind(this),
3056
+ this.dedupStep.bind(this),
3057
+ (stepContext) => tslib.__awaiter(this, void 0, void 0, function* () {
3058
+ const tokenResponse = stepContext.result.tokenResponse;
3059
+ const context = stepContext.context;
3060
+ const message = stepContext.result.message;
3061
+ try {
3062
+ if (tokenResponse) {
3063
+ yield handler(context, tokenResponse, message);
3064
+ }
3065
+ else {
3066
+ throw new Error(ErrorMessage.FailedToRetrieveSsoToken);
3067
+ }
3068
+ return yield stepContext.endDialog();
3069
+ }
3070
+ catch (error) {
3071
+ const errorMsg = formatString(ErrorMessage.FailedToProcessSsoHandler, error.message);
3072
+ internalLogger.error(errorMsg);
3073
+ return yield stepContext.endDialog(new ErrorWithCode(errorMsg, exports.ErrorCode.FailedToProcessSsoHandler));
3074
+ }
3075
+ }),
3076
+ ]);
3077
+ this.commandMapping.set(commandId, triggerPatterns);
3078
+ this.addDialog(dialog);
3079
+ }
3080
+ getCommandHash(patterns) {
3081
+ const expressions = Array.isArray(patterns) ? patterns : [patterns];
3082
+ const patternStr = expressions.join();
3083
+ const patternStrWithoutSpecialChar = patternStr.replace(/[^a-zA-Z0-9]/g, "");
3084
+ const hash = crypto.createHash("sha256").update(patternStr).digest("hex").toLowerCase();
3085
+ return patternStrWithoutSpecialChar + hash;
3086
+ }
3087
+ /**
3088
+ * The run method handles the incoming activity (in the form of a DialogContext) and passes it through the dialog system.
3089
+ *
3090
+ * @param context The context object for the current turn.
3091
+ * @param accessor The instance of StatePropertyAccessor for dialog system.
3092
+ */
3093
+ run(context, accessor) {
3094
+ return tslib.__awaiter(this, void 0, void 0, function* () {
3095
+ const dialogSet = new botbuilderDialogs.DialogSet(accessor);
3096
+ dialogSet.add(this);
3097
+ const dialogContext = yield dialogSet.createContext(context);
3098
+ this.ensureMsTeamsChannel(dialogContext);
3099
+ const results = yield dialogContext.continueDialog();
3100
+ if (results && results.status === botbuilderDialogs.DialogTurnStatus.empty) {
3101
+ yield dialogContext.beginDialog(this.id);
3102
+ }
3103
+ else if (results &&
3104
+ results.status === botbuilderDialogs.DialogTurnStatus.complete &&
3105
+ results.result instanceof Error) {
3106
+ throw results.result;
3107
+ }
3108
+ });
3109
+ }
3110
+ getActivityText(activity) {
3111
+ let text = activity.text;
3112
+ const removedMentionText = botbuilder.TurnContext.removeRecipientMention(activity);
3113
+ if (removedMentionText) {
3114
+ text = removedMentionText
3115
+ .toLowerCase()
3116
+ .replace(/\n|\r\n/g, "")
3117
+ .trim();
3118
+ }
3119
+ return text;
3120
+ }
3121
+ commandRouteStep(stepContext) {
3122
+ return tslib.__awaiter(this, void 0, void 0, function* () {
3123
+ const turnContext = stepContext.context;
3124
+ const text = this.getActivityText(turnContext.activity);
3125
+ const commandId = this.getMatchesCommandId(text);
3126
+ if (commandId) {
3127
+ return yield stepContext.beginDialog(commandId);
3128
+ }
3129
+ const errorMsg = formatString(ErrorMessage.CannotFindCommand, turnContext.activity.text);
3130
+ internalLogger.error(errorMsg);
3131
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.CannotFindCommand);
3132
+ });
3133
+ }
3134
+ ssoStep(stepContext) {
3135
+ return tslib.__awaiter(this, void 0, void 0, function* () {
3136
+ try {
3137
+ const turnContext = stepContext.context;
3138
+ const text = this.getActivityText(turnContext.activity);
3139
+ const message = {
3140
+ text,
3141
+ };
3142
+ stepContext.options.commandMessage = message;
3143
+ return yield stepContext.beginDialog(TEAMS_SSO_PROMPT_ID);
3144
+ }
3145
+ catch (error) {
3146
+ const errorMsg = formatString(ErrorMessage.FailedToRunSsoStep, error.message);
3147
+ internalLogger.error(errorMsg);
3148
+ return yield stepContext.endDialog(new ErrorWithCode(errorMsg, exports.ErrorCode.FailedToRunSsoStep));
3149
+ }
3150
+ });
3151
+ }
3152
+ dedupStep(stepContext) {
3153
+ return tslib.__awaiter(this, void 0, void 0, function* () {
3154
+ const tokenResponse = stepContext.result;
3155
+ if (!tokenResponse) {
3156
+ internalLogger.error(ErrorMessage.FailedToRetrieveSsoToken);
3157
+ return yield stepContext.endDialog(new ErrorWithCode(ErrorMessage.FailedToRetrieveSsoToken, exports.ErrorCode.FailedToRunSsoStep));
3158
+ }
3159
+ try {
3160
+ // Only dedup after ssoStep to make sure that all Teams client would receive the login request
3161
+ if (tokenResponse && (yield this.shouldDedup(stepContext.context))) {
3162
+ return botbuilderDialogs.Dialog.EndOfTurn;
3163
+ }
3164
+ return yield stepContext.next({
3165
+ tokenResponse,
3166
+ message: stepContext.options.commandMessage,
3167
+ });
3168
+ }
3169
+ catch (error) {
3170
+ const errorMsg = formatString(ErrorMessage.FailedToRunDedupStep, error.message);
3171
+ internalLogger.error(errorMsg);
3172
+ return yield stepContext.endDialog(new ErrorWithCode(errorMsg, exports.ErrorCode.FailedToRunDedupStep));
3173
+ }
3174
+ });
3175
+ }
3176
+ /**
3177
+ * Called when the component is ending.
3178
+ *
3179
+ * @param context Context for the current turn of conversation.
3180
+ */
3181
+ onEndDialog(context) {
3182
+ return tslib.__awaiter(this, void 0, void 0, function* () {
3183
+ const conversationId = context.activity.conversation.id;
3184
+ const currentDedupKeys = this.dedupStorageKeys.filter((key) => key.indexOf(conversationId) > 0);
3185
+ yield this.dedupStorage.delete(currentDedupKeys);
3186
+ this.dedupStorageKeys = this.dedupStorageKeys.filter((key) => key.indexOf(conversationId) < 0);
3187
+ });
3188
+ }
3189
+ /**
3190
+ * If a user is signed into multiple Teams clients, the Bot might receive a "signin/tokenExchange" from each client.
3191
+ * Each token exchange request for a specific user login will have an identical activity.value.Id.
3192
+ * Only one of these token exchange requests should be processed by the bot. For a distributed bot in production,
3193
+ * this requires a distributed storage to ensure only one token exchange is processed.
3194
+ * @param context Context for the current turn of conversation.
3195
+ * @returns boolean value indicate whether the message should be removed
3196
+ */
3197
+ shouldDedup(context) {
3198
+ return tslib.__awaiter(this, void 0, void 0, function* () {
3199
+ const storeItem = {
3200
+ eTag: context.activity.value.id,
3201
+ };
3202
+ const key = this.getStorageKey(context);
3203
+ const storeItems = { [key]: storeItem };
3204
+ try {
3205
+ yield this.dedupStorage.write(storeItems);
3206
+ this.dedupStorageKeys.push(key);
3207
+ }
3208
+ catch (err) {
3209
+ if (err instanceof Error && err.message.indexOf("eTag conflict")) {
3210
+ return true;
3211
+ }
3212
+ throw err;
3213
+ }
3214
+ return false;
3215
+ });
3216
+ }
3217
+ getStorageKey(context) {
3218
+ if (!context || !context.activity || !context.activity.conversation) {
3219
+ throw new Error("Invalid context, can not get storage key!");
3220
+ }
3221
+ const activity = context.activity;
3222
+ const channelId = activity.channelId;
3223
+ const conversationId = activity.conversation.id;
3224
+ if (activity.type !== botbuilder.ActivityTypes.Invoke || activity.name !== botbuilder.tokenExchangeOperationName) {
3225
+ throw new Error("TokenExchangeState can only be used with Invokes of signin/tokenExchange.");
3226
+ }
3227
+ const value = activity.value;
3228
+ if (!value || !value.id) {
3229
+ throw new Error("Invalid signin/tokenExchange. Missing activity.value.id.");
3230
+ }
3231
+ return `${channelId}/${conversationId}/${value.id}`;
3232
+ }
3233
+ matchPattern(pattern, text) {
3234
+ if (text) {
3235
+ if (typeof pattern === "string") {
3236
+ const regExp = new RegExp(pattern, "i");
3237
+ return regExp.test(text);
3238
+ }
3239
+ if (pattern instanceof RegExp) {
3240
+ const matches = text.match(pattern);
3241
+ return matches !== null && matches !== void 0 ? matches : false;
3242
+ }
3243
+ }
3244
+ return false;
3245
+ }
3246
+ isPatternMatched(patterns, text) {
3247
+ const expressions = Array.isArray(patterns) ? patterns : [patterns];
3248
+ for (const ex of expressions) {
3249
+ const matches = this.matchPattern(ex, text);
3250
+ return !!matches;
3251
+ }
3252
+ return false;
3253
+ }
3254
+ getMatchesCommandId(text) {
3255
+ for (const command of this.commandMapping) {
3256
+ const pattern = command[1];
3257
+ if (this.isPatternMatched(pattern, text)) {
3258
+ return command[0];
3259
+ }
3260
+ }
3261
+ return undefined;
3262
+ }
3263
+ /**
3264
+ * Ensure bot is running in MS Teams since TeamsBotSsoPrompt is only supported in MS Teams channel.
3265
+ * @param dc dialog context
3266
+ * @throws {@link ErrorCode|ChannelNotSupported} if bot channel is not MS Teams
3267
+ * @internal
3268
+ */
3269
+ ensureMsTeamsChannel(dc) {
3270
+ if (dc.context.activity.channelId != botbuilder.Channels.Msteams) {
3271
+ const errorMsg = formatString(ErrorMessage.OnlyMSTeamsChannelSupported, "SSO execution dialog");
3272
+ internalLogger.error(errorMsg);
3273
+ throw new ErrorWithCode(errorMsg, exports.ErrorCode.ChannelNotSupported);
3274
+ }
3275
+ }
3276
+ }
3277
+
3278
+ // Copyright (c) Microsoft Corporation.
3279
+ /**
3280
+ * Default SSO execution activity handler
3281
+ */
3282
+ class DefaultBotSsoExecutionActivityHandler extends botbuilder.TeamsActivityHandler {
3283
+ /**
3284
+ * Creates a new instance of the DefaultBotSsoExecutionActivityHandler.
3285
+ * @param ssoConfig configuration for SSO command bot
3286
+ *
3287
+ * @remarks
3288
+ * In the constructor, it uses BotSsoConfig parameter which from {@link ConversationBot} options to initialize {@link BotSsoExecutionDialog}.
3289
+ * It also need to register an event handler for the message event which trigger {@link BotSsoExecutionDialog} instance.
3290
+ */
3291
+ constructor(ssoConfig) {
3292
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
3293
+ super();
3294
+ const memoryStorage = new botbuilder.MemoryStorage();
3295
+ const userState = (_b = (_a = ssoConfig.dialog) === null || _a === void 0 ? void 0 : _a.userState) !== null && _b !== void 0 ? _b : new botbuilder.UserState(memoryStorage);
3296
+ const conversationState = (_d = (_c = ssoConfig.dialog) === null || _c === void 0 ? void 0 : _c.conversationState) !== null && _d !== void 0 ? _d : new botbuilder.ConversationState(memoryStorage);
3297
+ const dedupStorage = (_f = (_e = ssoConfig.dialog) === null || _e === void 0 ? void 0 : _e.dedupStorage) !== null && _f !== void 0 ? _f : memoryStorage;
3298
+ const _l = ssoConfig.aad, { scopes } = _l, customConfig = tslib.__rest(_l, ["scopes"]);
3299
+ const settings = {
3300
+ scopes: scopes,
3301
+ timeout: (_h = (_g = ssoConfig.dialog) === null || _g === void 0 ? void 0 : _g.ssoPromptConfig) === null || _h === void 0 ? void 0 : _h.timeout,
3302
+ endOnInvalidMessage: (_k = (_j = ssoConfig.dialog) === null || _j === void 0 ? void 0 : _j.ssoPromptConfig) === null || _k === void 0 ? void 0 : _k.endOnInvalidMessage,
3303
+ };
3304
+ const teamsfx = new TeamsFx(exports.IdentityType.User, Object.assign({}, customConfig));
3305
+ this.ssoExecutionDialog = new BotSsoExecutionDialog(dedupStorage, settings, teamsfx);
3306
+ this.conversationState = conversationState;
3307
+ this.dialogState = conversationState.createProperty("DialogState");
3308
+ this.userState = userState;
3309
+ this.onMessage((context, next) => tslib.__awaiter(this, void 0, void 0, function* () {
3310
+ yield this.ssoExecutionDialog.run(context, this.dialogState);
3311
+ yield next();
3312
+ }));
3313
+ }
3314
+ /**
3315
+ * Add TeamsFxBotSsoCommandHandler instance to SSO execution dialog
3316
+ * @param handler {@link BotSsoExecutionDialogHandler} callback function
3317
+ * @param triggerPatterns The trigger pattern
3318
+ *
3319
+ * @remarks
3320
+ * This function is used to add SSO command to {@link BotSsoExecutionDialog} instance.
3321
+ */
3322
+ addCommand(handler, triggerPatterns) {
3323
+ this.ssoExecutionDialog.addCommand(handler, triggerPatterns);
3324
+ }
3325
+ /**
3326
+ * Called to initiate the event emission process.
3327
+ * @param context The context object for the current turn.
3328
+ */
3329
+ run(context) {
3330
+ const _super = Object.create(null, {
3331
+ run: { get: () => super.run }
3332
+ });
3333
+ return tslib.__awaiter(this, void 0, void 0, function* () {
3334
+ try {
3335
+ yield _super.run.call(this, context);
3336
+ }
3337
+ finally {
3338
+ yield this.conversationState.saveChanges(context, false);
3339
+ yield this.userState.saveChanges(context, false);
3340
+ }
3341
+ });
3342
+ }
3343
+ /**
3344
+ * Receives invoke activities with Activity name of 'signin/verifyState'.
3345
+ * @param context A context object for this turn.
3346
+ * @param query Signin state (part of signin action auth flow) verification invoke query.
3347
+ * @returns A promise that represents the work queued.
3348
+ *
3349
+ * @remarks
3350
+ * It should trigger {@link BotSsoExecutionDialog} instance to handle signin process
3351
+ */
3352
+ handleTeamsSigninVerifyState(context, query) {
3353
+ return tslib.__awaiter(this, void 0, void 0, function* () {
3354
+ yield this.ssoExecutionDialog.run(context, this.dialogState);
3355
+ });
3356
+ }
3357
+ /**
3358
+ * Receives invoke activities with Activity name of 'signin/tokenExchange'
3359
+ * @param context A context object for this turn.
3360
+ * @param query Signin state (part of signin action auth flow) verification invoke query
3361
+ * @returns A promise that represents the work queued.
3362
+ *
3363
+ * @remark
3364
+ * It should trigger {@link BotSsoExecutionDialog} instance to handle signin process
3365
+ */
3366
+ handleTeamsSigninTokenExchange(context, query) {
3367
+ return tslib.__awaiter(this, void 0, void 0, function* () {
3368
+ yield this.ssoExecutionDialog.run(context, this.dialogState);
3369
+ });
3370
+ }
3371
+ }
3372
+
2910
3373
  // Copyright (c) Microsoft Corporation.
2911
3374
  /**
2912
3375
  * Provide utilities for bot conversation, including:
@@ -2969,20 +3432,30 @@ class ConversationBot {
2969
3432
  * @param options - initialize options
2970
3433
  */
2971
3434
  constructor(options) {
2972
- var _a, _b, _c;
3435
+ var _a, _b, _c, _d;
2973
3436
  if (options.adapter) {
2974
3437
  this.adapter = options.adapter;
2975
3438
  }
2976
3439
  else {
2977
3440
  this.adapter = this.createDefaultAdapter(options.adapterConfig);
2978
3441
  }
2979
- if ((_a = options.command) === null || _a === void 0 ? void 0 : _a.enabled) {
2980
- this.command = new CommandBot(this.adapter, options.command);
3442
+ let ssoCommandActivityHandler;
3443
+ if (options === null || options === void 0 ? void 0 : options.ssoConfig) {
3444
+ if ((_a = options.ssoConfig.dialog) === null || _a === void 0 ? void 0 : _a.CustomBotSsoExecutionActivityHandler) {
3445
+ ssoCommandActivityHandler =
3446
+ new options.ssoConfig.dialog.CustomBotSsoExecutionActivityHandler(options.ssoConfig);
3447
+ }
3448
+ else {
3449
+ ssoCommandActivityHandler = new DefaultBotSsoExecutionActivityHandler(options.ssoConfig);
3450
+ }
3451
+ }
3452
+ if ((_b = options.command) === null || _b === void 0 ? void 0 : _b.enabled) {
3453
+ this.command = new CommandBot(this.adapter, options.command, ssoCommandActivityHandler, options.ssoConfig);
2981
3454
  }
2982
- if ((_b = options.notification) === null || _b === void 0 ? void 0 : _b.enabled) {
3455
+ if ((_c = options.notification) === null || _c === void 0 ? void 0 : _c.enabled) {
2983
3456
  this.notification = new NotificationBot(this.adapter, options.notification);
2984
3457
  }
2985
- if ((_c = options.cardAction) === null || _c === void 0 ? void 0 : _c.enabled) {
3458
+ if ((_d = options.cardAction) === null || _d === void 0 ? void 0 : _d.enabled) {
2986
3459
  this.cardAction = new CardActionBot(this.adapter, options.cardAction);
2987
3460
  }
2988
3461
  }
@@ -3177,11 +3650,13 @@ exports.ApiKeyProvider = ApiKeyProvider;
3177
3650
  exports.AppCredential = AppCredential;
3178
3651
  exports.BasicAuthProvider = BasicAuthProvider;
3179
3652
  exports.BearerTokenAuthProvider = BearerTokenAuthProvider;
3653
+ exports.BotSsoExecutionDialog = BotSsoExecutionDialog;
3180
3654
  exports.CardActionBot = CardActionBot;
3181
3655
  exports.CertificateAuthProvider = CertificateAuthProvider;
3182
3656
  exports.Channel = Channel;
3183
3657
  exports.CommandBot = CommandBot;
3184
3658
  exports.ConversationBot = ConversationBot;
3659
+ exports.DefaultBotSsoExecutionActivityHandler = DefaultBotSsoExecutionActivityHandler;
3185
3660
  exports.ErrorWithCode = ErrorWithCode;
3186
3661
  exports.InvokeResponseFactory = InvokeResponseFactory;
3187
3662
  exports.Member = Member;