fix(core.gbapp): Context in VM is isolated now.
This commit is contained in:
parent
4cb9d5b906
commit
42a7074081
4 changed files with 45 additions and 47 deletions
|
@ -72,7 +72,6 @@ export class AdminDialog extends IGBDialog {
|
|||
|
||||
const importer = new GBImporter(min.core);
|
||||
const deployer = new GBDeployer(min.core, importer);
|
||||
const adminService = new GBAdminService(min.core);
|
||||
|
||||
AdminDialog.setupSecurityDialogs(min);
|
||||
|
||||
|
|
|
@ -70,6 +70,8 @@ import { WhatsappDirectLine } from '../../whatsapp.gblib/services/WhatsappDirect
|
|||
import fs = require('fs');
|
||||
import { GuaribasConversationMessage } from '../../analytics.gblib/models';
|
||||
import { GBCoreService } from './GBCoreService';
|
||||
import { DialogClass } from './GBAPIService';
|
||||
import { GBVMService } from './GBVMService';
|
||||
|
||||
/**
|
||||
* Minimal service layer for a bot.
|
||||
|
@ -712,7 +714,7 @@ export class GBMinService {
|
|||
if (hasBadWord) {
|
||||
await step.beginDialog('/pleaseNoBadWords');
|
||||
} else if (isVMCall) {
|
||||
await GBMinService.callVM(context.activity.text, min, step);
|
||||
await GBVMService.callVM(context.activity.text, min, step, this.deployer);
|
||||
} else if (context.activity.text.charAt(0) === '/') {
|
||||
let text = context.activity.text;
|
||||
let parts = text.split(' ');
|
||||
|
@ -803,9 +805,4 @@ export class GBMinService {
|
|||
}
|
||||
}
|
||||
|
||||
public static async callVM(text: string, min: GBMinInstance, step: GBDialogStep) {
|
||||
const mainMethod = text.toLowerCase();
|
||||
min.sandBoxMap[mainMethod][mainMethod].bind(min.sandBoxMap[mainMethod]);
|
||||
return await min.sandBoxMap[mainMethod][mainMethod](step);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,18 +33,18 @@
|
|||
'use strict';
|
||||
|
||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||
import { GBLog, GBMinInstance, GBService, IGBCoreService } from 'botlib';
|
||||
import { GBLog, GBMinInstance, GBService, IGBCoreService, GBDialogStep } from 'botlib';
|
||||
import * as fs from 'fs';
|
||||
import { GBDeployer } from './GBDeployer';
|
||||
import { TSCompiler } from './TSCompiler';
|
||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
||||
const walkPromise = require('walk-promise');
|
||||
const vm = require('vm');
|
||||
import urlJoin = require('url-join');
|
||||
import { DialogClass } from './GBAPIService';
|
||||
import { Messages } from '../strings';
|
||||
import { GBConversationalService } from './GBConversationalService';
|
||||
//tslint:disable-next-line:no-submodule-imports
|
||||
const vm = require('vm');
|
||||
const vb2ts = require('vbscript-to-typescript/dist/converter');
|
||||
const beautify = require('js-beautify').js;
|
||||
var textract = require('textract');
|
||||
|
@ -62,15 +62,12 @@ var textract = require('textract');
|
|||
* Basic services for BASIC manipulation.
|
||||
*/
|
||||
export class GBVMService extends GBService {
|
||||
private readonly script = new vm.Script();
|
||||
|
||||
public async loadDialogPackage(folder: string, min: GBMinInstance, core: IGBCoreService, deployer: GBDeployer) {
|
||||
const files = await walkPromise(folder);
|
||||
this.addHearDialog(min);
|
||||
|
||||
await CollectionUtil.asyncForEach(files, async file => {
|
||||
if (!file) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -85,12 +82,11 @@ export class GBVMService extends GBService {
|
|||
let writeVBS = true;
|
||||
if (fs.existsSync(fullVbsFile)) {
|
||||
const vbsStat = fs.statSync(fullVbsFile);
|
||||
if (docxStat.mtimeMs < (vbsStat.mtimeMs + interval)) {
|
||||
if (docxStat.mtimeMs < vbsStat.mtimeMs + interval) {
|
||||
writeVBS = false;
|
||||
}
|
||||
}
|
||||
if (writeVBS) {
|
||||
|
||||
let text = await this.getTextFromWord(folder, wordFile);
|
||||
fs.writeFileSync(urlJoin(folder, vbsFile), text);
|
||||
}
|
||||
|
@ -113,35 +109,29 @@ export class GBVMService extends GBService {
|
|||
if (fs.existsSync(jsfile)) {
|
||||
const jsStat = fs.statSync(jsfile);
|
||||
const interval = 30000; // If compiled is older 30 seconds, then recompile.
|
||||
if (compiledAt.isFile() && compiledAt.mtimeMs > (jsStat.mtimeMs + interval)) {
|
||||
if (compiledAt.isFile() && compiledAt.mtimeMs > jsStat.mtimeMs + interval) {
|
||||
await this.executeBASIC(fullFilename, min, deployer, mainName);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
const parsedCode: string = fs.readFileSync(jsfile, 'utf8');
|
||||
this.executeJS(min, deployer, parsedCode, mainName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
await this.executeBASIC(fullFilename, min, deployer, mainName);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async getTextFromWord(folder: string, filename: string) {
|
||||
return new Promise<string>(async (resolve, reject) => {
|
||||
textract.fromFileWithPath(urlJoin(folder, filename), { preserveLineBreaks: true },
|
||||
(error, text) => {
|
||||
textract.fromFileWithPath(urlJoin(folder, filename), { preserveLineBreaks: true }, (error, text) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
else {
|
||||
text = text.replace('“', '\"');
|
||||
text = text.replace('”', '\"');
|
||||
text = text.replace('‘', '\'');
|
||||
text = text.replace('’', '\'');
|
||||
|
||||
} else {
|
||||
text = text.replace('“', '"');
|
||||
text = text.replace('”', '"');
|
||||
text = text.replace('‘', "'");
|
||||
text = text.replace('’', "'");
|
||||
|
||||
resolve(text);
|
||||
}
|
||||
|
@ -262,8 +252,8 @@ export class GBVMService extends GBService {
|
|||
|
||||
parsedCode = code.substring(pos, pos + match1.index);
|
||||
parsedCode += ``;
|
||||
parsedCode += `const ${promiseName}= async (step, ${variable}) => {`
|
||||
parsedCode += ` return new Promise(async (resolve) => {`
|
||||
parsedCode += `const ${promiseName}= async (step, ${variable}) => {`;
|
||||
parsedCode += ` return new Promise(async (resolve) => {`;
|
||||
|
||||
// Skips old construction and point to the async block.
|
||||
|
||||
|
@ -306,7 +296,7 @@ export class GBVMService extends GBService {
|
|||
|
||||
parsedCode = this.handleThisAndAwait(parsedCode);
|
||||
|
||||
parsedCode = beautify(parsedCode, { indent_size: 2, space_in_empty_paren: true })
|
||||
parsedCode = beautify(parsedCode, { indent_size: 2, space_in_empty_paren: true });
|
||||
fs.writeFileSync(jsfile, parsedCode);
|
||||
|
||||
this.executeJS(min, deployer, parsedCode, mainName);
|
||||
|
@ -316,12 +306,8 @@ export class GBVMService extends GBService {
|
|||
|
||||
private executeJS(min: GBMinInstance, deployer: GBDeployer, parsedCode: string, mainName: string) {
|
||||
try {
|
||||
const sandbox: DialogClass = new DialogClass(min, deployer);
|
||||
const context = vm.createContext(sandbox);
|
||||
vm.runInContext(parsedCode, context);
|
||||
min.sandBoxMap[mainName.toLowerCase()] = sandbox;
|
||||
}
|
||||
catch (error) {
|
||||
min.sandBoxMap[mainName.toLowerCase()] = parsedCode;
|
||||
} catch (error) {
|
||||
GBLog.error(`[GBVMService] ERROR loading ${error}`);
|
||||
}
|
||||
}
|
||||
|
@ -346,7 +332,6 @@ export class GBVMService extends GBService {
|
|||
return $1 === undefined ? 'this.sendFile' : $1;
|
||||
});
|
||||
|
||||
|
||||
// await insertion.
|
||||
|
||||
code = code.replace(/this\./gm, 'await this.');
|
||||
|
@ -385,4 +370,15 @@ export class GBVMService extends GBService {
|
|||
])
|
||||
);
|
||||
}
|
||||
|
||||
public static async callVM(text: string, min: GBMinInstance, step: GBDialogStep, deployer: GBDeployer) {
|
||||
const sandbox: DialogClass = new DialogClass(min, deployer);
|
||||
const context = vm.createContext(sandbox);
|
||||
const code = min.sandBoxMap[text];
|
||||
vm.runInContext(code, context);
|
||||
|
||||
const mainMethod = text.toLowerCase();
|
||||
sandbox[mainMethod].bind(sandbox);
|
||||
return await sandbox[mainMethod](step);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,9 +43,11 @@ import { GBLog, GBMinInstance, IGBDialog, IGBPackage } from 'botlib';
|
|||
import { Messages } from '../strings';
|
||||
import { KBService } from './../services/KBService';
|
||||
import { GuaribasAnswer } from '../models';
|
||||
import { GBMinService } from '../../../packages/core.gbapp/services/GBMinService';
|
||||
import { SecService } from '../../security.gbapp/services/SecService';
|
||||
import { CollectionUtil, AzureText } from 'pragmatismo-io-framework';
|
||||
import { GBVMService } from '../../core.gbapp/services/GBVMService';
|
||||
import { GBImporter } from '../../core.gbapp/services/GBImporterService';
|
||||
import { GBDeployer } from '../../core.gbapp/services/GBDeployer';
|
||||
|
||||
/**
|
||||
* Dialog arguments.
|
||||
|
@ -59,6 +61,7 @@ export class AskDialogArgs {
|
|||
* Handle the ask loop on knowledge base data or delegate to other services.
|
||||
*/
|
||||
export class AskDialog extends IGBDialog {
|
||||
static deployer: any;
|
||||
/**
|
||||
* Setup dialogs flows and define services call.
|
||||
*
|
||||
|
@ -67,6 +70,9 @@ export class AskDialog extends IGBDialog {
|
|||
*/
|
||||
public static setup(bot: BotAdapter, min: GBMinInstance) {
|
||||
const service = new KBService(min.core.sequelize);
|
||||
const importer = new GBImporter(min.core);
|
||||
this.deployer = new GBDeployer(min.core, importer);
|
||||
|
||||
min.dialogs.add(new WaterfallDialog('/answerEvent', AskDialog.getAnswerEventDialog(service, min)));
|
||||
min.dialogs.add(new WaterfallDialog('/answer', AskDialog.getAnswerDialog(min, service)));
|
||||
min.dialogs.add(new WaterfallDialog('/ask', AskDialog.getAskDialog(min)));
|
||||
|
@ -259,7 +265,7 @@ export class AskDialog extends IGBDialog {
|
|||
private static async handleAnswer(service: KBService, min: GBMinInstance, step: any, answer: GuaribasAnswer) {
|
||||
if (answer.content.endsWith('.docx')) {
|
||||
const mainName = answer.content.replace(/\s|\-/gi, '').split('.')[0];
|
||||
return await GBMinService.callVM(mainName, min, step);
|
||||
return await GBVMService.callVM(mainName, min, step, this.deployer);
|
||||
} else {
|
||||
await service.sendAnswer(min, AskDialog.getChannel(step), step, answer);
|
||||
return await step.replaceDialog('/ask', { isReturning: true });
|
||||
|
|
Loading…
Add table
Reference in a new issue