-
selectTab('appMode')}>
- App Mode
-
-
selectTab('jsRuntime')}>
- JS Runtime
-
+
Scripting Sandbox
+
+
+ Bruno allows JavaScript code to be executed within Variables, Scripts, Tests, and Assertions.
+
+
+
+
+
+
+ JavaScript code is executed in a secure sandbox and cannot excess your filesystem or execute system commands.
+
+
+
+
+ JavaScript code has access to the filesystem, execute system commands and access sensitive information.
+
+
+
-
);
};
diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js
index a91a6fb0d..85eb5e99f 100644
--- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js
+++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js
@@ -33,7 +33,6 @@ export const collectionsSlice = createSlice({
const collection = action.payload;
collection.settingsSelectedTab = 'headers';
- collection.securitySettingsSelectedTab = 'appMode';
collection.showAppModeModal = !collection?.securityConfig?.appMode;
@@ -1629,15 +1628,6 @@ export const collectionsSlice = createSlice({
item.draft.request.docs = action.payload.docs;
}
}
- },
- updateSecuritySettingsSelectedTab: (state, action) => {
- const { collectionUid, tab } = action.payload;
-
- const collection = findCollectionByUid(state.collections, collectionUid);
-
- if (collection) {
- collection.securitySettingsSelectedTab = tab;
- }
}
}
});
@@ -1729,7 +1719,6 @@ export const {
runFolderEvent,
resetCollectionRunner,
updateRequestDocs,
- updateSecuritySettingsSelectedTab,
setShowAppModeModal
} = collectionsSlice.actions;
diff --git a/packages/bruno-cli/src/runner/run-single-request.js b/packages/bruno-cli/src/runner/run-single-request.js
index 63369e149..78daa8d6a 100644
--- a/packages/bruno-cli/src/runner/run-single-request.js
+++ b/packages/bruno-cli/src/runner/run-single-request.js
@@ -57,7 +57,7 @@ const runSingleRequest = async function (
// run pre-request vars
const preRequestVars = get(bruJson, 'request.vars.req');
if (preRequestVars?.length) {
- const varsRuntime = new VarsRuntime({ runtime: scriptingConfig?.runtime, mode: scriptingConfig?.appMode });
+ const varsRuntime = new VarsRuntime({ runtime: scriptingConfig?.runtime });
varsRuntime.runPreRequestVars(
preRequestVars,
request,
@@ -74,7 +74,7 @@ const runSingleRequest = async function (
get(bruJson, 'request.script.req')
]).join(os.EOL);
if (requestScriptFile?.length) {
- const scriptRuntime = new ScriptRuntime({ runtime: scriptingConfig?.runtime, mode: scriptingConfig?.appMode });
+ const scriptRuntime = new ScriptRuntime({ runtime: scriptingConfig?.runtime });
const result = await scriptRuntime.runRequestScript(
decomment(requestScriptFile),
request,
@@ -276,7 +276,7 @@ const runSingleRequest = async function (
// run post-response vars
const postResponseVars = get(bruJson, 'request.vars.res');
if (postResponseVars?.length) {
- const varsRuntime = new VarsRuntime({ runtime: scriptingConfig?.runtime, mode: scriptingConfig?.appMode });
+ const varsRuntime = new VarsRuntime({ runtime: scriptingConfig?.runtime });
varsRuntime.runPostResponseVars(
postResponseVars,
request,
@@ -294,7 +294,7 @@ const runSingleRequest = async function (
get(bruJson, 'request.script.res')
]).join(os.EOL);
if (responseScriptFile?.length) {
- const scriptRuntime = new ScriptRuntime({ runtime: scriptingConfig?.runtime, mode: scriptingConfig?.appMode });
+ const scriptRuntime = new ScriptRuntime({ runtime: scriptingConfig?.runtime });
const result = await scriptRuntime.runResponseScript(
decomment(responseScriptFile),
request,
@@ -315,7 +315,7 @@ const runSingleRequest = async function (
let assertionResults = [];
const assertions = get(bruJson, 'request.assertions');
if (assertions) {
- const assertRuntime = new AssertRuntime({ runtime: scriptingConfig?.runtime, mode: scriptingConfig?.appMode });
+ const assertRuntime = new AssertRuntime({ runtime: scriptingConfig?.runtime });
assertionResults = assertRuntime.runAssertions(
assertions,
request,
@@ -339,7 +339,7 @@ const runSingleRequest = async function (
let testResults = [];
const testFile = compact([get(collectionRoot, 'request.tests'), get(bruJson, 'request.tests')]).join(os.EOL);
if (typeof testFile === 'string') {
- const testRuntime = new TestRuntime({ runtime: scriptingConfig?.runtime, mode: scriptingConfig?.appMode });
+ const testRuntime = new TestRuntime({ runtime: scriptingConfig?.runtime });
const result = await testRuntime.runTests(
decomment(testFile),
request,
diff --git a/packages/bruno-electron/package.json b/packages/bruno-electron/package.json
index 504fde624..466702d6a 100644
--- a/packages/bruno-electron/package.json
+++ b/packages/bruno-electron/package.json
@@ -47,7 +47,6 @@
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"iconv-lite": "^0.6.3",
- "is-number": "^7.0.0",
"is-valid-path": "^0.1.1",
"js-yaml": "^4.1.0",
"json-bigint": "^1.0.0",
@@ -66,7 +65,7 @@
"dmg-license": "^1.0.11"
},
"devDependencies": {
- "electron": "31.2.1",
+ "electron": "21.1.1",
"electron-builder": "23.0.2",
"electron-icon-maker": "^0.0.5"
}
diff --git a/packages/bruno-electron/src/ipc/collection.js b/packages/bruno-electron/src/ipc/collection.js
index 748633045..582812f94 100644
--- a/packages/bruno-electron/src/ipc/collection.js
+++ b/packages/bruno-electron/src/ipc/collection.js
@@ -670,7 +670,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
ipcMain.handle('renderer:save-collection-security-config', async (event, collectionPath, securityConfig) => {
try {
- collectionSecurityStore.storeSecurityConfigForCollection(collectionPath, securityConfig);
+ collectionSecurityStore.setSecurityConfigForCollection(collectionPath, securityConfig);
} catch (error) {
return Promise.reject(error);
}
diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js
index 1b23b838d..972cf52d9 100644
--- a/packages/bruno-electron/src/ipc/network/index.js
+++ b/packages/bruno-electron/src/ipc/network/index.js
@@ -315,7 +315,7 @@ const registerNetworkIpc = (mainWindow) => {
// run pre-request vars
const preRequestVars = get(request, 'vars.req', []);
if (preRequestVars?.length) {
- const varsRuntime = new VarsRuntime({ runtime: scriptingConfig?.runtime, mode: scriptingConfig?.appMode });
+ const varsRuntime = new VarsRuntime({ runtime: scriptingConfig?.runtime });
varsRuntime.runPreRequestVars(
preRequestVars,
request,
@@ -330,7 +330,7 @@ const registerNetworkIpc = (mainWindow) => {
let scriptResult;
const requestScript = compact([get(collectionRoot, 'request.script.req'), get(request, 'script.req')]).join(os.EOL);
if (requestScript?.length) {
- const scriptRuntime = new ScriptRuntime({ runtime: scriptingConfig?.runtime, mode: scriptingConfig?.appMode });
+ const scriptRuntime = new ScriptRuntime({ runtime: scriptingConfig?.runtime });
scriptResult = await scriptRuntime.runRequestScript(
decomment(requestScript),
request,
@@ -382,7 +382,7 @@ const registerNetworkIpc = (mainWindow) => {
// run post-response vars
const postResponseVars = get(request, 'vars.res', []);
if (postResponseVars?.length) {
- const varsRuntime = new VarsRuntime({ runtime: scriptingConfig?.runtime, mode: scriptingConfig?.appMode });
+ const varsRuntime = new VarsRuntime({ runtime: scriptingConfig?.runtime });
const result = varsRuntime.runPostResponseVars(
postResponseVars,
request,
@@ -416,7 +416,7 @@ const registerNetworkIpc = (mainWindow) => {
let scriptResult;
if (responseScript?.length) {
- const scriptRuntime = new ScriptRuntime({ runtime: scriptingConfig?.runtime, mode: scriptingConfig?.appMode });
+ const scriptRuntime = new ScriptRuntime({ runtime: scriptingConfig?.runtime });
scriptResult = await scriptRuntime.runResponseScript(
decomment(responseScript),
request,
@@ -575,7 +575,7 @@ const registerNetworkIpc = (mainWindow) => {
// run assertions
const assertions = get(request, 'assertions');
if (assertions) {
- const assertRuntime = new AssertRuntime({ runtime: scriptingConfig?.runtime, mode: scriptingConfig?.appMode });
+ const assertRuntime = new AssertRuntime({ runtime: scriptingConfig?.runtime });
const results = assertRuntime.runAssertions(
assertions,
request,
@@ -603,7 +603,7 @@ const registerNetworkIpc = (mainWindow) => {
]).join(os.EOL);
if (typeof testFile === 'string') {
- const testRuntime = new TestRuntime({ runtime: scriptingConfig?.runtime, mode: scriptingConfig?.appMode });
+ const testRuntime = new TestRuntime({ runtime: scriptingConfig?.runtime });
const testResults = await testRuntime.runTests(
decomment(testFile),
request,
@@ -1028,10 +1028,7 @@ const registerNetworkIpc = (mainWindow) => {
// run assertions
const assertions = get(item, 'request.assertions');
if (assertions) {
- const assertRuntime = new AssertRuntime({
- runtime: scriptingConfig?.runtime,
- mode: scriptingConfig?.appMode
- });
+ const assertRuntime = new AssertRuntime({ runtime: scriptingConfig?.runtime });
const results = assertRuntime.runAssertions(
assertions,
request,
@@ -1058,10 +1055,7 @@ const registerNetworkIpc = (mainWindow) => {
]).join(os.EOL);
if (typeof testFile === 'string') {
- const testRuntime = new TestRuntime({
- runtime: scriptingConfig?.runtime,
- mode: scriptingConfig?.appMode
- });
+ const testRuntime = new TestRuntime({ runtime: scriptingConfig?.runtime });
const testResults = await testRuntime.runTests(
decomment(testFile),
request,
diff --git a/packages/bruno-electron/src/store/collection-security.js b/packages/bruno-electron/src/store/collection-security.js
index d1ca189c3..07a572ca6 100644
--- a/packages/bruno-electron/src/store/collection-security.js
+++ b/packages/bruno-electron/src/store/collection-security.js
@@ -9,7 +9,7 @@ class CollectionSecurityStore {
});
}
- storeSecurityConfigForCollection(collectionPathname, securityConfig) {
+ setSecurityConfigForCollection(collectionPathname, securityConfig) {
const collections = this.store.get('collections') || [];
const collection = _.find(collections, (c) => c.path === collectionPathname);
diff --git a/packages/bruno-js/.gitignore b/packages/bruno-js/.gitignore
new file mode 100644
index 000000000..c7c43f854
--- /dev/null
+++ b/packages/bruno-js/.gitignore
@@ -0,0 +1 @@
+src/bundle-browser-rollup.js
\ No newline at end of file
diff --git a/packages/bruno-js/package.json b/packages/bruno-js/package.json
index 26d311c8c..345f9da5c 100644
--- a/packages/bruno-js/package.json
+++ b/packages/bruno-js/package.json
@@ -17,7 +17,7 @@
"install:isolated-vm": "cd ./node_modules/isolated-vm && npm install",
"prebuild:isolated-vm:dev": "node ./scripts/prebuild-isolated-vm-for-dev.js",
"prebuild:isolated-vm:prod": "node ./scripts/prebuild-isolated-vm-for-prod-builds.js",
- "build:isolated-vm:inbuilt-modules": "node ./src/sandbox/isolatedvm/utils/bundleLibraries.js"
+ "build:isolated-vm:inbuilt-modules": "node ./src/sandbox/isolatedvm/utils/bundle-libraries.js"
},
"dependencies": {
"@faker-js/faker": "^8.4.1",
diff --git a/packages/bruno-js/src/runtime/assert-runtime.js b/packages/bruno-js/src/runtime/assert-runtime.js
index 95f725d0d..adc67ff61 100644
--- a/packages/bruno-js/src/runtime/assert-runtime.js
+++ b/packages/bruno-js/src/runtime/assert-runtime.js
@@ -162,58 +162,31 @@ const isUnaryOperator = (operator) => {
return unaryOperators.includes(operator);
};
-const toNumber = (value) => {
- const num = Number(value);
- return Number.isInteger(num) ? parseInt(value, 10) : parseFloat(value);
-};
-
-const evaluateJsTemplateLiteralBasedOnRuntime = (v, context, runtime, mode) => {
- let value;
- if (mode === 'restricted') {
- let _value = _.get(context, v, v);
- if (_value && typeof _value == 'object') {
- value = JSON.stringify(_value);
- } else if (Number.isNaN(Number(_value))) {
- value = _value;
- } else {
- value = toNumber(_value);
- }
- } else if (mode === 'safe') {
- value = isolatedVMStrictInstance.execute({
- script: v,
+const evaluateJsTemplateLiteralBasedOnRuntime = (literal, context, runtime) => {
+ if(runtime === 'isolated-vm') {
+ return isolatedVMStrictInstance.execute({
+ script: literal,
context,
scriptType: 'template-literal'
});
- } else {
- value = evaluateJsTemplateLiteral(v, context);
}
- return value;
+
+ return evaluateJsTemplateLiteral(literal, context);
};
-const evaluateJsExpressionBasedOnRuntime = (v, context, runtime, mode) => {
- let value;
- if (mode === 'restricted') {
- let _value = _.get(context, v, v);
- if (_value && typeof _value == 'object') {
- value = JSON.stringify(_value);
- } else if (Number.isNaN(Number(_value))) {
- value = _value;
- } else {
- value = toNumber(_value);
- }
- } else if (mode === 'safe') {
- value = isolatedVMStrictInstance.execute({
- script: v,
+const evaluateJsExpressionBasedOnRuntime = (expr, context, runtime) => {
+ if(runtime === 'isolated-vm') {
+ return isolatedVMStrictInstance.execute({
+ script: expr,
context,
scriptType: 'expression'
});
- } else {
- value = evaluateJsExpression(v, context);
}
- return value;
-};
-const evaluateRhsOperand = (rhsOperand, operator, context, runtime, mode) => {
+ return evaluateJsExpression(expr, context);
+}
+
+const evaluateRhsOperand = (rhsOperand, operator, context, runtime) => {
if (isUnaryOperator(operator)) {
return;
}
@@ -237,8 +210,7 @@ const evaluateRhsOperand = (rhsOperand, operator, context, runtime, mode) => {
evaluateJsTemplateLiteralBasedOnRuntime(
interpolateString(v.trim(), interpolationContext),
context,
- runtime,
- mode
+ runtime
)
);
}
@@ -250,8 +222,7 @@ const evaluateRhsOperand = (rhsOperand, operator, context, runtime, mode) => {
evaluateJsTemplateLiteralBasedOnRuntime(
interpolateString(v.trim(), interpolationContext),
context,
- runtime,
- mode
+ runtime
)
);
return [lhs, rhs];
@@ -269,15 +240,13 @@ const evaluateRhsOperand = (rhsOperand, operator, context, runtime, mode) => {
return evaluateJsTemplateLiteralBasedOnRuntime(
interpolateString(rhsOperand, interpolationContext),
context,
- runtime,
- mode
+ runtime
);
};
class AssertRuntime {
constructor(props) {
this.runtime = props?.runtime || 'vm2';
- this.mode = props?.mode || 'developer';
}
runAssertions(assertions, request, response, envVariables, runtimeVariables, processEnvVars) {
@@ -314,8 +283,8 @@ class AssertRuntime {
const { operator, value: rhsOperand } = parseAssertionOperator(rhsExpr);
try {
- const lhs = evaluateJsExpressionBasedOnRuntime(lhsExpr, context, this.runtime, this.mode);
- const rhs = evaluateRhsOperand(rhsOperand, operator, context, this.runtime, this.mode);
+ const lhs = evaluateJsExpressionBasedOnRuntime(lhsExpr, context, this.runtime);
+ const rhs = evaluateRhsOperand(rhsOperand, operator, context, this.runtime);
switch (operator) {
case 'eq':
diff --git a/packages/bruno-js/src/runtime/script-runtime.js b/packages/bruno-js/src/runtime/script-runtime.js
index bc121f59b..68c64784f 100644
--- a/packages/bruno-js/src/runtime/script-runtime.js
+++ b/packages/bruno-js/src/runtime/script-runtime.js
@@ -28,12 +28,11 @@ const fetch = require('node-fetch');
const chai = require('chai');
const CryptoJS = require('crypto-js');
const NodeVault = require('node-vault');
-const { isolatedVMAsyncInstance, executeInIsolatedVMAsync } = require('../sandbox/isolatedvm');
+const { executeInIsolatedVMAsync } = require('../sandbox/isolatedvm');
class ScriptRuntime {
constructor(props) {
this.runtime = props?.runtime || 'vm2';
- this.mode = props?.mode || 'developer';
}
// This approach is getting out of hand
@@ -48,14 +47,6 @@ class ScriptRuntime {
processEnvVars,
scriptingConfig
) {
- if (this.mode === 'restricted') {
- return {
- request,
- envVariables: cleanJson(envVariables),
- collectionVariables: cleanJson(collectionVariables),
- nextRequestName: undefined
- };
- }
const requestVariables = request?.requestVariables || {};
const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, requestVariables);
const req = new BrunoRequest(request);
@@ -98,7 +89,7 @@ class ScriptRuntime {
};
}
- if (this.mode == 'safe') {
+ if (this.runtime === 'isolated-vm') {
// Reuses the same instance of IsolatedVMAsync
// TODO: Test for performance
// await isolatedVMAsyncInstance.execute({
@@ -113,53 +104,54 @@ class ScriptRuntime {
modules: {},
scriptType: 'jsScript'
});
- } else {
- const vm = new NodeVM({
- sandbox: context,
- require: {
- context: 'sandbox',
- external: true,
- root: [collectionPath, ...additionalContextRootsAbsolute],
- mock: {
- // node libs
- path,
- stream,
- util,
- url,
- http,
- https,
- punycode,
- zlib,
- // 3rd party libs
- ajv,
- 'ajv-formats': addFormats,
- atob,
- btoa,
- lodash,
- moment,
- uuid,
- nanoid,
- axios,
- chai,
- 'node-fetch': fetch,
- 'crypto-js': CryptoJS,
- ...whitelistedModules,
- fs: allowScriptFilesystemAccess ? fs : undefined,
- 'node-vault': NodeVault
- }
- }
- });
- const asyncVM = vm.run(
- `module.exports = async () => {
- console?.debug && console.debug('vm2:pre-request:execution-start');
- ${script}
- console?.debug && console.debug('vm2:pre-request:execution-end:');
- }`,
- path.join(collectionPath, 'vm.js')
- );
- await asyncVM();
+
+ return {
+ request,
+ envVariables: cleanJson(envVariables),
+ runtimeVariables: cleanJson(runtimeVariables),
+ nextRequestName: bru.nextRequest
+ };
}
+ // default runtime is vm2
+ const vm = new NodeVM({
+ sandbox: context,
+ require: {
+ context: 'sandbox',
+ external: true,
+ root: [collectionPath, ...additionalContextRootsAbsolute],
+ mock: {
+ // node libs
+ path,
+ stream,
+ util,
+ url,
+ http,
+ https,
+ punycode,
+ zlib,
+ // 3rd party libs
+ ajv,
+ 'ajv-formats': addFormats,
+ atob,
+ btoa,
+ lodash,
+ moment,
+ uuid,
+ nanoid,
+ axios,
+ chai,
+ 'node-fetch': fetch,
+ 'crypto-js': CryptoJS,
+ ...whitelistedModules,
+ fs: allowScriptFilesystemAccess ? fs : undefined,
+ 'node-vault': NodeVault
+ }
+ }
+ });
+ const asyncVM = vm.run(`module.exports = async () => { ${script} }`, path.join(collectionPath, 'vm.js'));
+ await asyncVM();
+
return {
request,
envVariables: cleanJson(envVariables),
@@ -179,14 +171,6 @@ class ScriptRuntime {
processEnvVars,
scriptingConfig
) {
- if (this.mode === 'restricted') {
- return {
- request,
- envVariables: cleanJson(envVariables),
- collectionVariables: cleanJson(collectionVariables),
- nextRequestName: undefined
- };
- }
const requestVariables = request?.requestVariables || {};
const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, requestVariables);
const req = new BrunoRequest(request);
@@ -226,7 +210,7 @@ class ScriptRuntime {
};
}
- if (this.mode == 'safe') {
+ if (this.runtime === 'isolated-vm') {
// Reuses the same instance of IsolatedVMAsync
// TODO: Test for performance
// await isolatedVMAsyncInstance.execute({
@@ -241,54 +225,54 @@ class ScriptRuntime {
modules: {},
scriptType: 'jsScript'
});
- } else {
- // DEVELOPER MODE
- const vm = new NodeVM({
- sandbox: context,
- require: {
- context: 'sandbox',
- external: true,
- root: [collectionPath],
- mock: {
- // node libs
- path,
- stream,
- util,
- url,
- http,
- https,
- punycode,
- zlib,
- // 3rd party libs
- ajv,
- 'ajv-formats': addFormats,
- atob,
- btoa,
- lodash,
- moment,
- uuid,
- nanoid,
- axios,
- 'node-fetch': fetch,
- 'crypto-js': CryptoJS,
- ...whitelistedModules,
- fs: allowScriptFilesystemAccess ? fs : undefined,
- 'node-vault': NodeVault
- }
- }
- });
- const asyncVM = vm.run(
- `module.exports = async () => {
- console?.debug && console.debug('vm2:post-response:execution-start:');
- ${script}
- console?.debug && console.debug('vm2:post-response:execution-end:');
- }`,
- path.join(collectionPath, 'vm.js')
- );
- await asyncVM();
+ return {
+ response,
+ envVariables: cleanJson(envVariables),
+ runtimeVariables: cleanJson(runtimeVariables),
+ nextRequestName: bru.nextRequest
+ };
}
+ // default runtime is vm2
+ const vm = new NodeVM({
+ sandbox: context,
+ require: {
+ context: 'sandbox',
+ external: true,
+ root: [collectionPath],
+ mock: {
+ // node libs
+ path,
+ stream,
+ util,
+ url,
+ http,
+ https,
+ punycode,
+ zlib,
+ // 3rd party libs
+ ajv,
+ 'ajv-formats': addFormats,
+ atob,
+ btoa,
+ lodash,
+ moment,
+ uuid,
+ nanoid,
+ axios,
+ 'node-fetch': fetch,
+ 'crypto-js': CryptoJS,
+ ...whitelistedModules,
+ fs: allowScriptFilesystemAccess ? fs : undefined,
+ 'node-vault': NodeVault
+ }
+ }
+ });
+
+ const asyncVM = vm.run(`module.exports = async () => { ${script} }`, path.join(collectionPath, 'vm.js'));
+ await asyncVM();
+
return {
response,
envVariables: cleanJson(envVariables),
diff --git a/packages/bruno-js/src/runtime/test-runtime.js b/packages/bruno-js/src/runtime/test-runtime.js
index 615c98904..72565d2e2 100644
--- a/packages/bruno-js/src/runtime/test-runtime.js
+++ b/packages/bruno-js/src/runtime/test-runtime.js
@@ -30,12 +30,11 @@ const axios = require('axios');
const fetch = require('node-fetch');
const CryptoJS = require('crypto-js');
const NodeVault = require('node-vault');
-const { executeInIsolatedVMAsync, isolatedVMAsyncInstance } = require('../sandbox/isolatedvm');
+const { executeInIsolatedVMAsync } = require('../sandbox/isolatedvm');
class TestRuntime {
constructor(props) {
this.runtime = props?.runtime || 'vm2';
- this.mode = props?.mode || 'developer';
}
async runTests(
@@ -49,14 +48,6 @@ class TestRuntime {
processEnvVars,
scriptingConfig
) {
- if (this.mode === 'restricted') {
- return {
- request,
- envVariables: cleanJson(envVariables),
- collectionVariables: cleanJson(collectionVariables),
- results: []
- };
- }
const requestVariables = request?.requestVariables || {};
const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, requestVariables);
const req = new BrunoRequest(request);
@@ -132,54 +123,55 @@ class TestRuntime {
modules: {},
scriptType: 'jsScript'
});
- } else {
- // DEVELOPER MODE
- const vm = new NodeVM({
- sandbox: context,
- require: {
- context: 'sandbox',
- external: true,
- root: [collectionPath, ...additionalContextRootsAbsolute],
- mock: {
- // node libs
- path,
- stream,
- util,
- url,
- http,
- https,
- punycode,
- zlib,
- // 3rd party libs
- ajv,
- 'ajv-formats': addFormats,
- btoa,
- atob,
- lodash,
- moment,
- uuid,
- nanoid,
- axios,
- chai,
- 'node-fetch': fetch,
- 'crypto-js': CryptoJS,
- ...whitelistedModules,
- fs: allowScriptFilesystemAccess ? fs : undefined,
- 'node-vault': NodeVault
- }
- }
- });
- const asyncVM = vm.run(
- `module.exports = async () => {
- console?.debug && console.debug('vm2:tests:execution-start');
- ${testsFile}
- console?.debug && console.debug('vm2:tests:execution-end:');
- }`,
- path.join(collectionPath, 'vm.js')
- );
- await asyncVM();
+
+ return {
+ request,
+ envVariables: cleanJson(envVariables),
+ runtimeVariables: cleanJson(runtimeVariables),
+ results: cleanJson(__brunoTestResults.getResults()),
+ nextRequestName: bru.nextRequest
+ };
}
+ // default runtime is vm2
+ const vm = new NodeVM({
+ sandbox: context,
+ require: {
+ context: 'sandbox',
+ external: true,
+ root: [collectionPath, ...additionalContextRootsAbsolute],
+ mock: {
+ // node libs
+ path,
+ stream,
+ util,
+ url,
+ http,
+ https,
+ punycode,
+ zlib,
+ // 3rd party libs
+ ajv,
+ 'ajv-formats': addFormats,
+ btoa,
+ atob,
+ lodash,
+ moment,
+ uuid,
+ nanoid,
+ axios,
+ chai,
+ 'node-fetch': fetch,
+ 'crypto-js': CryptoJS,
+ ...whitelistedModules,
+ fs: allowScriptFilesystemAccess ? fs : undefined,
+ 'node-vault': NodeVault
+ }
+ }
+ });
+ const asyncVM = vm.run(`module.exports = async () => { ${testsFile}}`, path.join(collectionPath, 'vm.js'));
+ await asyncVM();
+
return {
request,
envVariables: cleanJson(envVariables),
diff --git a/packages/bruno-js/src/runtime/vars-runtime.js b/packages/bruno-js/src/runtime/vars-runtime.js
index ef92bc936..ef04511a5 100644
--- a/packages/bruno-js/src/runtime/vars-runtime.js
+++ b/packages/bruno-js/src/runtime/vars-runtime.js
@@ -5,55 +5,28 @@ const { evaluateJsTemplateLiteral, evaluateJsExpression, createResponseParser }
const { isolatedVMStrictInstance } = require('../sandbox/isolatedvm');
-const toNumber = (value) => {
- const num = Number(value);
- return Number.isInteger(num) ? parseInt(value, 10) : parseFloat(value);
-};
-
-const evaluateJsTemplateLiteralBasedOnRuntime = (v, context, runtime, mode) => {
- let value;
- if (mode === 'restricted') {
- let _value = _.get(context, v, v);
- if (_value && typeof _value == 'object') {
- value = JSON.stringify(_value);
- } else if (Number.isNaN(Number(_value))) {
- value = _value;
- } else {
- value = toNumber(_value);
- }
- } else if (mode === 'safe') {
- value = isolatedVMStrictInstance.execute({
- script: v,
+const evaluateJsTemplateLiteralBasedOnRuntime = (literal, context, runtime) => {
+ if(runtime === 'isolated-vm') {
+ return isolatedVMStrictInstance.execute({
+ script: literal,
context,
scriptType: 'template-literal'
});
- } else {
- value = evaluateJsTemplateLiteral(v, context);
}
- return value;
+
+ return evaluateJsTemplateLiteral(literal, context);
};
-const evaluateJsExpressionBasedOnRuntime = (v, context, runtime, mode) => {
- let value;
- if (mode === 'restricted') {
- let _value = _.get(context, v, v);
- if (_value && typeof _value == 'object') {
- value = JSON.stringify(_value);
- } else if (Number.isNaN(Number(_value))) {
- value = _value;
- } else {
- value = toNumber(_value);
- }
- } else if (mode === 'safe') {
- value = isolatedVMStrictInstance.execute({
- script: v,
+const evaluateJsExpressionBasedOnRuntime = (expr, context, runtime, mode) => {
+ if(runtime === 'isolated-vm') {
+ return isolatedVMStrictInstance.execute({
+ script: expr,
context,
scriptType: 'expression'
});
- } else {
- value = evaluateJsExpression(v, context);
}
- return value;
+
+ return evaluateJsExpression(expr, context);
};
class VarsRuntime {
@@ -86,7 +59,7 @@ class VarsRuntime {
};
_.each(enabledVars, (v) => {
- const value = evaluateJsTemplateLiteralBasedOnRuntime(v.value, context, this.runtime, this.mode);
+ const value = evaluateJsTemplateLiteralBasedOnRuntime(v.value, context, this.runtime);
request?.requestVariables && (request.requestVariables[v.name] = value);
});
}
@@ -117,7 +90,7 @@ class VarsRuntime {
const errors = new Map();
_.each(enabledVars, (v) => {
try {
- const value = evaluateJsExpressionBasedOnRuntime(v.value, context, this.runtime, this.mode);
+ const value = evaluateJsExpressionBasedOnRuntime(v.value, context, this.runtime);
bru.setVar(v.name, value);
} catch (error) {
errors.set(v.name, error);
diff --git a/packages/bruno-js/src/sandbox/isolatedvm/index.js b/packages/bruno-js/src/sandbox/isolatedvm/index.js
index ac361ef9e..c98e38e3e 100644
--- a/packages/bruno-js/src/sandbox/isolatedvm/index.js
+++ b/packages/bruno-js/src/sandbox/isolatedvm/index.js
@@ -1,8 +1,8 @@
const ivm = require('isolated-vm');
const addBruShimToContext = require('./shims/bru');
-const addBrunoRequestShimToContext = require('./shims/brunoRequest');
+const addBrunoRequestShimToContext = require('./shims/bruno-request');
const addConsoleShimToContext = require('./shims/console');
-const addBrunoResponseShimToContext = require('./shims/brunoResponse');
+const addBrunoResponseShimToContext = require('./shims/bruno-response');
const addTestShimToContext = require('./shims/test');
const fs = require('fs');
const addLibraryShimsToContext = require('./shims/lib');
diff --git a/packages/bruno-js/src/sandbox/isolatedvm/shims/brunoRequest.js b/packages/bruno-js/src/sandbox/isolatedvm/shims/bruno-request.js
similarity index 100%
rename from packages/bruno-js/src/sandbox/isolatedvm/shims/brunoRequest.js
rename to packages/bruno-js/src/sandbox/isolatedvm/shims/bruno-request.js
diff --git a/packages/bruno-js/src/sandbox/isolatedvm/shims/brunoResponse.js b/packages/bruno-js/src/sandbox/isolatedvm/shims/bruno-response.js
similarity index 100%
rename from packages/bruno-js/src/sandbox/isolatedvm/shims/brunoResponse.js
rename to packages/bruno-js/src/sandbox/isolatedvm/shims/bruno-response.js
diff --git a/packages/bruno-js/src/sandbox/isolatedvm/utils/bundleLibraries.js b/packages/bruno-js/src/sandbox/isolatedvm/utils/bundle-libraries.js
similarity index 100%
rename from packages/bruno-js/src/sandbox/isolatedvm/utils/bundleLibraries.js
rename to packages/bruno-js/src/sandbox/isolatedvm/utils/bundle-libraries.js
diff --git a/packages/bruno-js/tests/runtime.spec.js b/packages/bruno-js/tests/runtime.spec.js
index 46ea62fb7..766569d03 100644
--- a/packages/bruno-js/tests/runtime.spec.js
+++ b/packages/bruno-js/tests/runtime.spec.js
@@ -114,7 +114,7 @@ describe('runtime', () => {
bru.setVar('validation', validate(new Date().toISOString()))
`;
- const runtime = new ScriptRuntime({ runtime: 'vm2', mode: 'developer' });
+ const runtime = new ScriptRuntime({ runtime: 'vm2' });
const result = await runtime.runRequestScript(script, { ...baseRequest }, {}, {}, '.', null, process.env);
expect(result.runtimeVariables.validation).toBeTruthy();
});
@@ -160,7 +160,7 @@ describe('runtime', () => {
bru.setVar('validation', validate(new Date().toISOString()))
`;
- const runtime = new ScriptRuntime({ runtime: 'vm2', mode: 'developer' });
+ const runtime = new ScriptRuntime({ runtime: 'vm2' });
const result = await runtime.runResponseScript(
script,
{ ...baseRequest },