Skip to content

Commit

Permalink
fix(core.gbapp): Context in VM is isolated now.
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigorodriguez committed Aug 29, 2020
1 parent 4cb9d5b commit 42a7074
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 47 deletions.
1 change: 0 additions & 1 deletion packages/admin.gbapp/dialogs/AdminDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
9 changes: 3 additions & 6 deletions packages/core.gbapp/services/GBMinService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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(' ');
Expand Down Expand Up @@ -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);
}
}
72 changes: 34 additions & 38 deletions packages/core.gbapp/services/GBVMService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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;
}

Expand All @@ -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);
}
Expand All @@ -113,39 +109,33 @@ 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) => {
if (error) {
reject(error);
}
else {
text = text.replace('“', '\"');
text = text.replace('”', '\"');
text = text.replace('‘', '\'');
text = text.replace('’', '\'');


resolve(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('’', "'");

resolve(text);
}
});
});
}

Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -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);
Expand All @@ -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}`);
}
}
Expand All @@ -346,7 +332,6 @@ export class GBVMService extends GBService {
return $1 === undefined ? 'this.sendFile' : $1;
});


// await insertion.

code = code.replace(/this\./gm, 'await this.');
Expand Down Expand Up @@ -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);
}
}
10 changes: 8 additions & 2 deletions packages/kb.gbapp/dialogs/AskDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
*
Expand All @@ -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)));
Expand Down Expand Up @@ -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 });
Expand Down

0 comments on commit 42a7074

Please sign in to comment.