Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: set up sandbox for script execution [INS-3378] #6991

Closed
wants to merge 35 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c4db28a
feat: enable islated utility process [INS-3378]
ihexxa Dec 2, 2023
2c57eda
fix: disable flaky test and extend timeout
ihexxa Dec 11, 2023
6e010d0
test: add some logs
ihexxa Dec 11, 2023
f9badb3
chore: add some logs
ihexxa Dec 11, 2023
8261c04
feat: add cookie related objects
ihexxa Dec 12, 2023
08dadd7
fix: add script path env for utility process
ihexxa Dec 13, 2023
47a3fbe
fix: lint issue
ihexxa Dec 13, 2023
1538d04
fix: lint error
ihexxa Dec 13, 2023
5ee7ffc
fix: make vite supporting multiple entries
ihexxa Dec 13, 2023
dea3165
fix: remove utility process building task and use vite instead
ihexxa Dec 13, 2023
438ecaa
fix: always outputs utility process bundle to src folder instead of b…
ihexxa Dec 13, 2023
5438d38
chore: some small fixes
ihexxa Dec 14, 2023
475ab01
fix: make utility process can be triggerred
ihexxa Dec 14, 2023
b8fb33b
fix: add missing file
ihexxa Dec 14, 2023
9ed1595
fix: enable smoke tests
ihexxa Dec 15, 2023
04178a7
fix: revert commented tests
ihexxa Dec 15, 2023
bb2b293
fix: utility process is a improper name for the browser window
ihexxa Dec 20, 2023
daad944
feat: support global object aliases and timeout
ihexxa Dec 20, 2023
42f46ed
chore: keep develop version for other tests
ihexxa Dec 21, 2023
e907790
fix: improve tests a bit and hide the browser window
ihexxa Dec 22, 2023
7a5076b
test: add tests for unhappy paths
ihexxa Dec 22, 2023
dbe2697
fix: get the main renderer instead of the first one in testing as the…
ihexxa Jan 2, 2024
485fe7c
chore: try keep test timeout untouched
ihexxa Jan 2, 2024
11b53f1
fix: pick improvements from the downstream PR
ihexxa Jan 3, 2024
6016412
fix: start hidden window on-demand instead of by default
ihexxa Jan 4, 2024
92a808c
test: create a helper function for waiting for a specific window
ihexxa Jan 4, 2024
f97320d
chore: add logs for hidden browser window initing
ihexxa Jan 4, 2024
99276aa
chore: add log prefix for logs
ihexxa Jan 8, 2024
7bf4191
chore: clean up and minimize changes
ihexxa Jan 17, 2024
0939f9b
chore: minimize changes
ihexxa Jan 17, 2024
5298c9e
fix: make test just run one line code and return
ihexxa Jan 17, 2024
de56d3e
fix: use builtin function for waiting
ihexxa Jan 17, 2024
c18fbbe
chore: turn class into functions
ihexxa Jan 17, 2024
7297ce8
chore: clean up
ihexxa Jan 17, 2024
2ad8d17
chore: refactor table driven tests into the normal approach
ihexxa Jan 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: support global object aliases and timeout
  • Loading branch information
