diff --git a/packages/bruno-app/src/components/RequestTabs/CollectionToolBar/index.js b/packages/bruno-app/src/components/RequestTabs/CollectionToolBar/index.js index 815699a40..defc0b400 100644 --- a/packages/bruno-app/src/components/RequestTabs/CollectionToolBar/index.js +++ b/packages/bruno-app/src/components/RequestTabs/CollectionToolBar/index.js @@ -5,11 +5,10 @@ import EnvironmentSelector from 'components/Environments/EnvironmentSelector'; import { addTab } from 'providers/ReduxStore/slices/tabs'; import { useDispatch } from 'react-redux'; import StyledWrapper from './StyledWrapper'; -import SecuritySettingsIcon from 'components/SecuritySettings/SecurityIconWithModal/index'; +import JsSandboxMode from 'components/SecuritySettings/JsSandboxMode'; const CollectionToolBar = ({ collection }) => { const dispatch = useDispatch(); - const appMode = collection?.securityConfig?.appMode; const handleRun = () => { dispatch( @@ -59,16 +58,8 @@ const CollectionToolBar = ({ collection }) => { {collection?.name}
- {appMode && ( - - {appMode} mode - - )} - + diff --git a/packages/bruno-app/src/components/SecuritySettings/JsSandboxMode/StyledWrapper.js b/packages/bruno-app/src/components/SecuritySettings/JsSandboxMode/StyledWrapper.js new file mode 100644 index 000000000..cad253fd9 --- /dev/null +++ b/packages/bruno-app/src/components/SecuritySettings/JsSandboxMode/StyledWrapper.js @@ -0,0 +1,16 @@ +import styled from 'styled-components'; + +const StyledWrapper = styled.div` + .safe-mode { + padding: 0.15rem 0.3rem; + color: ${(props) => props.theme.colors.text.green}; + border: solid 1px ${(props) => props.theme.colors.text.green} !important; + } + .developer-mode { + padding: 0.15rem 0.3rem; + color: ${(props) => props.theme.colors.text.yellow}; + border: solid 1px ${(props) => props.theme.colors.text.yellow} !important; + } +`; + +export default StyledWrapper; diff --git a/packages/bruno-app/src/components/SecuritySettings/JsSandboxMode/index.js b/packages/bruno-app/src/components/SecuritySettings/JsSandboxMode/index.js new file mode 100644 index 000000000..c4ab2dbf2 --- /dev/null +++ b/packages/bruno-app/src/components/SecuritySettings/JsSandboxMode/index.js @@ -0,0 +1,45 @@ +import { useDispatch } from 'react-redux'; +import { IconShieldLock } from '@tabler/icons'; +import { addTab } from 'providers/ReduxStore/slices/tabs'; +import { uuid } from 'utils/common/index'; +import JsSandboxModeModal from '../JsSandboxModeModal'; +import StyledWrapper from './StyledWrapper'; + +const JsSandboxMode = ({ collection }) => { + const jsSandboxMode = collection?.securityConfig?.jsSandboxMode; + const dispatch = useDispatch(); + + const viewSecuritySettings = () => { + dispatch( + addTab({ + uid: uuid(), + collectionUid: collection.uid, + type: 'security-settings' + }) + ); + }; + + return ( + + {jsSandboxMode === 'safe' && ( +
+ Safe Mode +
+ )} + {jsSandboxMode === 'developer' && ( +
+ Developer Mode +
+ )} + {!jsSandboxMode ? : null} +
+ ); +}; + +export default JsSandboxMode; diff --git a/packages/bruno-app/src/components/SecuritySettings/SecurityIconWithModal/AppModeModal/StyledWrapper.js b/packages/bruno-app/src/components/SecuritySettings/JsSandboxModeModal/StyledWrapper.js similarity index 100% rename from packages/bruno-app/src/components/SecuritySettings/SecurityIconWithModal/AppModeModal/StyledWrapper.js rename to packages/bruno-app/src/components/SecuritySettings/JsSandboxModeModal/StyledWrapper.js diff --git a/packages/bruno-app/src/components/SecuritySettings/SecurityIconWithModal/AppModeModal/index.js b/packages/bruno-app/src/components/SecuritySettings/JsSandboxModeModal/index.js similarity index 73% rename from packages/bruno-app/src/components/SecuritySettings/SecurityIconWithModal/AppModeModal/index.js rename to packages/bruno-app/src/components/SecuritySettings/JsSandboxModeModal/index.js index f208a08e7..d0e5942a6 100644 --- a/packages/bruno-app/src/components/SecuritySettings/SecurityIconWithModal/AppModeModal/index.js +++ b/packages/bruno-app/src/components/SecuritySettings/JsSandboxModeModal/index.js @@ -6,33 +6,32 @@ import Portal from 'components/Portal'; import Modal from 'components/Modal'; import StyledWrapper from './StyledWrapper'; -const AppModeModal = ({ collection, onClose }) => { +const JsSandboxModeModal = ({ collection, onClose }) => { const dispatch = useDispatch(); - const [selectedAppMode, setSelectedAppMode] = useState(collection?.securityConfig?.appMode || 'developer'); + const [jsSandboxMode, setJsSandboxMode] = useState(collection?.securityConfig?.jsSandboxMode || 'safe'); - const handleAppModeChange = (e) => { - setSelectedAppMode(e.target.value); + const handleChange = (e) => { + setJsSandboxMode(e.target.value); }; const handleSave = () => { dispatch( saveCollectionSecurityConfig(collection?.uid, { - appMode: selectedAppMode, - runtime: selectedAppMode === 'developer' ? 'vm2' : selectedAppMode === 'safe' ? 'isolated-vm' : undefined + jsSandboxMode: jsSandboxMode }) ) .then(() => { - toast.success('App Mode updated successfully'); + toast.success('Sandbox mode updated successfully'); onClose(); }) - .catch((err) => console.log(err) && toast.error('Failed to update JS AppMode')); + .catch((err) => console.log(err) && toast.error('Failed to update sandbox mode')); }; return ( { - + Safe Mode BETA @@ -73,13 +72,13 @@ const AppModeModal = ({ collection, onClose }) => { - + Developer Mode (use only if you trust the collections authors) @@ -97,4 +96,4 @@ const AppModeModal = ({ collection, onClose }) => { ); }; -export default AppModeModal; +export default JsSandboxModeModal; diff --git a/packages/bruno-app/src/components/SecuritySettings/SecurityIconWithModal/index.js b/packages/bruno-app/src/components/SecuritySettings/SecurityIconWithModal/index.js deleted file mode 100644 index 12251aa78..000000000 --- a/packages/bruno-app/src/components/SecuritySettings/SecurityIconWithModal/index.js +++ /dev/null @@ -1,35 +0,0 @@ -import { setShowAppModeModal } from 'providers/ReduxStore/slices/collections/index'; -import { useDispatch } from 'react-redux'; -import { IconShieldLock } from '@tabler/icons'; -import { addTab } from 'providers/ReduxStore/slices/tabs'; -import { uuid } from 'utils/common/index'; -import AppModeModal from './AppModeModal/index'; - -const SecuritySettingsIcon = ({ collection }) => { - const showAppModeModel = collection?.showAppModeModal; - const dispatch = useDispatch(); - - const viewSecuritySettings = () => { - dispatch( - addTab({ - uid: uuid(), - collectionUid: collection.uid, - type: 'security-settings' - }) - ); - }; - - return ( - <> - - {showAppModeModel ? ( - dispatch(setShowAppModeModal({ showAppModeModal: false, collectionUid: collection?.uid }))} - /> - ) : null} - - ); -}; - -export default SecuritySettingsIcon; diff --git a/packages/bruno-app/src/components/SecuritySettings/index.js b/packages/bruno-app/src/components/SecuritySettings/index.js index 587db0996..f83d2b69a 100644 --- a/packages/bruno-app/src/components/SecuritySettings/index.js +++ b/packages/bruno-app/src/components/SecuritySettings/index.js @@ -1,33 +1,32 @@ import { useState } from 'react'; import { saveCollectionSecurityConfig } from 'providers/ReduxStore/slices/collections/actions'; -import classnames from 'classnames'; +import toast from 'react-hot-toast'; import StyledWrapper from './StyledWrapper'; import { useDispatch } from 'react-redux'; const SecuritySettings = ({ collection }) => { const dispatch = useDispatch(); - const [selectedAppMode, setSelectedAppMode] = useState(collection?.securityConfig?.appMode || 'developer'); + const [jsSandboxMode, setJsSandboxMode] = useState(collection?.securityConfig?.jsSandboxMode || 'safe'); - const handleAppModeChange = (e) => { - setSelectedAppMode(e.target.value); + const handleChange = (e) => { + setJsSandboxMode(e.target.value); }; const handleSave = () => { dispatch( saveCollectionSecurityConfig(collection?.uid, { - appMode: selectedAppMode, - runtime: selectedAppMode === 'developer' ? 'vm2' : selectedAppMode === 'safe' ? 'isolated-vm' : undefined + jsSandboxMode: jsSandboxMode }) ) .then(() => { - toast.success('App Mode updated successfully'); + toast.success('Sandbox mode updated successfully'); }) - .catch((err) => console.log(err) && toast.error('Failed to update JS AppMode')); + .catch((err) => console.log(err) && toast.error('Failed to update sandbox mode')); }; return ( -
Scripting Sandbox
+
JavaScript Sandbox
The collection might include JavaScript code in Variables, Scripts, Tests, and Assertions. @@ -39,13 +38,13 @@ const SecuritySettings = ({ collection }) => { - + Safe Mode BETA @@ -58,13 +57,13 @@ const SecuritySettings = ({ collection }) => { - + Developer Mode (use only if you trust the collections authors) @@ -76,6 +75,9 @@ const SecuritySettings = ({ collection }) => { + + * SAFE mode has been introduced v1.25 onwards and is in beta. Please report any issues on github. +
); 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 85eb5e99f..ca66ac2ea 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js @@ -33,9 +33,6 @@ export const collectionsSlice = createSlice({ const collection = action.payload; collection.settingsSelectedTab = 'headers'; - - collection.showAppModeModal = !collection?.securityConfig?.appMode; - collection.folderLevelSettingsSelectedTab = {}; // TODO: move this to use the nextAction approach @@ -53,10 +50,6 @@ export const collectionsSlice = createSlice({ state.collections.push(collection); } }, - setShowAppModeModal: (state, action) => { - const collection = findCollectionByUid(state.collections, action.payload.collectionUid); - collection.showAppModeModal = action.payload.showAppModeModal; - }, setCollectionSecurityConfig: (state, action) => { const collection = findCollectionByUid(state.collections, action.payload.collectionUid); if (collection) { @@ -1718,8 +1711,7 @@ export const { runRequestEvent, runFolderEvent, resetCollectionRunner, - updateRequestDocs, - setShowAppModeModal + updateRequestDocs } = collectionsSlice.actions; export default collectionsSlice.reducer; diff --git a/packages/bruno-electron/src/ipc/collection.js b/packages/bruno-electron/src/ipc/collection.js index 582812f94..82453ec66 100644 --- a/packages/bruno-electron/src/ipc/collection.js +++ b/packages/bruno-electron/src/ipc/collection.js @@ -670,7 +670,9 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection ipcMain.handle('renderer:save-collection-security-config', async (event, collectionPath, securityConfig) => { try { - collectionSecurityStore.setSecurityConfigForCollection(collectionPath, securityConfig); + collectionSecurityStore.setSecurityConfigForCollection(collectionPath, { + jsSandboxMode: securityConfig.jsSandboxMode + }); } 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 972cf52d9..53d3a6afd 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -81,6 +81,11 @@ const getEnvVars = (environment = {}) => { }; }; +const getJsSandboxRuntime = (collection) => { + const securityConfig = get(collection, 'securityConfig', {}); + return securityConfig.jsSandboxMode === 'safe' ? 'isolated-vm' : 'vm2'; +}; + const protocolRegex = /^([-+\w]{1,25})(:?\/\/|:)/; const configureRequest = async ( @@ -459,7 +464,8 @@ const registerNetworkIpc = (mainWindow) => { const envVars = getEnvVars(environment); const processEnvVars = getProcessEnvVars(collectionUid); const brunoConfig = getBrunoConfig(collectionUid); - const scriptingConfig = { ...get(brunoConfig, 'scripts', {}), ...get(collection, 'securityConfig', {}) }; + const scriptingConfig = get(brunoConfig, 'scripts', {}); + scriptingConfig.runtime = getJsSandboxRuntime(collection); try { const controller = new AbortController(); @@ -660,7 +666,8 @@ const registerNetworkIpc = (mainWindow) => { const envVars = getEnvVars(environment); const processEnvVars = getProcessEnvVars(collectionUid); const brunoConfig = getBrunoConfig(collectionUid); - const scriptingConfig = { ...get(brunoConfig, 'scripts', {}), ...get(collection, 'securityConfig', {}) }; + const scriptingConfig = get(brunoConfig, 'scripts', {}); + scriptingConfig.runtime = getJsSandboxRuntime(collection); await runPreRequest( request, @@ -765,7 +772,8 @@ const registerNetworkIpc = (mainWindow) => { const runtimeVariables = collection.runtimeVariables; const processEnvVars = getProcessEnvVars(collectionUid); const brunoConfig = getBrunoConfig(collection.uid); - const scriptingConfig = { ...get(brunoConfig, 'scripts', {}), ...get(collection, 'securityConfig', {}) }; + const scriptingConfig = get(brunoConfig, 'scripts', {}); + scriptingConfig.runtime = getJsSandboxRuntime(collection); await runPreRequest( request, @@ -831,7 +839,8 @@ const registerNetworkIpc = (mainWindow) => { const folderUid = folder ? folder.uid : null; const cancelTokenUid = uuid(); const brunoConfig = getBrunoConfig(collectionUid); - const scriptingConfig = { ...get(brunoConfig, 'scripts', {}), ...get(collection, 'securityConfig', {}) }; + const scriptingConfig = get(brunoConfig, 'scripts', {}); + scriptingConfig.runtime = getJsSandboxRuntime(collection); const collectionRoot = get(collection, 'root', {}); const abortController = new AbortController(); diff --git a/packages/bruno-electron/src/store/collection-security.js b/packages/bruno-electron/src/store/collection-security.js index 07a572ca6..5873c629a 100644 --- a/packages/bruno-electron/src/store/collection-security.js +++ b/packages/bruno-electron/src/store/collection-security.js @@ -16,7 +16,9 @@ class CollectionSecurityStore { if (!collection) { collections.push({ path: collectionPathname, - securityConfig + securityConfig: { + jsSandboxMode: securityConfig.jsSandboxMode + } }); this.store.set('collections', collections); 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 90% rename from packages/bruno-js/src/sandbox/isolatedvm/utils/bundleLibraries.js rename to packages/bruno-js/src/sandbox/isolatedvm/utils/bundle-libraries.js index 194742ca0..f909ec405 100644 --- a/packages/bruno-js/src/sandbox/isolatedvm/utils/bundleLibraries.js +++ b/packages/bruno-js/src/sandbox/isolatedvm/utils/bundle-libraries.js @@ -6,9 +6,6 @@ const { terser } = require('rollup-plugin-terser'); const bundleLibraries = async () => { const codeScript = ` - import isNumber from "is-number"; - global.isNumber = isNumber; - import { faker } from "@faker-js/faker"; import { expect, assert } from 'chai'; import { Buffer } from "buffer"; import moment from "moment"; @@ -16,15 +13,12 @@ const bundleLibraries = async () => { import atob from "atob"; global.expect = expect; global.assert = assert; - global.faker = faker; global.moment = moment; global.btoa = btoa; global.atob = atob; global.Buffer = Buffer; global.requireObject = { 'chai': { expect, assert }, - 'faker': faker, - '@faker-js/faker': { faker }, 'moment': moment, 'buffer': { Buffer }, 'btoa': btoa,