From 675c8511cbdf8a009a86547eb65dd3da9ac4c8e7 Mon Sep 17 00:00:00 2001 From: Rodrigo Rodriguez Date: Tue, 25 Feb 2020 10:13:38 -0300 Subject: [PATCH] fix(core.gbapp): GB Apps can now publish bots and replace root web application. --- package.json | 69 ++++++++++--------- .../services/GBConversationalService.ts | 15 ++++ packages/core.gbapp/services/GBCoreService.ts | 6 ++ packages/core.gbapp/services/GBDeployer.ts | 29 +++++--- .../core.gbapp/services/GBImporterService.ts | 12 ++-- packages/core.gbapp/services/GBMinService.ts | 6 +- src/app.ts | 2 + 7 files changed, 92 insertions(+), 47 deletions(-) diff --git a/package.json b/package.json index 3fc99550..4fbbd435 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ }, "license": "AGPL-3.0", "preferGlobal": true, + "private": false, "bin": { "gbot": "./boot.js" }, @@ -45,9 +46,9 @@ "commit": "git-cz" }, "dependencies": { - "@azure/ms-rest-js": "^2.0.4", - "@microsoft/microsoft-graph-client": "^2.0.0", - "@types/validator": "^12.0.1", + "@azure/ms-rest-js": "2.0.4", + "@microsoft/microsoft-graph-client": "2.0.0", + "@types/validator": "12.0.1", "adal-node": "0.2.1", "async-promises": "0.2.2", "azure-arm-cognitiveservices": "3.0.0", @@ -56,66 +57,66 @@ "azure-arm-sql": "5.7.0", "azure-arm-website": "5.7.0", "azure-search-client": "3.1.5", - "bluebird": "^3.7.2", + "bluebird": "3.7.2", "body-parser": "1.19.0", - "botbuilder": "^4.7.0", - "botbuilder-ai": "^4.7.0", - "botbuilder-dialogs": "^4.7.0", - "botframework-connector": "^4.7.0", - "botlib": "1.3.2", + "botbuilder": "4.7.0", + "botbuilder-ai": "4.7.0", + "botbuilder-dialogs": "4.7.0", + "botframework-connector": "4.7.0", + "botlib": "1.4.0", "chai": "4.2.0", "cli-spinner": "0.2.10", - "csv-parse": "^4.8.3", - "dotenv-extended": "^2.7.1", - "exceljs": "^3.5.0", + "csv-parse": "4.8.3", + "dotenv-extended": "2.7.1", + "exceljs": "3.5.0", "express": "4.17.1", "express-remove-route": "1.0.0", "js-beautify": "1.10.2", - "marked": "^0.8.0", + "marked": "0.8.0", "mocha": "6.2.2", - "ms-rest-azure": "^3.0.0", - "nexmo": "^2.5.2", - "ngrok": "^3.2.7", - "npm": "^6.13.4", + "ms-rest-azure": "3.0.0", + "nexmo": "2.5.2", + "ngrok": "3.2.7", + "npm": "6.13.4", "opn": "6.0.0", "pragmatismo-io-framework": "1.0.20", - "public-ip": "^4.0.0", + "public-ip": "4.0.0", "reflect-metadata": "0.1.13", "request-promise": "4.2.5", "request-promise-native": "1.0.8", - "rimraf": "^3.0.0", - "scanf": "^1.1.1", - "sequelize-typescript": "^1.1.0", + "rimraf": "3.0.0", + "scanf": "1.1.1", + "sequelize-typescript": "1.1.0", "shx": "0.3.2", - "simple-git": "^1.129.0", + "simple-git": "1.129.0", "sppull": "2.5.1", "strict-password-generator": "1.1.2", - "swagger-client": "^3.9.6", - "tedious": "^6.6.5", - "typedoc": "^0.15.6", - "typescript": "^3.7.4", + "swagger-client": "3.9.6", + "tedious": "6.6.5", + "typedoc": "0.15.6", + "typescript": "3.7.4", "url-join": "4.0.1", "vbscript-to-typescript": "1.0.8", "wait-until": "0.0.2", "walk-promise": "0.2.0", - "washyourmouthoutwithsoap": "^1.0.2" + "washyourmouthoutwithsoap": "1.0.2" }, "devDependencies": { - "@types/chai": "^4.2.7", + "@types/chai": "4.2.7", "@types/mocha": "5.2.7", "@types/url-join": "4.0.0", "@types/winston": "2.4.4", "ban-sensitive-files": "1.9.2", - "commitizen": "^4.0.3", - "cz-conventional-changelog": "^3.0.2", - "dependency-check": "^4.1.0", + "commitizen": "4.0.3", + "cz-conventional-changelog": "3.0.2", + "dependency-check": "4.1.0", "git-issues": "1.3.1", "license-checker": "25.0.1", "nsp": "3.2.1", - "prettier-standard": "^16.1.0", - "semantic-release": "^15.14.0", + "prettier-standard": "16.1.0", + "semantic-release": "15.14.0", "travis-deploy-once": "5.0.11", - "ts-node": "^8.5.4", + "ts-node": "8.5.4", "tslint": "5.20.1" }, "eslintConfig": { diff --git a/packages/core.gbapp/services/GBConversationalService.ts b/packages/core.gbapp/services/GBConversationalService.ts index ef527862..24b579b2 100644 --- a/packages/core.gbapp/services/GBConversationalService.ts +++ b/packages/core.gbapp/services/GBConversationalService.ts @@ -41,6 +41,7 @@ import { LuisRecognizer } from 'botbuilder-ai'; import { GBDialogStep, GBLog, GBMinInstance, IGBConversationalService, IGBCoreService } from 'botlib'; import { AzureText } from 'pragmatismo-io-framework'; import { Messages } from '../strings'; +const PasswordGenerator = require("strict-password-generator").default; const Nexmo = require('nexmo'); export interface LanguagePickerSettings { @@ -59,6 +60,20 @@ export class GBConversationalService implements IGBConversationalService { this.coreService = coreService; } + public static getNewMobileCode() { + const passwordGenerator = new PasswordGenerator(); + const options = { + upperCaseAlpha: false, + lowerCaseAlpha: false, + number: true, + specialCharacter: false, + minimumLength: 4, + maximumLength: 4 + }; + let code = passwordGenerator.generatePassword(options); + return code; + } + public getCurrentLanguage(step: GBDialogStep) { return step.context.activity.locale; } diff --git a/packages/core.gbapp/services/GBCoreService.ts b/packages/core.gbapp/services/GBCoreService.ts index d67cb8aa..3b5a9677 100644 --- a/packages/core.gbapp/services/GBCoreService.ts +++ b/packages/core.gbapp/services/GBCoreService.ts @@ -288,6 +288,12 @@ STORAGE_SYNC=true } } + public setWWWRoot(localPath: string) + { + GBServer.globals.wwwroot = localPath; + } + + public async deleteInstance(botId: string) { const options = { where: {} }; options.where = { botId: botId }; diff --git a/packages/core.gbapp/services/GBDeployer.ts b/packages/core.gbapp/services/GBDeployer.ts index 880e190d..ab4eec26 100644 --- a/packages/core.gbapp/services/GBDeployer.ts +++ b/packages/core.gbapp/services/GBDeployer.ts @@ -48,7 +48,7 @@ const rimraf = require('rimraf'); import { GBError, GBLog, GBMinInstance, IGBCoreService, IGBInstance, IGBPackage } from 'botlib'; import { AzureSearch } from 'pragmatismo-io-framework'; import { GBServer } from '../../../src/app'; -import { GuaribasPackage } from '../models/GBModel'; +import { GuaribasPackage, GuaribasInstance } from '../models/GBModel'; import { GBAdminService } from './../../admin.gbapp/services/GBAdminService'; import { AzureDeployerService } from './../../azuredeployer.gbapp/services/AzureDeployerService'; import { KBService } from './../../kb.gbapp/services/KBService'; @@ -163,16 +163,20 @@ export class GBDeployer { ); } + + public async deployBlankBot(botId: string){ + let instance = await this.importer.createBotInstance(botId); + return this.deployBotFull(instance, GBServer.globals.publicAddress); + + } + /** * Deploys a bot to the storage. */ - public async deployBot(localPath: string, publicAddress: string): Promise { - const packageName = Path.basename(localPath); + public async deployBotFull(instance: IGBInstance, publicAddress: string): Promise { const service = new AzureDeployerService(this); - let instance = await this.importer.importIfNotExistsBotPackage(undefined, packageName, localPath); - const username = GBConfigService.get('CLOUD_USERNAME'); const password = GBConfigService.get('CLOUD_PASSWORD'); const group = GBConfigService.get('CLOUD_GROUP'); @@ -227,9 +231,18 @@ export class GBDeployer { await GBServer.globals.minService.mountBot(instance); } await this.core.saveInstance(instance); - + } + /** + * Deploys a bot to the storage from a .gbot folder. + */ + + public async deployBotFromLocalPath(localPath: string, publicAddress: string): Promise { + const packageName = Path.basename(localPath); + let instance = await this.importer.importIfNotExistsBotPackage(undefined, packageName, localPath); + this.deployBotFull(instance, publicAddress); + } /** * UndDeploys a bot to the storage. @@ -276,7 +289,7 @@ export class GBDeployer { switch (packageType) { case '.gbot': - await this.deployBot(localPath, GBServer.globals.publicAddress); + await this.deployBotFromLocalPath(localPath, GBServer.globals.publicAddress); break; case '.gbkb': @@ -406,7 +419,7 @@ export class GBDeployer { await CollectionUtil.asyncForEach(botPackages, async e => { if (e !== 'packages\\boot.gbot') { GBLog.info(`Deploying bot: ${e}...`); - await _this.deployBot(e, GBServer.globals.publicAddress); + await _this.deployBotFromLocalPath(e, GBServer.globals.publicAddress); GBLog.info(`Bot: ${e} deployed...`); } }); diff --git a/packages/core.gbapp/services/GBImporterService.ts b/packages/core.gbapp/services/GBImporterService.ts index 7345a234..04d68ac8 100644 --- a/packages/core.gbapp/services/GBImporterService.ts +++ b/packages/core.gbapp/services/GBImporterService.ts @@ -64,11 +64,18 @@ export class GBImporter { const instance = await this.core.loadInstance(botId); if (instance.botId === undefined || instance.botId === null) { - console.log("••• Atenção botId é nulo ou undefined"); + console.log(`Null BotId after load instance with botId: ${botId}.`); } return await this.createOrUpdateInstanceInternal(instance, botId, localPath, settingsJson); } + public async createBotInstance(botId: string) { + let fullSettingsJson = { ...GBServer.globals.bootInstance }; + fullSettingsJson.botId = botId; + return await GuaribasInstance.create(fullSettingsJson); + } + + private async createOrUpdateInstanceInternal(instance: IGBInstance, botId: string, localPath: string, settingsJson: any) { let packageJson = JSON.parse(fs.readFileSync(urlJoin(localPath, 'package.json'), 'utf8')); @@ -83,9 +90,6 @@ export class GBImporter { if (instance !== null) { instance = { ...instance, ...fullSettingsJson }; - if (instance.botId === undefined || instance.botId === null) { - console.log("••• Atenção botId é nulo ou undefined"); - } return await this.core.saveInstance(instance); } else { return await GuaribasInstance.create(fullSettingsJson); diff --git a/packages/core.gbapp/services/GBMinService.ts b/packages/core.gbapp/services/GBMinService.ts index d455e254..ad7c0c0e 100644 --- a/packages/core.gbapp/services/GBMinService.ts +++ b/packages/core.gbapp/services/GBMinService.ts @@ -110,7 +110,10 @@ export class GBMinService { ) { // Serves default UI on root address '/' if web enabled. if (process.env.DISABLE_WEB !== 'true') { - GBServer.globals.server.use('/', express.static(urlJoin(GBDeployer.deployFolder, GBMinService.uiPackage, 'build'))); + let url = urlJoin(GBDeployer.deployFolder, GBMinService.uiPackage, 'build'); + + GBServer.globals.server.use('/', express.static(GBServer.globals.wwwroot ? + GBServer.globals.wwwroot : url)); } // Serves the bot information object via HTTP so clients can get // instance information stored on server. @@ -382,6 +385,7 @@ export class GBMinService { min.core = this.core; min.conversationalService = this.conversationalService; min.adminService = this.adminService; + min.deployer = this.deployer; min.instance = await this.core.loadInstance(min.botId); min.cbMap = {}; min.scriptMap = {}; diff --git a/src/app.ts b/src/app.ts index 843c986c..d8950c9f 100644 --- a/src/app.ts +++ b/src/app.ts @@ -64,6 +64,7 @@ export class RootData { public bootInstance: IGBInstance; // General Bot Interface Instance public minInstances: any[]; // public minBoot: GBMinInstance; + public wwwroot: string; // .gbui or a static webapp. } /** @@ -87,6 +88,7 @@ export class GBServer { GBServer.globals.appPackages = []; GBServer.globals.sysPackages = []; GBServer.globals.minInstances = []; + GBServer.globals.wwwroot = null; server.use(bodyParser.json()); server.use(bodyParser.urlencoded({ extended: true }));