mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-21 23:43:15 +01:00
feat: safe mode quickjs updates (#2866)
* wip: safe mode updates * wip: safe mode quickjs updates * wip: safe mode updates * wip: safe mode updates * wip: safe mode updates
This commit is contained in:
parent
35376305ae
commit
64cb45c09a
8
package-lock.json
generated
8
package-lock.json
generated
@ -8340,6 +8340,12 @@
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
|
||||
},
|
||||
"node_modules/crypto-js-3.1.9-1": {
|
||||
"name": "crypto-js",
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz",
|
||||
"integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q=="
|
||||
},
|
||||
"node_modules/crypto-random-string": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
|
||||
@ -20595,12 +20601,14 @@
|
||||
"chai": "^4.3.7",
|
||||
"chai-string": "^1.5.0",
|
||||
"crypto-js": "^4.1.1",
|
||||
"crypto-js-3.1.9-1": "npm:crypto-js@^3.1.9-1",
|
||||
"json-query": "^2.2.2",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.4",
|
||||
"nanoid": "3.3.4",
|
||||
"node-fetch": "^2.7.0",
|
||||
"node-vault": "^0.10.2",
|
||||
"path": "^0.12.7",
|
||||
"quickjs-emscripten": "^0.29.2",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
|
@ -25,12 +25,14 @@
|
||||
"chai": "^4.3.7",
|
||||
"chai-string": "^1.5.0",
|
||||
"crypto-js": "^4.1.1",
|
||||
"crypto-js-3.1.9-1": "npm:crypto-js@^3.1.9-1",
|
||||
"json-query": "^2.2.2",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.4",
|
||||
"nanoid": "3.3.4",
|
||||
"node-fetch": "^2.7.0",
|
||||
"node-vault": "^0.10.2",
|
||||
"path": "^0.12.7",
|
||||
"quickjs-emscripten": "^0.29.2",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
|
@ -84,6 +84,9 @@ class TestRuntime {
|
||||
};
|
||||
}
|
||||
|
||||
// add 'await' prefix to the test function calls
|
||||
testsFile = testsFile.replace(/^(?!\s*await\s)(test\([^)]*\))/gm, 'await $1');
|
||||
|
||||
const context = {
|
||||
test,
|
||||
bru,
|
||||
|
@ -11,18 +11,22 @@ const bundleLibraries = async () => {
|
||||
import moment from "moment";
|
||||
import btoa from "btoa";
|
||||
import atob from "atob";
|
||||
import * as CryptoJS from "crypto-js-3.1.9-1";
|
||||
globalThis.expect = expect;
|
||||
globalThis.assert = assert;
|
||||
globalThis.moment = moment;
|
||||
globalThis.btoa = btoa;
|
||||
globalThis.atob = atob;
|
||||
globalThis.Buffer = Buffer;
|
||||
globalThis.CryptoJS = CryptoJS;
|
||||
globalThis.requireObject = {
|
||||
...(globalThis.requireObject || {}),
|
||||
'chai': { expect, assert },
|
||||
'moment': moment,
|
||||
'buffer': { Buffer },
|
||||
'btoa': btoa,
|
||||
'atob': atob,
|
||||
'crypto-js': CryptoJS
|
||||
};
|
||||
`;
|
||||
|
||||
|
@ -9,6 +9,7 @@ const { newQuickJSWASMModule, memoizePromiseFactory } = require('quickjs-emscrip
|
||||
|
||||
// execute `npm run sandbox:bundle-libraries` if the below file doesn't exist
|
||||
const getBundledCode = require('../bundle-browser-rollup');
|
||||
const addPathShimToContext = require('./shims/lib/path');
|
||||
|
||||
let QuickJSSyncContext;
|
||||
const loader = memoizePromiseFactory(() => newQuickJSWASMModule());
|
||||
@ -64,14 +65,14 @@ const executeQuickJsVmAsync = async ({ script: externalScript, context: external
|
||||
const vm = module.newContext();
|
||||
|
||||
const bundledCode = getBundledCode?.toString() || '';
|
||||
const moduleLoaderCode = function() {
|
||||
const moduleLoaderCode = function () {
|
||||
return `
|
||||
globalThis.require = (mod) => {
|
||||
let lib = globalThis.requireObject[mod];
|
||||
if (lib) {
|
||||
return lib;
|
||||
}
|
||||
else {
|
||||
else if(mod?.startsWith('.') || mod?.startsWith?.(bru.cwd())){
|
||||
// fetch local module
|
||||
let localModuleCode = globalThis.__brunoLoadLocalModule(mod);
|
||||
|
||||
@ -79,7 +80,12 @@ const executeQuickJsVmAsync = async ({ script: externalScript, context: external
|
||||
(function (){
|
||||
const initModuleExportsCode = "const module = { exports: {} };"
|
||||
const copyModuleExportsCode = "\\n;globalThis.requireObject[mod] = module.exports;";
|
||||
eval(initModuleExportsCode + localModuleCode + copyModuleExportsCode);
|
||||
const patchedRequire = ${`
|
||||
"\\n;" +
|
||||
"let require = (subModule) => globalThis.require(path.resolve(bru.cwd(), mod, '..', subModule))" +
|
||||
"\\n;"
|
||||
`}
|
||||
eval(initModuleExportsCode + patchedRequire + localModuleCode + copyModuleExportsCode);
|
||||
})();
|
||||
|
||||
// resolve module
|
||||
@ -103,6 +109,7 @@ const executeQuickJsVmAsync = async ({ script: externalScript, context: external
|
||||
res && addBrunoResponseShimToContext(vm, res);
|
||||
consoleFn && addConsoleShimToContext(vm, consoleFn);
|
||||
addLocalModuleLoaderShimToContext(vm, collectionPath);
|
||||
addPathShimToContext(vm);
|
||||
|
||||
await addLibraryShimsToContext(vm);
|
||||
|
||||
@ -135,6 +142,7 @@ const executeQuickJsVmAsync = async ({ script: externalScript, context: external
|
||||
return;
|
||||
} catch (error) {
|
||||
console.error('Error executing the script!', error);
|
||||
throw new Error(error);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
const addAxiosShimToContext = require('./axios');
|
||||
const addNanoidShimToContext = require('./nanoid');
|
||||
const addNodeFetchShimToContext = require('./node-fetch');
|
||||
const addPathShimToContext = require('./path');
|
||||
const addUuidShimToContext = require('./uuid');
|
||||
|
||||
const addLibraryShimsToContext = async (vm) => {
|
||||
await addNanoidShimToContext(vm);
|
||||
await addAxiosShimToContext(vm);
|
||||
await addNodeFetchShimToContext(vm);
|
||||
await addUuidShimToContext(vm);
|
||||
await addPathShimToContext(vm);
|
||||
};
|
||||
|
||||
module.exports = addLibraryShimsToContext;
|
||||
|
@ -1,41 +0,0 @@
|
||||
const fetch = require('node-fetch');
|
||||
const { cleanJson } = require('../../../../utils');
|
||||
const { marshallToVm } = require('../../utils');
|
||||
|
||||
const addNodeFetchShimToContext = async (vm) => {
|
||||
const nodeFetchHandle = vm.newFunction('node_fetch', (...args) => {
|
||||
const nativeArgs = args.map(vm.dump);
|
||||
const promise = vm.newPromise();
|
||||
fetch(...nativeArgs)
|
||||
.then(async (response) => {
|
||||
const { status, headers } = response || {};
|
||||
const data = await response.json();
|
||||
promise.resolve(marshallToVm(cleanJson({ status, headers, data }), vm));
|
||||
})
|
||||
.catch((err) => {
|
||||
promise.resolve(
|
||||
marshallToVm(
|
||||
cleanJson({
|
||||
message: err.message
|
||||
}),
|
||||
vm
|
||||
)
|
||||
);
|
||||
});
|
||||
promise.settled.then(vm.runtime.executePendingJobs);
|
||||
return promise.handle;
|
||||
});
|
||||
|
||||
nodeFetchHandle.consume((handle) => vm.setProp(vm.global, `__bruno__node_fetch`, handle));
|
||||
vm.evalCode(
|
||||
`
|
||||
globalThis.nodeFetch = __bruno__node_fetch;
|
||||
globalThis.requireObject = {
|
||||
...globalThis.requireObject,
|
||||
'node-fetch': globalThis.nodeFetch,
|
||||
}
|
||||
`
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = addNodeFetchShimToContext;
|
28
packages/bruno-js/src/sandbox/quickjs/shims/lib/path.js
Normal file
28
packages/bruno-js/src/sandbox/quickjs/shims/lib/path.js
Normal file
@ -0,0 +1,28 @@
|
||||
const path = require('path');
|
||||
const { marshallToVm } = require('../../utils');
|
||||
|
||||
const fns = ['resolve'];
|
||||
|
||||
const addPathShimToContext = async (vm) => {
|
||||
fns.forEach((fn) => {
|
||||
let fnHandle = vm.newFunction(fn, function (...args) {
|
||||
const nativeArgs = args.map(vm.dump);
|
||||
return marshallToVm(path[fn](...nativeArgs), vm);
|
||||
});
|
||||
vm.setProp(vm.global, `__bruno__path__${fn}`, fnHandle);
|
||||
fnHandle.dispose();
|
||||
});
|
||||
|
||||
vm.evalCode(
|
||||
`
|
||||
globalThis.path = {};
|
||||
${fns?.map((fn, idx) => `globalThis.path.${fn} = __bruno__path__${fn}`).join('\n')}
|
||||
globalThis.requireObject = {
|
||||
...(globalThis.requireObject || {}),
|
||||
path: globalThis.path,
|
||||
}
|
||||
`
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = addPathShimToContext;
|
@ -1,4 +1,4 @@
|
||||
const { PI } = require('./lib/constants');
|
||||
const { PI } = require('./constants');
|
||||
|
||||
const sum = (a, b) => a + b;
|
||||
const areaOfCircle = (radius) => PI * radius * radius;
|
||||
@ -6,4 +6,4 @@ const areaOfCircle = (radius) => PI * radius * radius;
|
||||
module.exports = {
|
||||
sum,
|
||||
areaOfCircle
|
||||
};
|
||||
};
|
||||
|
@ -9,8 +9,3 @@ get {
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
var CryptoJS = require("crypto-js");
|
||||
console.log(CryptoJS);
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
meta {
|
||||
name: crypto-js-pre-request-script
|
||||
type: http
|
||||
seq: 1
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{host}}/ping
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
var CryptoJS = require("crypto-js");
|
||||
|
||||
// Encrypt
|
||||
var ciphertext = CryptoJS.AES.encrypt('my message', 'secret key 123').toString();
|
||||
|
||||
// Decrypt
|
||||
var bytes = CryptoJS.AES.decrypt(ciphertext, 'secret key 123');
|
||||
var originalText = bytes.toString(CryptoJS.enc.Utf8);
|
||||
|
||||
bru.setVar('crypto-test-message', originalText);
|
||||
}
|
||||
|
||||
tests {
|
||||
test("crypto message", function() {
|
||||
const data = bru.getVar('crypto-test-message');
|
||||
bru.setVar('crypto-test-message', null);
|
||||
expect(data).to.eql('my message');
|
||||
});
|
||||
|
||||
}
|
@ -13,5 +13,14 @@ get {
|
||||
script:pre-request {
|
||||
const { nanoid } = require("nanoid");
|
||||
|
||||
req.setHeader("transaction-id", nanoid());
|
||||
bru.setVar("nanoid-test-id", nanoid());
|
||||
}
|
||||
|
||||
tests {
|
||||
test("nanoid var", function() {
|
||||
const id = bru.getVar('nanoid-test-id');
|
||||
let isValidNanoid = /^[a-zA-Z0-9_-]{21}$/.test(id)
|
||||
bru.setVar('nanoid-test-id', null);
|
||||
expect(isValidNanoid).to.eql(true);
|
||||
});
|
||||
}
|
||||
|
@ -1,36 +0,0 @@
|
||||
meta {
|
||||
name: node-fetch-pre-req-script
|
||||
type: http
|
||||
seq: 1
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{host}}/ping
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
const fetch = require("node-fetch");
|
||||
|
||||
const url = "https://testbench-sanity.usebruno.com/api/echo/json";
|
||||
const response = await fetch(url, {
|
||||
method: 'post',
|
||||
body: JSON.stringify({hello:'bruno'}),
|
||||
headers: {'Content-Type': 'application/json'}
|
||||
});
|
||||
|
||||
req.setBody(response.data);
|
||||
req.setMethod("POST");
|
||||
req.setUrl(url);
|
||||
}
|
||||
|
||||
tests {
|
||||
test("req.getBody()", function() {
|
||||
const data = res.getBody();
|
||||
expect(data).to.eql({
|
||||
"hello": "bruno"
|
||||
});
|
||||
});
|
||||
|
||||
}
|
@ -13,5 +13,14 @@ get {
|
||||
script:pre-request {
|
||||
const { v4 } = require("uuid");
|
||||
|
||||
req.setHeader("transaction-id", v4());
|
||||
bru.setVar("uuid-test-id", v4());
|
||||
}
|
||||
|
||||
tests {
|
||||
test("uuid var", function() {
|
||||
const id = bru.getVar('uuid-test-id');
|
||||
let isValidUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(id);
|
||||
bru.setVar('uuid-test-id', null);
|
||||
expect(isValidUuid).to.eql(true);
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user