ihexxa authored and jackkav committed Feb 5, 2024
commit daad94470ad7aff72fd330151a49b6c5cd1cc49d
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ test.describe('test pre-request script execution', async () => {
pm.environment.set('rendered', vals);
`,
context: {
pm: {
insomnia: {
environment: {
bool1: true,
num1: 1,
Expand Down Expand Up @@ -102,7 +102,7 @@ test.describe('test pre-request script execution', async () => {
pm.collectionVariables.set('rendered', vals);
`,
context: {
pm: {
insomnia: {
collectionVariables: {
bool1: true,
num1: 1,
Expand Down Expand Up @@ -164,7 +164,7 @@ test.describe('test pre-request script execution', async () => {
pm.variables.set('rendered', rendered);
`,
context: {
pm: {
insomnia: {
globals: {
bool: false,
num: 1,
Expand Down Expand Up @@ -228,47 +228,6 @@ test.describe('test pre-request script execution', async () => {
'requestName': '',
},
},
// {
// id: 'simple test sendRequest and await/async',
// code: `
// let testResp;
// try {
// await new Promise(
// resolve => {
// pm.sendRequest(
// 'https://127.0.0.1:4010/pets/1',
// (err, resp) => {
// testResp = resp;
// resolve();
// }
// );
// }
// );
// } catch (e) {
// pm.variables.set('resp.code', e);
// }
// pm.variables.set('resp.code', testResp.code);
// `,
// context: {
// pm: {},
// },
// expectedResult: {
// globals: {},
// iterationData: {},
// variables: {
// 'resp.code': 200,
// },
// environment: {},
// collectionVariables: {},
// info: {
// 'eventName': 'prerequest',
// 'iteration': 1,
// 'iterationCount': 1,
// 'requestId': '',
// 'requestName': '',
// },
// },
// },
{
id: 'requestInfo tests',
code: `
Expand All @@ -279,7 +238,7 @@ test.describe('test pre-request script execution', async () => {
const requestId = pm.info.requestId;
`,
context: {
pm: {
insomnia: {
requestInfo: {
eventName: 'prerequest',
iteration: 1,
Expand Down Expand Up @@ -326,7 +285,7 @@ test.describe('test pre-request script execution', async () => {
},
);

// waiting for the process ready
// waiting for the hidden browser ready
for (let i = 0; i < 120; i++) {
const windows = app.windows();
if (windows.length > originalWindowCount) {
Expand Down Expand Up @@ -372,8 +331,6 @@ test.describe('test pre-request script execution', async () => {
await mainWindow.waitForTimeout(500);
}

// await mainWindow.waitForTimeout(300000);

if (localStorage) { // just for suppressing ts complaint
console.log(localStorage[`test_error:${tc.id}`]);
expect(JSON.parse(localStorage[`test_result:${tc.id}`])).toEqual(tc.expectedResult);
Expand Down
2 changes: 1 addition & 1 deletion packages/insomnia/src/main/window-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export function init() {

export function createHiddenBrowserWindow() {
hiddenBrowserWindow = new BrowserWindow({
show: false,
show: true,
title: 'HiddenBrowserWindow',
webPreferences: {
sandbox: true,
Expand Down
51 changes: 31 additions & 20 deletions packages/insomnia/src/renderers/hidden-browser-window/index.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,61 @@
import { initPm } from './inso-object';
import { initGlobalObject } from './inso-object';

const executeAction = 'message-port:https://hidden.browser-window/execute';
const executeAction = 'message-channel:https://hidden.browser-window/execute';
const ErrorTimeout = 'execution timeout';

async function init() {
const channel = new MessageChannel();

channel.port1.onmessage = async (ev: MessageEvent) => {
const action = ev.data.action;
const timeout = ev.data.timeout ? ev.data.timeout : 3000;

if (action === executeAction || action === 'message-port:https://hidden.browser-window/debug') {
if (action === executeAction || action === 'message-channel:https://hidden.browser-window/debug') {
try {
const getPm = new Function('pm', 'return pm;');
const rawPm = getPm(ev.data.options.context.pm);
const pm = initPm(rawPm);
const getRawGlobalObject = new Function('insomnia', 'return insomnia;');
const rawObject = getRawGlobalObject(ev.data.options.context.insomnia);
const insomniaObject = initGlobalObject(rawObject);

const AsyncFunction = (async () => { }).constructor;
const func = AsyncFunction(
'pm',
// TODO: support require function
// TODO: support async/await
const executeScript = AsyncFunction(
'insomnia',
`
${ev.data.options.code};
return pm.toObject();
return new Promise(async (resolve, reject) => {
const $ = insomnia;
const pm = insomnia;
const alertTimeout = () => reject({ message: '${ErrorTimeout}' });
const timeoutChecker = setTimeout(alertTimeout, ${timeout});

${ev.data.options.code};

clearTimeout(timeoutChecker);
resolve(insomnia.toObject());
});
`
);

const result = await func(pm);
const result = await executeScript(
insomniaObject,
);

channel.port1.postMessage({
action: action === executeAction ? 'message-port:https://caller/respond' : 'message-port:https://caller/debug/respond',
action: action === executeAction ? 'message-channel:https://caller/respond' : 'message-channel:https://caller/debug/respond',
id: action === executeAction ? undefined : ev.data.options.id,
result,
});
} catch (e) {
const message = e.message;
const stacktrace = e.stacktrace;

channel.port1.postMessage({
action: action === executeAction ? 'message-port:https://caller/respond' : 'message-port:https://caller/debug/respond',
action: action === executeAction ? 'message-channel:https://caller/respond' : 'message-channel:https://caller/debug/respond',
id: action === executeAction ? undefined : ev.data.options.id,
error: JSON.stringify({ message, stacktrace }),
error: JSON.stringify({ message }),
});
}
} else {
console.error(`unknown action ${ev.data}`);
}
};

}
;
window.postMessage('message-event:https://preload/publish-port', '*', [channel.port2]);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getHttpRequestSender, getIntepolator, HttpRequestSender, PmHttpRequest, PmHttpResponse } from './static-modules';
import { getIntepolator } from './intepolator';

export type EventName = 'prerequest' | 'test';
class RequestInfo {
Expand Down Expand Up @@ -161,8 +161,6 @@ class InsomniaObject {
public variables: Variables;
public info: RequestInfo;

private httpRequestSender: HttpRequestSender = getHttpRequestSender();

constructor(input: {
globals: Environment;
collectionVariables: Environment;
Expand All @@ -189,10 +187,6 @@ class InsomniaObject {
info: this.info.toObject(),
};
};

sendRequest = async (req: string | PmHttpRequest, callback: (e?: Error, resp?: PmHttpResponse) => void) => {
return await this.httpRequestSender.sendRequest(req, callback);
};
}

interface RawObject {
Expand All @@ -203,7 +197,7 @@ interface RawObject {
requestInfo?: object;
}

export function initPm(rawObj: RawObject) {
export function initGlobalObject(rawObj: RawObject) {
const globals = new Environment(rawObj.globals);
const environment = new Environment(rawObj.environment);
const collectionVariables = new Environment(rawObj.collectionVariables);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { configure, type ConfigureOptions, type Environment as NunjuncksEnv } from 'nunjucks';

class Intepolator {
private engine: NunjuncksEnv;

constructor(config: ConfigureOptions) {
this.engine = configure(config);
}

render = (template: string, context: object) => {
// TODO: handle timeout
// TODO: support plugin?
return this.engine.renderString(template, context);
};
}

const intepolator = new Intepolator({
autoescape: false,
// Don't escape HTML
throwOnUndefined: true,
// Strict mode
tags: {
blockStart: '{%',
blockEnd: '%}',
variableStart: '{{',
variableEnd: '}}',
commentStart: '{#',
commentEnd: '#}',
},
});

export function getIntepolator() {
return intepolator;
}

This file was deleted.

9 changes: 6 additions & 3 deletions packages/insomnia/src/ui/window-message-handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ class WindowMessageHandler {
this.hiddenBrowserWindowPort = ev.ports[0];

this.hiddenBrowserWindowPort.onmessage = ev => {
if (ev.data.action === 'message-port:https://caller/respond') {
if (ev.data.action === 'message-channel:https://caller/respond') {
// TODO: hook to UI and display result
console.log('[main] result from hidden browser window:', ev.data.result);
} else if (ev.data.action === 'message-port:https://caller/debug/respond') {
} else if (ev.data.action === 'message-channel:https://caller/debug/respond') {
if (ev.data.result) {
window.localStorage.setItem(`test_result:${ev.data.id}`, JSON.stringify(ev.data.result));
console.log(ev.data.result);
} else {
window.localStorage.setItem(`test_error:${ev.data.id}`, JSON.stringify(ev.data.error));
console.error(ev.data.error);
}
} else {
console.error(`unknown action ${ev}`);
Expand All @@ -37,8 +39,9 @@ class WindowMessageHandler {
return;
}

console.info('sending script to hidden browser window');
this.hiddenBrowserWindowPort.postMessage({
action: 'message-port:https://hidden.browser-window/debug',
action: 'message-channel:https://hidden.browser-window/debug',
options: {
id: ev.data.id,
code: ev.data.code,
Expand Down