diff --git a/DATABASE-CHANGES.md b/DATABASE-CHANGES.md index da775b99..80f97f6e 100644 --- a/DATABASE-CHANGES.md +++ b/DATABASE-CHANGES.md @@ -49,11 +49,17 @@ ALTER TABLE dbo.GuaribasInstance ADD activationCode nvarchar(16) NULL GO -# 1.7.9 +# ALTER TABLE dbo.GuaribasInstance ADD params nvarchar(4000) NULL GO +# + +ALTER TABLE dbo.GuaribasInstance ADD + state nvarchar(16) NULL +GO +UPDATE dbo.GuaribasInstance SET state= 'active' ``` \ No newline at end of file diff --git a/package.json b/package.json index ada09388..c80310dd 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "botbuilder-ai": "4.7.0", "botbuilder-dialogs": "4.7.0", "botframework-connector": "4.7.0", - "botlib": "1.5.4", + "botlib": "1.5.5", "cli-spinner": "0.2.10", "dotenv-extended": "2.7.1", "exceljs": "3.5.0", diff --git a/packages/admin.gbapp/dialogs/AdminDialog.ts b/packages/admin.gbapp/dialogs/AdminDialog.ts index c9b8fbea..6aa1744d 100644 --- a/packages/admin.gbapp/dialogs/AdminDialog.ts +++ b/packages/admin.gbapp/dialogs/AdminDialog.ts @@ -76,6 +76,29 @@ export class AdminDialog extends IGBDialog { AdminDialog.setupSecurityDialogs(min); + min.dialogs.add( + new WaterfallDialog('/admin-auth', [ + async step => { + const locale = step.context.activity.locale; + const prompt = Messages[locale].authenticate; + + return await min.conversationalService.prompt(min, step, prompt); + }, + async step => { + const locale = step.context.activity.locale; + const sensitive = step.result; + + if (sensitive === process.env.ADMIN_PASS ) { // TODO: Per bot: min.instance.adminPass + await min.conversationalService.sendText(min, step, Messages[locale].welcome); + + return await step.endDialog(true); + + } else { + await min.conversationalService.sendText(min, step, Messages[locale].wrong_password); + return await step.replaceDialog('/admin-auth'); + } + }])); + min.dialogs.add( new WaterfallDialog('/admin', [ async step => { @@ -181,57 +204,69 @@ export class AdminDialog extends IGBDialog { let canPublish = AdminDialog.canPublish(min, from); - if (canPublish) { - - const botId = min.instance.botId; - const locale = step.context.activity.locale; - await min.conversationalService.sendText(min, step, Messages[locale].working('Publishing')); - - step.activeDialog.state.options.args = (step.options as any).args; - const filename = step.activeDialog.state.options.args ? - step.activeDialog.state.options.args.split(' ')[0] : null; - - const packages = []; - if (filename === null || filename === "") { - await min.conversationalService.sendText(min, step, `Starting publishing for ${botId}.gbkb...`); - packages.push(`${botId}.gbkb`); - } else { - await min.conversationalService.sendText(min, step, `Starting publishing for ${filename}...`); - packages.push(filename); - } - - try { - - await CollectionUtil.asyncForEach(packages, async packageName => { - - const cmd1 = `deployPackage ${process.env.STORAGE_SITE} /${process.env.STORAGE_LIBRARY}/${botId}.gbai/${packageName}`; - - if (await (deployer as any).getStoragePackageByName(min.instance.instanceId, - packageName) !== null) { - const cmd2 = `undeployPackage ${packageName}`; - await GBAdminService.undeployPackageCommand(cmd2, min); - } - await GBAdminService.deployPackageCommand(min, cmd1, deployer); - await min.conversationalService.sendText(min, step, `Finished publishing ${packageName}.`); - }); - } catch (error) { - await min.conversationalService.sendText(min, step, `ERROR: ${error}`); - GBLog.error(error); - return await step.replaceDialog('/ask', { isReturning: true }); - } - await min.conversationalService.sendText(min, step, Messages[locale].publish_success); - if (!step.activeDialog.state.options.confirm) { - return await step.replaceDialog('/ask', { isReturning: true }); - } - else { - return await step.endDialog(); - } - - } else { - await min.conversationalService.sendText(min, step, Messages[locale].publish_must_be_admin); + if (!canPublish) { + await step.beginDialog('/admin-auth'); + } + else { + step.next(true); } } - await min.conversationalService.sendText(min, step, Messages[locale].publish_canceled); + else { + await min.conversationalService.sendText(min, step, Messages[locale].publish_canceled); + } + }, + async step => { + const locale = step.context.activity.locale; + if (!step.result) { + await min.conversationalService.sendText(min, step, Messages[locale].publish_must_be_admin); + + return step.endDialog(); + } + + const botId = min.instance.botId; + + await min.conversationalService.sendText(min, step, Messages[locale].working('Publishing')); + + step.activeDialog.state.options.args = (step.options as any).args; + const filename = step.activeDialog.state.options.args ? + step.activeDialog.state.options.args.split(' ')[0] : null; + + const packages = []; + if (filename === null || filename === "") { + await min.conversationalService.sendText(min, step, `Starting publishing for ${botId}.gbkb...`); + packages.push(`${botId}.gbkb`); + } else { + await min.conversationalService.sendText(min, step, `Starting publishing for ${filename}...`); + packages.push(filename); + } + + try { + + await CollectionUtil.asyncForEach(packages, async packageName => { + + const cmd1 = `deployPackage ${process.env.STORAGE_SITE} /${process.env.STORAGE_LIBRARY}/${botId}.gbai/${packageName}`; + + if (await (deployer as any).getStoragePackageByName(min.instance.instanceId, + packageName) !== null) { + const cmd2 = `undeployPackage ${packageName}`; + await GBAdminService.undeployPackageCommand(cmd2, min); + } + await GBAdminService.deployPackageCommand(min, cmd1, deployer); + await min.conversationalService.sendText(min, step, `Finished publishing ${packageName}.`); + }); + } catch (error) { + await min.conversationalService.sendText(min, step, `ERROR: ${error}`); + GBLog.error(error); + return await step.replaceDialog('/ask', { isReturning: true }); + } + await min.conversationalService.sendText(min, step, Messages[locale].publish_success); + if (!step.activeDialog.state.options.confirm) { + return await step.replaceDialog('/ask', { isReturning: true }); + } + else { + return await step.endDialog(); + } + }])); } diff --git a/packages/core.gbapp/models/GBModel.ts b/packages/core.gbapp/models/GBModel.ts index 58fdc8fe..21bd165a 100644 --- a/packages/core.gbapp/models/GBModel.ts +++ b/packages/core.gbapp/models/GBModel.ts @@ -81,6 +81,9 @@ export class GuaribasInstance extends Model @Column public description: string; + @Column({ type: DataType.STRING(16) }) + public state: string; + @Column public version: string; diff --git a/packages/core.gbapp/services/GBConversationalService.ts b/packages/core.gbapp/services/GBConversationalService.ts index c06bf472..78d95ef7 100644 --- a/packages/core.gbapp/services/GBConversationalService.ts +++ b/packages/core.gbapp/services/GBConversationalService.ts @@ -525,10 +525,15 @@ export class GBConversationalService { language: string ): Promise { - if (process.env.TRANSLATOR_DISABLED === "true"){ + if (process.env.TRANSLATOR_DISABLED === "true"){ return text; } + if (text.length > 5000){ + text = text.substr(0,4999); + GBLog.warn(`Text that bot will translate will be truncated due to MSFT service limitations.`); + } + let options = { method: 'POST', baseUrl: endPoint, diff --git a/packages/core.gbapp/services/GBCoreService.ts b/packages/core.gbapp/services/GBCoreService.ts index 56efaf7c..a31ef5b8 100644 --- a/packages/core.gbapp/services/GBCoreService.ts +++ b/packages/core.gbapp/services/GBCoreService.ts @@ -215,7 +215,8 @@ export class GBCoreService implements IGBCoreService { return GuaribasInstance.findAll(options); } else { - return GuaribasInstance.findAll({}); + const options = { where: { state: 'active' } }; + return GuaribasInstance.findAll(options); } } @@ -223,17 +224,25 @@ export class GBCoreService implements IGBCoreService { * Loads just one Bot instance by its internal Id. */ public async loadInstanceById(instanceId: number): Promise { - const options = { where: { instanceId: instanceId } }; + const options = { where: { instanceId: instanceId, state: 'active' } }; return GuaribasInstance.findOne(options); } + /** + * Loads just one Bot instance. + */ + public async loadInstanceByActivationCode(code: string): Promise { + let options = { where: { activationCode: code, state: 'active' } }; + + return await GuaribasInstance.findOne(options); + } /** * Loads just one Bot instance. */ public async loadInstanceByBotId(botId: string): Promise { const options = { where: {} }; - options.where = { botId: botId }; + options.where = { botId: botId, state: 'active' }; return await GuaribasInstance.findOne(options); } diff --git a/packages/core.gbapp/services/GBMinService.ts b/packages/core.gbapp/services/GBMinService.ts index d999bb84..859f6595 100644 --- a/packages/core.gbapp/services/GBMinService.ts +++ b/packages/core.gbapp/services/GBMinService.ts @@ -343,7 +343,12 @@ export class GBMinService { if (botId === '[default]' || botId === undefined) { botId = GBConfigService.get('BOT_ID'); } - const instance = await this.core.loadInstanceByBotId(botId); + let instance = await this.core.loadInstanceByBotId(botId); + + if (instance === null){ + instance = await this.core.loadInstanceByActivationCode(botId); + } + if (instance !== null) { const webchatTokenContainer = await this.getWebchatToken(instance); const speechToken = instance.speechKey != null ? await this.getSTSToken(instance) : null;