sp-dev-fx-webparts/samples/react-bot-framework-sso/bot/dialogs/mainDialog.js

114 lines
4.3 KiB
JavaScript

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
const {
ChoicePrompt,
DialogSet,
DialogTurnStatus,
OAuthPrompt,
TextPrompt,
WaterfallDialog
} = require('botbuilder-dialogs');
const { LogoutDialog } = require('./logoutDialog');
const { OAuthHelpers } = require('../OAuthHelpers');
const MAIN_WATERFALL_DIALOG = 'mainWaterfallDialog';
const OAUTH_PROMPT = 'oAuthPrompt';
const CHOICE_PROMPT = 'choicePrompt';
const TEXT_PROMPT = 'textPrompt';
class MainDialog extends LogoutDialog {
constructor() {
super('MainDialog');
this.addDialog(new ChoicePrompt(CHOICE_PROMPT))
.addDialog(
new OAuthPrompt(OAUTH_PROMPT, {
connectionName: process.env.ConnectionName,
text: 'Please login',
title: 'Login',
timeout: 300000
})
)
.addDialog(new TextPrompt(TEXT_PROMPT))
.addDialog(
new WaterfallDialog(MAIN_WATERFALL_DIALOG, [
this.promptStep.bind(this),
this.loginStep.bind(this),
this.commandStep.bind(this),
this.processStep.bind(this)
])
);
this.initialDialogId = MAIN_WATERFALL_DIALOG;
}
/**
* The run method handles the incoming activity (in the form of a TurnContext) and passes it through the dialog system.
* If no dialog is active, it will start the default dialog.
* @param {*} turnContext
* @param {*} accessor
*/
async run(turnContext, accessor) {
const dialogSet = new DialogSet(accessor);
dialogSet.add(this);
const dialogContext = await dialogSet.createContext(turnContext);
const results = await dialogContext.continueDialog();
if (results.status === DialogTurnStatus.empty) {
await dialogContext.beginDialog(this.id);
}
}
async promptStep(step) {
return step.beginDialog(OAUTH_PROMPT);
}
async loginStep(step) {
// Get the token from the previous step. Note that we could also have gotten the
// token directly from the prompt itself. There is an example of this in the next method.
const tokenResponse = step.result;
if (tokenResponse) {
await OAuthHelpers.listMe(step.context, tokenResponse);
return await step.prompt(TEXT_PROMPT, {
prompt: "What would you like to do? You can type anything or 'logout' to retry."
});
}
await step.context.sendActivity('Login was not successful please try again.');
return await step.endDialog();
}
async commandStep(step) {
step.values.command = step.result;
// Call the prompt again because we need the token. The reasons for this are:
// 1. If the user is already logged in we do not need to store the token locally in the bot and worry
// about refreshing it. We can always just call the prompt again to get the token.
// 2. We never know how long it will take a user to respond. By the time the
// user responds the token may have expired. The user would then be prompted to login again.
//
// There is no reason to store the token locally in the bot because we can always just call
// the OAuth prompt to get the token or get a new token if needed.
return await step.beginDialog(OAUTH_PROMPT);
}
async processStep(step) {
if (step.result) {
// We do not need to store the token in the bot. When we need the token we can
// send another prompt. If the token is valid the user will not need to log back in.
// The token will be available in the Result property of the task.
const tokenResponse = step.result;
// If we have the token use the user is authenticated so we may use it to make API calls.
if (tokenResponse && tokenResponse.token) {
await OAuthHelpers.listMe(step.context, tokenResponse);
}
} else {
await step.context.sendActivity("We couldn't log you in. Please try again later.");
}
return await step.endDialog();
}
}
module.exports.MainDialog = MainDialog;