mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-22 07:53:34 +01:00
#224 refactor preferences store, add global proxy settings
This commit is contained in:
parent
159dd90b03
commit
b854e66a24
82
package-lock.json
generated
82
package-lock.json
generated
@ -13507,8 +13507,7 @@
|
||||
"node_modules/react-is": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
},
|
||||
"node_modules/react-redux": {
|
||||
"version": "7.2.9",
|
||||
@ -16647,7 +16646,7 @@
|
||||
},
|
||||
"packages/bruno-cli": {
|
||||
"name": "@usebruno/cli",
|
||||
"version": "0.12.0",
|
||||
"version": "0.13.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@usebruno/js": "0.8.0",
|
||||
@ -16730,7 +16729,7 @@
|
||||
},
|
||||
"packages/bruno-electron": {
|
||||
"name": "bruno",
|
||||
"version": "v0.20.0",
|
||||
"version": "v0.21.1",
|
||||
"dependencies": {
|
||||
"@usebruno/js": "0.8.0",
|
||||
"@usebruno/lang": "0.5.0",
|
||||
@ -19496,7 +19495,8 @@
|
||||
"@tabler/icons": {
|
||||
"version": "1.119.0",
|
||||
"resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-1.119.0.tgz",
|
||||
"integrity": "sha512-Fk3Qq4w2SXcTjc/n1cuL5bccPkylrOMo7cYpQIf/yw6zP76LQV9dtLcHQUjFiUnaYuswR645CnURIhlafyAh9g=="
|
||||
"integrity": "sha512-Fk3Qq4w2SXcTjc/n1cuL5bccPkylrOMo7cYpQIf/yw6zP76LQV9dtLcHQUjFiUnaYuswR645CnURIhlafyAh9g==",
|
||||
"requires": {}
|
||||
},
|
||||
"@tauri-apps/cli": {
|
||||
"version": "1.2.2",
|
||||
@ -20117,7 +20117,8 @@
|
||||
}
|
||||
},
|
||||
"@usebruno/schema": {
|
||||
"version": "file:packages/bruno-schema"
|
||||
"version": "file:packages/bruno-schema",
|
||||
"requires": {}
|
||||
},
|
||||
"@usebruno/testbench": {
|
||||
"version": "file:packages/bruno-testbench",
|
||||
@ -20293,7 +20294,8 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz",
|
||||
"integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"@webpack-cli/info": {
|
||||
"version": "1.5.0",
|
||||
@ -20308,7 +20310,8 @@
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz",
|
||||
"integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"@xtuc/ieee754": {
|
||||
"version": "1.2.0",
|
||||
@ -20413,7 +20416,8 @@
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
|
||||
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"amdefine": {
|
||||
"version": "0.0.8",
|
||||
@ -22011,7 +22015,8 @@
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz",
|
||||
"integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"css-loader": {
|
||||
"version": "6.7.3",
|
||||
@ -22156,7 +22161,8 @@
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz",
|
||||
"integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"csso": {
|
||||
"version": "4.2.0",
|
||||
@ -23617,7 +23623,8 @@
|
||||
"goober": {
|
||||
"version": "2.1.11",
|
||||
"resolved": "https://registry.npmjs.org/goober/-/goober-2.1.11.tgz",
|
||||
"integrity": "sha512-5SS2lmxbhqH0u9ABEWq7WPU69a4i2pYcHeCxqaNq6Cw3mnrF0ghWNM4tEGid4dKy8XNIAUbuThuozDHHKJVh3A=="
|
||||
"integrity": "sha512-5SS2lmxbhqH0u9ABEWq7WPU69a4i2pYcHeCxqaNq6Cw3mnrF0ghWNM4tEGid4dKy8XNIAUbuThuozDHHKJVh3A==",
|
||||
"requires": {}
|
||||
},
|
||||
"got": {
|
||||
"version": "9.6.0",
|
||||
@ -24090,7 +24097,8 @@
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
|
||||
"integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"idb": {
|
||||
"version": "7.1.1",
|
||||
@ -24869,7 +24877,8 @@
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
|
||||
"integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"jest-regex-util": {
|
||||
"version": "29.2.0",
|
||||
@ -25631,7 +25640,8 @@
|
||||
"meros": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/meros/-/meros-1.2.1.tgz",
|
||||
"integrity": "sha512-R2f/jxYqCAGI19KhAvaxSOxALBMkaXWH2a7rOyqQw+ZmizX5bKkEYWLzdhC+U82ZVVPVp6MCXe3EkVligh+12g=="
|
||||
"integrity": "sha512-R2f/jxYqCAGI19KhAvaxSOxALBMkaXWH2a7rOyqQw+ZmizX5bKkEYWLzdhC+U82ZVVPVp6MCXe3EkVligh+12g==",
|
||||
"requires": {}
|
||||
},
|
||||
"methods": {
|
||||
"version": "1.1.2",
|
||||
@ -26661,25 +26671,29 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz",
|
||||
"integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"postcss-discard-duplicates": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz",
|
||||
"integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"postcss-discard-empty": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz",
|
||||
"integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"postcss-discard-overridden": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz",
|
||||
"integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"postcss-js": {
|
||||
"version": "3.0.3",
|
||||
@ -26781,7 +26795,8 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
|
||||
"integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"postcss-modules-local-by-default": {
|
||||
"version": "4.0.0",
|
||||
@ -26824,7 +26839,8 @@
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz",
|
||||
"integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"postcss-normalize-display-values": {
|
||||
"version": "5.1.0",
|
||||
@ -27345,13 +27361,13 @@
|
||||
"react-inspector": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.2.tgz",
|
||||
"integrity": "sha512-x+b7LxhmHXjHoU/VrFAzw5iutsILRoYyDq97EDYdFpPLcvqtEzk4ZSZSQjnFPbr5T57tLXnHcqFYoN1pI6u8uQ=="
|
||||
"integrity": "sha512-x+b7LxhmHXjHoU/VrFAzw5iutsILRoYyDq97EDYdFpPLcvqtEzk4ZSZSQjnFPbr5T57tLXnHcqFYoN1pI6u8uQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"react-is": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
},
|
||||
"react-redux": {
|
||||
"version": "7.2.9",
|
||||
@ -27538,7 +27554,8 @@
|
||||
"redux-thunk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
|
||||
"integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q=="
|
||||
"integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
|
||||
"requires": {}
|
||||
},
|
||||
"regenerate": {
|
||||
"version": "1.4.2",
|
||||
@ -27840,7 +27857,8 @@
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/rollup-plugin-peer-deps-external/-/rollup-plugin-peer-deps-external-2.2.4.tgz",
|
||||
"integrity": "sha512-AWdukIM1+k5JDdAqV/Cxd+nejvno2FVLVeZ74NKggm3Q5s9cbbcOgUPGdbxPi4BXu7xGaZ8HG12F+thImYu/0g==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"rollup-plugin-postcss": {
|
||||
"version": "4.0.2",
|
||||
@ -28453,7 +28471,8 @@
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz",
|
||||
"integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"styled-components": {
|
||||
"version": "5.3.6",
|
||||
@ -28490,7 +28509,8 @@
|
||||
"styled-jsx": {
|
||||
"version": "5.0.7",
|
||||
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.7.tgz",
|
||||
"integrity": "sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA=="
|
||||
"integrity": "sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA==",
|
||||
"requires": {}
|
||||
},
|
||||
"stylehacks": {
|
||||
"version": "5.1.1",
|
||||
@ -29228,7 +29248,8 @@
|
||||
"use-sync-external-store": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
|
||||
"integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA=="
|
||||
"integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
|
||||
"requires": {}
|
||||
},
|
||||
"utf8-byte-length": {
|
||||
"version": "1.0.4",
|
||||
@ -29441,7 +29462,8 @@
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
|
||||
"integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"schema-utils": {
|
||||
"version": "3.1.1",
|
||||
|
@ -7,7 +7,7 @@ import StyledWrapper from './StyledWrapper';
|
||||
const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
enabled: proxyConfig.enabled || false,
|
||||
enabled: proxyConfig.enabled || 'global',
|
||||
protocol: proxyConfig.protocol || 'http',
|
||||
hostname: proxyConfig.hostname || '',
|
||||
port: proxyConfig.port || '',
|
||||
@ -15,18 +15,20 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
enabled: proxyConfig.auth ? proxyConfig.auth.enabled || false : false,
|
||||
username: proxyConfig.auth ? proxyConfig.auth.username || '' : '',
|
||||
password: proxyConfig.auth ? proxyConfig.auth.password || '' : ''
|
||||
}
|
||||
},
|
||||
noProxy: proxyConfig.noProxy || ''
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
enabled: Yup.boolean(),
|
||||
protocol: Yup.string().oneOf(['http', 'https']),
|
||||
enabled: Yup.string().oneOf(['global', 'enabled', 'disabled']),
|
||||
protocol: Yup.string().oneOf(['http', 'https', 'socks5']),
|
||||
hostname: Yup.string().max(1024),
|
||||
port: Yup.number().min(0).max(65535),
|
||||
auth: Yup.object({
|
||||
enabled: Yup.boolean(),
|
||||
username: Yup.string().max(1024),
|
||||
password: Yup.string().max(1024)
|
||||
})
|
||||
}),
|
||||
noProxy: Yup.string().max(1024)
|
||||
}),
|
||||
onSubmit: (values) => {
|
||||
onUpdate(values);
|
||||
@ -35,7 +37,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
|
||||
useEffect(() => {
|
||||
formik.setValues({
|
||||
enabled: proxyConfig.enabled || false,
|
||||
enabled: proxyConfig.enabled || 'global',
|
||||
protocol: proxyConfig.protocol || 'http',
|
||||
hostname: proxyConfig.hostname || '',
|
||||
port: proxyConfig.port || '',
|
||||
@ -43,7 +45,8 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
enabled: proxyConfig.auth ? proxyConfig.auth.enabled || false : false,
|
||||
username: proxyConfig.auth ? proxyConfig.auth.username || '' : '',
|
||||
password: proxyConfig.auth ? proxyConfig.auth.password || '' : ''
|
||||
}
|
||||
},
|
||||
noProxy: proxyConfig.noProxy || ''
|
||||
});
|
||||
}, [proxyConfig]);
|
||||
|
||||
@ -53,16 +56,50 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
<form className="bruno-form" onSubmit={formik.handleSubmit}>
|
||||
<div className="ml-4 mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="enabled">
|
||||
Enabled
|
||||
Usage
|
||||
</label>
|
||||
<input type="checkbox" name="enabled" checked={formik.values.enabled} onChange={formik.handleChange} />
|
||||
<div className="flex items-center">
|
||||
<label className="flex items-center">
|
||||
<input
|
||||
type="radio"
|
||||
name="enabled"
|
||||
value="global"
|
||||
checked={formik.values.enabled === 'global'}
|
||||
onChange={formik.handleChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
use global settings
|
||||
</label>
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="enabled"
|
||||
value="enabled"
|
||||
checked={formik.values.enabled === 'enabled'}
|
||||
onChange={formik.handleChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
enabled
|
||||
</label>
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="enabled"
|
||||
value="disabled"
|
||||
checked={formik.values.enabled === 'disabled'}
|
||||
onChange={formik.handleChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
disabled
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="ml-4 mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="protocol">
|
||||
Protocol
|
||||
</label>
|
||||
<div className="flex items-center">
|
||||
<label className="flex items-center mr-4">
|
||||
<label className="flex items-center">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
@ -73,7 +110,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
/>
|
||||
http
|
||||
</label>
|
||||
<label className="flex items-center">
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
@ -84,6 +121,17 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
/>
|
||||
https
|
||||
</label>
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
value="socks5"
|
||||
checked={formik.values.protocol === 'socks5'}
|
||||
onChange={formik.handleChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
socks5
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="ml-4 mb-3 flex items-center">
|
||||
@ -177,6 +225,26 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className="ml-4 mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="noProxy">
|
||||
Proxy Bypass
|
||||
</label>
|
||||
<input
|
||||
id="noProxy"
|
||||
type="text"
|
||||
name="noProxy"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
onChange={formik.handleChange}
|
||||
value={formik.values.noProxy || ''}
|
||||
/>
|
||||
{formik.touched.noProxy && formik.errors.noProxy ? (
|
||||
<div className="text-red-500">{formik.errors.noProxy}</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="mt-6">
|
||||
<button type="submit" className="submit btn btn-md btn-secondary">
|
||||
Save
|
||||
|
@ -17,7 +17,7 @@ const CollectionSettings = ({ collection }) => {
|
||||
brunoConfig.proxy = config;
|
||||
dispatch(updateBrunoConfig(brunoConfig, collection.uid))
|
||||
.then(() => {
|
||||
toast.success('Collection settings updated successfully');
|
||||
toast.success('Collection settings updated successfully.');
|
||||
})
|
||||
.catch((err) => console.log(err) && toast.error('Failed to update collection settings'));
|
||||
};
|
||||
|
@ -1,24 +1,26 @@
|
||||
import React, { useState } from 'react';
|
||||
import { usePreferences } from 'providers/Preferences';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
const General = () => {
|
||||
const { preferences, setPreferences } = usePreferences();
|
||||
|
||||
const [sslVerification, setSslVerification] = useState(preferences.request.sslVerification);
|
||||
const [tlsVerification, setTlsVerification] = useState(preferences.request.tlsVerification);
|
||||
|
||||
const handleCheckboxChange = () => {
|
||||
const updatedPreferences = {
|
||||
...preferences,
|
||||
request: {
|
||||
...preferences.request,
|
||||
sslVerification: !sslVerification
|
||||
tlsVerification: !tlsVerification
|
||||
}
|
||||
};
|
||||
|
||||
setPreferences(updatedPreferences)
|
||||
.then(() => {
|
||||
setSslVerification(!sslVerification);
|
||||
setTlsVerification(!tlsVerification);
|
||||
toast.success('Request settings saved successful.');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
@ -28,8 +30,8 @@ const General = () => {
|
||||
return (
|
||||
<StyledWrapper>
|
||||
<div className="flex items-center mt-2">
|
||||
<input type="checkbox" checked={sslVerification} onChange={handleCheckboxChange} className="mr-3 mousetrap" />
|
||||
SSL Certificate Verification
|
||||
<input type="checkbox" checked={tlsVerification} onChange={handleCheckboxChange} className="mr-3 mousetrap" />
|
||||
TLS Certificate Verification
|
||||
</div>
|
||||
</StyledWrapper>
|
||||
);
|
||||
|
@ -0,0 +1,25 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
.settings-label {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.textbox {
|
||||
border: 1px solid #ccc;
|
||||
padding: 0.15rem 0.45rem;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
transition: border-color ease-in-out 0.1s;
|
||||
border-radius: 3px;
|
||||
background-color: ${(props) => props.theme.modal.input.bg};
|
||||
border: 1px solid ${(props) => props.theme.modal.input.border};
|
||||
|
||||
&:focus {
|
||||
border: solid 1px ${(props) => props.theme.modal.input.focusBorder} !important;
|
||||
outline: none !important;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default StyledWrapper;
|
@ -0,0 +1,243 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useFormik } from 'formik';
|
||||
import * as Yup from 'yup';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { usePreferences } from 'providers/Preferences';
|
||||
|
||||
const ProxySettings = () => {
|
||||
const { preferences, setPreferences } = usePreferences();
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
enabled: preferences.proxy.enabled || false,
|
||||
protocol: preferences.proxy.protocol || 'http',
|
||||
hostname: preferences.proxy.hostname || '',
|
||||
port: preferences.proxy.port || 0,
|
||||
auth: {
|
||||
enabled: preferences.proxy.auth ? preferences.proxy.auth.enabled || false : false,
|
||||
username: preferences.proxy.auth ? preferences.proxy.auth.username || '' : '',
|
||||
password: preferences.proxy.auth ? preferences.proxy.auth.password || '' : ''
|
||||
},
|
||||
noProxy: preferences.proxy.noProxy || ''
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
enabled: Yup.boolean(),
|
||||
protocol: Yup.string().oneOf(['http', 'https', 'socks5']),
|
||||
hostname: Yup.string().max(1024),
|
||||
port: Yup.number().min(0).max(65535),
|
||||
auth: Yup.object({
|
||||
enabled: Yup.boolean(),
|
||||
username: Yup.string().max(1024),
|
||||
password: Yup.string().max(1024)
|
||||
}),
|
||||
noProxy: Yup.string().max(1024)
|
||||
}),
|
||||
onSubmit: (values) => {
|
||||
onUpdate(values);
|
||||
}
|
||||
});
|
||||
|
||||
const onUpdate = (values) => {
|
||||
const updatedPreferences = {
|
||||
...preferences,
|
||||
proxy: values
|
||||
};
|
||||
|
||||
setPreferences(updatedPreferences)
|
||||
.then(() => {
|
||||
toast.success('Proxy settings updated successfully.');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
formik.setValues({
|
||||
enabled: preferences.proxy.enabled || false,
|
||||
protocol: preferences.proxy.protocol || 'http',
|
||||
hostname: preferences.proxy.hostname || '',
|
||||
port: preferences.proxy.port || '',
|
||||
auth: {
|
||||
enabled: preferences.proxy.auth ? preferences.proxy.auth.enabled || false : false,
|
||||
username: preferences.proxy.auth ? preferences.proxy.auth.username || '' : '',
|
||||
password: preferences.proxy.auth ? preferences.proxy.auth.password || '' : ''
|
||||
},
|
||||
noProxy: preferences.proxy.noProxy || ''
|
||||
});
|
||||
}, [preferences]);
|
||||
|
||||
return (
|
||||
<StyledWrapper>
|
||||
<h1 className="font-medium mb-3">Proxy Settings</h1>
|
||||
<form className="bruno-form" onSubmit={formik.handleSubmit}>
|
||||
<div className="ml-4 mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="enabled">
|
||||
Enabled
|
||||
</label>
|
||||
<input type="checkbox" name="enabled" checked={formik.values.enabled} onChange={formik.handleChange} />
|
||||
</div>
|
||||
<div className="ml-4 mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="protocol">
|
||||
Protocol
|
||||
</label>
|
||||
<div className="flex items-center">
|
||||
<label className="flex items-center">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
value="http"
|
||||
checked={formik.values.protocol === 'http'}
|
||||
onChange={formik.handleChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
http
|
||||
</label>
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
value="https"
|
||||
checked={formik.values.protocol === 'https'}
|
||||
onChange={formik.handleChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
https
|
||||
</label>
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
value="socks5"
|
||||
checked={formik.values.protocol === 'socks5'}
|
||||
onChange={formik.handleChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
socks5
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="ml-4 mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="hostname">
|
||||
Hostname
|
||||
</label>
|
||||
<input
|
||||
id="hostname"
|
||||
type="text"
|
||||
name="hostname"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
onChange={formik.handleChange}
|
||||
value={formik.values.hostname || ''}
|
||||
/>
|
||||
{formik.touched.hostname && formik.errors.hostname ? (
|
||||
<div className="text-red-500">{formik.errors.hostname}</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="ml-4 mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="port">
|
||||
Port
|
||||
</label>
|
||||
<input
|
||||
id="port"
|
||||
type="number"
|
||||
name="port"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
onChange={formik.handleChange}
|
||||
value={formik.values.port}
|
||||
/>
|
||||
{formik.touched.port && formik.errors.port ? <div className="text-red-500">{formik.errors.port}</div> : null}
|
||||
</div>
|
||||
<div className="ml-4 mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="auth.enabled">
|
||||
Auth
|
||||
</label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="auth.enabled"
|
||||
checked={formik.values.auth.enabled}
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className="ml-4 mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="auth.username">
|
||||
Username
|
||||
</label>
|
||||
<input
|
||||
id="auth.username"
|
||||
type="text"
|
||||
name="auth.username"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
value={formik.values.auth.username}
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
{formik.touched.auth?.username && formik.errors.auth?.username ? (
|
||||
<div className="text-red-500">{formik.errors.auth.username}</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="ml-4 mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="auth.password">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
id="auth.password"
|
||||
type="text"
|
||||
name="auth.password"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
value={formik.values.auth.password}
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
{formik.touched.auth?.password && formik.errors.auth?.password ? (
|
||||
<div className="text-red-500">{formik.errors.auth.password}</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className="ml-4 mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="noProxy">
|
||||
Proxy Bypass
|
||||
</label>
|
||||
<input
|
||||
id="noProxy"
|
||||
type="text"
|
||||
name="noProxy"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
onChange={formik.handleChange}
|
||||
value={formik.values.noProxy || ''}
|
||||
/>
|
||||
{formik.touched.noProxy && formik.errors.noProxy ? (
|
||||
<div className="text-red-500">{formik.errors.noProxy}</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="mt-6">
|
||||
<button type="submit" className="submit btn btn-md btn-secondary">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProxySettings;
|
@ -4,6 +4,7 @@ import React, { useState } from 'react';
|
||||
import Support from './Support';
|
||||
import General from './General';
|
||||
import Theme from './Theme';
|
||||
import Proxy from './ProxySettings';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const Preferences = ({ onClose }) => {
|
||||
@ -21,6 +22,10 @@ const Preferences = ({ onClose }) => {
|
||||
return <General />;
|
||||
}
|
||||
|
||||
case 'proxy': {
|
||||
return <Proxy />;
|
||||
}
|
||||
|
||||
case 'theme': {
|
||||
return <Theme />;
|
||||
}
|
||||
@ -41,6 +46,9 @@ const Preferences = ({ onClose }) => {
|
||||
<div className={getTabClassname('theme')} role="tab" onClick={() => setTab('theme')}>
|
||||
Theme
|
||||
</div>
|
||||
<div className={getTabClassname('proxy')} role="tab" onClick={() => setTab('proxy')}>
|
||||
Proxy
|
||||
</div>
|
||||
<div className={getTabClassname('support')} role="tab" onClick={() => setTab('support')}>
|
||||
Support
|
||||
</div>
|
||||
|
@ -1,6 +1,12 @@
|
||||
import React from 'react';
|
||||
import { IconSend } from '@tabler/icons';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { isMacOS } from 'utils/common/platform';
|
||||
|
||||
const isMac = isMacOS();
|
||||
const sendShortcut = isMac ? 'Cmd + Enter' : 'Ctrl + Enter';
|
||||
const newShortcut = isMac ? 'Cmd + B' : 'Ctrl + B';
|
||||
const editEnvShortcut = isMac ? 'Cmd + E' : 'Ctrl + E';
|
||||
|
||||
const Placeholder = () => {
|
||||
return (
|
||||
@ -15,9 +21,9 @@ const Placeholder = () => {
|
||||
<div className="px-1 py-2">Edit Environments</div>
|
||||
</div>
|
||||
<div className="flex flex-1 flex-col px-1">
|
||||
<div className="px-1 py-2">Cmd + Enter</div>
|
||||
<div className="px-1 py-2">Cmd + B</div>
|
||||
<div className="px-1 py-2">Cmd + E</div>
|
||||
<div className="px-1 py-2">{sendShortcut}</div>
|
||||
<div className="px-1 py-2">{newShortcut}</div>
|
||||
<div className="px-1 py-2">{editEnvShortcut}</div>
|
||||
</div>
|
||||
</div>
|
||||
</StyledWrapper>
|
||||
|
@ -82,7 +82,7 @@ const useCollectionTreeSync = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const _collectionAlreadyOpened = (pathname) => {
|
||||
const _collectionAlreadyOpened = () => {
|
||||
toast.success('Collection is already opened');
|
||||
};
|
||||
|
||||
@ -115,7 +115,8 @@ const useCollectionTreeSync = () => {
|
||||
dispatch(runRequestEvent(val));
|
||||
};
|
||||
|
||||
ipcRenderer.invoke('renderer:ready');
|
||||
ipcRenderer.invoke('renderer:ready-application');
|
||||
ipcRenderer.invoke('renderer:ready-collection');
|
||||
|
||||
const removeListener1 = ipcRenderer.on('main:collection-opened', _openCollection);
|
||||
const removeListener2 = ipcRenderer.on('main:collection-tree-updated', _collectionTreeUpdated);
|
||||
|
@ -7,32 +7,64 @@
|
||||
* On start, an IPC event is published to the main process to set the preferences in the electron process.
|
||||
*/
|
||||
|
||||
import { useEffect, createContext, useContext } from 'react';
|
||||
import { useEffect, createContext, useContext, useMemo } from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import useLocalStorage from 'hooks/useLocalStorage/index';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
const defaultPreferences = {
|
||||
request: {
|
||||
sslVerification: true
|
||||
}
|
||||
};
|
||||
|
||||
const preferencesSchema = Yup.object().shape({
|
||||
request: Yup.object().shape({
|
||||
sslVerification: Yup.boolean()
|
||||
const preferencesSchema = Yup.object({
|
||||
request: Yup.object({
|
||||
sslVerification: Yup.boolean(),
|
||||
caCert: Yup.string().max(1024)
|
||||
}),
|
||||
proxy: Yup.object({
|
||||
enabled: Yup.boolean(),
|
||||
protocol: Yup.string().oneOf(['http', 'https', 'socks5']),
|
||||
hostname: Yup.string().max(1024),
|
||||
port: Yup.number().min(0).max(65535),
|
||||
auth: Yup.object({
|
||||
enabled: Yup.boolean(),
|
||||
username: Yup.string().max(1024),
|
||||
password: Yup.string().max(1024)
|
||||
}),
|
||||
noProxy: Yup.string().max(1024)
|
||||
})
|
||||
});
|
||||
|
||||
export const PreferencesContext = createContext();
|
||||
export const PreferencesProvider = (props) => {
|
||||
const [preferences, setPreferences] = useLocalStorage('bruno.preferences', defaultPreferences);
|
||||
// TODO: Remove migration later
|
||||
const [localStorePreferences] = useLocalStorage('bruno.preferences');
|
||||
|
||||
const preferences = {};
|
||||
const { ipcRenderer } = window;
|
||||
|
||||
useEffect(() => {
|
||||
ipcRenderer.invoke('renderer:set-preferences', preferences).catch((err) => {
|
||||
// TODO: Remove migration later
|
||||
if (localStorePreferences?.request) {
|
||||
console.log('migrate prefs from localStorage ' + JSON.stringify(localStorePreferences));
|
||||
ipcRenderer
|
||||
.invoke('renderer:migrate-preferences', localStorePreferences.request.sslVerification)
|
||||
.then(() => {
|
||||
localStorage.removeItem('bruno.preferences');
|
||||
})
|
||||
.catch((err) => {
|
||||
toast.error(err.message || 'Preferences sync error');
|
||||
});
|
||||
}
|
||||
|
||||
const removeListener = ipcRenderer.on('main:preferences-read', (currentPreferences) => {
|
||||
if (currentPreferences.request) {
|
||||
preferences.request = currentPreferences.request;
|
||||
}
|
||||
if (currentPreferences.proxy) {
|
||||
preferences.proxy = currentPreferences.proxy;
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
removeListener();
|
||||
};
|
||||
}, [preferences, toast]);
|
||||
|
||||
const validatedSetPreferences = (newPreferences) => {
|
||||
@ -40,7 +72,15 @@ export const PreferencesProvider = (props) => {
|
||||
preferencesSchema
|
||||
.validate(newPreferences, { abortEarly: true })
|
||||
.then((validatedPreferences) => {
|
||||
setPreferences(validatedPreferences);
|
||||
ipcRenderer
|
||||
.invoke('renderer:set-preferences', validatedPreferences)
|
||||
.then(() => {
|
||||
preferences.request = validatedPreferences.request;
|
||||
preferences.proxy = validatedPreferences.proxy;
|
||||
})
|
||||
.catch((err) => {
|
||||
toast.error(err.message || 'Preferences sync error');
|
||||
});
|
||||
resolve(validatedPreferences);
|
||||
})
|
||||
.catch((error) => {
|
||||
@ -51,11 +91,13 @@ export const PreferencesProvider = (props) => {
|
||||
});
|
||||
};
|
||||
|
||||
// todo: setPreferences must validate the preferences object against a schema
|
||||
const value = {
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
preferences,
|
||||
setPreferences: validatedSetPreferences
|
||||
};
|
||||
}),
|
||||
[preferences, validatedSetPreferences]
|
||||
);
|
||||
|
||||
return (
|
||||
<PreferencesContext.Provider value={value}>
|
||||
|
@ -8,8 +8,10 @@ const menuTemplate = require('./app/menu-template');
|
||||
const LastOpenedCollections = require('./store/last-opened-collections');
|
||||
const registerNetworkIpc = require('./ipc/network');
|
||||
const registerCollectionsIpc = require('./ipc/collection');
|
||||
const registerApplicationIpc = require('./ipc/application');
|
||||
const Watcher = require('./app/watcher');
|
||||
const { loadWindowState, saveWindowState } = require('./utils/window');
|
||||
const preferences = require('./store/preferences');
|
||||
|
||||
const lastOpenedCollections = new LastOpenedCollections();
|
||||
|
||||
@ -68,8 +70,9 @@ app.on('ready', async () => {
|
||||
});
|
||||
|
||||
// register all ipc handlers
|
||||
registerNetworkIpc(mainWindow, watcher, lastOpenedCollections);
|
||||
registerNetworkIpc(mainWindow);
|
||||
registerCollectionsIpc(mainWindow, watcher, lastOpenedCollections);
|
||||
registerApplicationIpc(mainWindow, preferences);
|
||||
});
|
||||
|
||||
// Quit the app once all windows are closed
|
||||
|
72
packages/bruno-electron/src/ipc/application.js
Normal file
72
packages/bruno-electron/src/ipc/application.js
Normal file
@ -0,0 +1,72 @@
|
||||
const { ipcMain } = require('electron');
|
||||
const chokidar = require('chokidar');
|
||||
const stores = require('../store');
|
||||
|
||||
const registerApplicationIpc = (mainWindow, preferences) => {
|
||||
const change = async (pathname, store) => {
|
||||
if (store === stores.PREFERENCES) {
|
||||
mainWindow.webContents.send('main:preferences-read', preferences.getAll());
|
||||
}
|
||||
};
|
||||
|
||||
class StoreWatcher {
|
||||
constructor() {
|
||||
this.watchers = {};
|
||||
}
|
||||
|
||||
addWatcher(watchPath, store) {
|
||||
console.log(`watcher add: ${watchPath} for store ${store}`);
|
||||
|
||||
if (this.watchers[watchPath]) {
|
||||
this.watchers[watchPath].close();
|
||||
}
|
||||
|
||||
const self = this;
|
||||
setTimeout(() => {
|
||||
const watcher = chokidar.watch(watchPath, {
|
||||
ignoreInitial: false,
|
||||
usePolling: false,
|
||||
persistent: true,
|
||||
ignorePermissionErrors: true,
|
||||
awaitWriteFinish: {
|
||||
stabilityThreshold: 80,
|
||||
pollInterval: 10
|
||||
},
|
||||
depth: 20
|
||||
});
|
||||
|
||||
watcher.on('change', (pathname) => change(pathname, store));
|
||||
|
||||
self.watchers[watchPath] = watcher;
|
||||
}, 100);
|
||||
}
|
||||
|
||||
hasWatcher(watchPath) {
|
||||
return this.watchers[watchPath];
|
||||
}
|
||||
|
||||
removeWatcher(watchPath) {
|
||||
if (this.watchers[watchPath]) {
|
||||
this.watchers[watchPath].close();
|
||||
this.watchers[watchPath] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const storeWatcher = new StoreWatcher();
|
||||
storeWatcher.addWatcher(preferences.getPath(), stores.PREFERENCES);
|
||||
|
||||
ipcMain.handle('renderer:ready-application', async () => {
|
||||
mainWindow.webContents.send('main:preferences-read', preferences.getAll());
|
||||
});
|
||||
|
||||
ipcMain.handle('renderer:set-preferences', async (event, newPreferences) => {
|
||||
preferences.setPreferences(newPreferences);
|
||||
});
|
||||
|
||||
ipcMain.handle('renderer:migrate-preferences', async (event, sslVerification) => {
|
||||
preferences.migrateSslVerification(sslVerification);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = registerApplicationIpc;
|
@ -18,7 +18,6 @@ const { stringifyJson } = require('../utils/common');
|
||||
const { openCollectionDialog, openCollection } = require('../app/collections');
|
||||
const { generateUidBasedOnHash } = require('../utils/common');
|
||||
const { moveRequestUid, deleteRequestUid } = require('../cache/requestUids');
|
||||
const { setPreferences } = require('../store/preferences');
|
||||
const EnvironmentSecretsStore = require('../store/env-secrets');
|
||||
|
||||
const environmentSecretsStore = new EnvironmentSecretsStore();
|
||||
@ -33,9 +32,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
|
||||
// browse directory
|
||||
ipcMain.handle('renderer:browse-directory', async (event, pathname, request) => {
|
||||
try {
|
||||
const dirPath = await browseDirectory(mainWindow);
|
||||
|
||||
return dirPath;
|
||||
return await browseDirectory(mainWindow);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
@ -68,8 +65,6 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
|
||||
|
||||
mainWindow.webContents.send('main:collection-opened', dirPath, uid, brunoConfig);
|
||||
ipcMain.emit('main:collection-opened', mainWindow, dirPath, uid);
|
||||
|
||||
return;
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
@ -94,8 +89,6 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
|
||||
collectionPathname,
|
||||
newName
|
||||
});
|
||||
|
||||
return;
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
@ -315,7 +308,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
|
||||
|
||||
fs.unlinkSync(pathname);
|
||||
} else {
|
||||
return Promise.reject(error);
|
||||
return Promise.reject();
|
||||
}
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
@ -458,7 +451,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('renderer:ready', async (event) => {
|
||||
ipcMain.handle('renderer:ready-collection', async (event) => {
|
||||
// reload last opened collections
|
||||
const lastOpened = lastOpenedCollections.getAll();
|
||||
|
||||
@ -473,10 +466,6 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('renderer:set-preferences', async (event, preferences) => {
|
||||
setPreferences(preferences);
|
||||
});
|
||||
|
||||
ipcMain.handle('renderer:update-bruno-config', async (event, brunoConfig, collectionPath, collectionUid) => {
|
||||
try {
|
||||
const brunoConfigPath = path.join(collectionPath, 'bruno.json');
|
||||
|
@ -14,7 +14,7 @@ const { uuid } = require('../../utils/common');
|
||||
const interpolateVars = require('./interpolate-vars');
|
||||
const { interpolateString } = require('./interpolate-string');
|
||||
const { sortFolder, getAllRequestsInFolderRecursively } = require('./helper');
|
||||
const { getPreferences } = require('../../store/preferences');
|
||||
const { preferences } = require('../../store/preferences');
|
||||
const { getProcessEnvVars } = require('../../store/process-env');
|
||||
const { getBrunoConfig } = require('../../store/bruno-config');
|
||||
const { HttpsProxyAgent } = require('https-proxy-agent');
|
||||
@ -197,19 +197,16 @@ const registerNetworkIpc = (mainWindow) => {
|
||||
cancelTokenUid
|
||||
});
|
||||
|
||||
const preferences = getPreferences();
|
||||
const sslVerification = get(preferences, 'request.sslVerification', true);
|
||||
const httpsAgentRequestFields = {};
|
||||
if (!sslVerification) {
|
||||
if (!preferences.isTlsVerification()) {
|
||||
httpsAgentRequestFields['rejectUnauthorized'] = false;
|
||||
} else {
|
||||
const cacertArray = [preferences['cacert'], process.env.SSL_CERT_FILE, process.env.NODE_EXTRA_CA_CERTS];
|
||||
cacertFile = cacertArray.find((el) => el);
|
||||
const cacertArray = [preferences.getCaCert(), process.env.SSL_CERT_FILE, process.env.NODE_EXTRA_CA_CERTS];
|
||||
const cacertFile = cacertArray.find((el) => el);
|
||||
if (cacertFile && cacertFile.length > 1) {
|
||||
try {
|
||||
const fs = require('fs');
|
||||
caCrt = fs.readFileSync(cacertFile);
|
||||
httpsAgentRequestFields['ca'] = caCrt;
|
||||
httpsAgentRequestFields['ca'] = fs.readFileSync(cacertFile);
|
||||
} catch (err) {
|
||||
console.log('Error reading CA cert file:' + cacertFile, err);
|
||||
}
|
||||
@ -474,10 +471,7 @@ const registerNetworkIpc = (mainWindow) => {
|
||||
const envVars = getEnvVars(environment);
|
||||
const preparedRequest = prepareGqlIntrospectionRequest(endpoint, envVars, request);
|
||||
|
||||
const preferences = getPreferences();
|
||||
const sslVerification = get(preferences, 'request.sslVerification', true);
|
||||
|
||||
if (!sslVerification) {
|
||||
if (!preferences.isTlsVerification()) {
|
||||
request.httpsAgent = new https.Agent({
|
||||
rejectUnauthorized: false
|
||||
});
|
||||
@ -649,9 +643,6 @@ const registerNetworkIpc = (mainWindow) => {
|
||||
...eventData
|
||||
});
|
||||
|
||||
const preferences = getPreferences();
|
||||
const sslVerification = get(preferences, 'request.sslVerification', true);
|
||||
|
||||
// proxy configuration
|
||||
const brunoConfig = getBrunoConfig(collectionUid);
|
||||
const proxyEnabled = get(brunoConfig, 'proxy.enabled', false);
|
||||
@ -685,11 +676,11 @@ const registerNetworkIpc = (mainWindow) => {
|
||||
}
|
||||
|
||||
request.httpsAgent = new HttpsProxyAgent(proxy, {
|
||||
rejectUnauthorized: sslVerification
|
||||
rejectUnauthorized: preferences.isTlsVerification()
|
||||
});
|
||||
|
||||
request.httpAgent = new HttpProxyAgent(proxy);
|
||||
} else if (!sslVerification) {
|
||||
} else if (!preferences.isTlsVerification()) {
|
||||
request.httpsAgent = new https.Agent({
|
||||
rejectUnauthorized: false
|
||||
});
|
||||
|
7
packages/bruno-electron/src/store/index.js
Normal file
7
packages/bruno-electron/src/store/index.js
Normal file
@ -0,0 +1,7 @@
|
||||
const PREFERENCES = 'PREFERENCES';
|
||||
|
||||
const stores = {
|
||||
PREFERENCES
|
||||
};
|
||||
|
||||
module.exports = stores;
|
@ -1,26 +1,107 @@
|
||||
const Store = require('electron-store');
|
||||
const { get } = require('lodash');
|
||||
|
||||
/**
|
||||
* The preferences are stored in the browser local storage.
|
||||
* When the app is started, an IPC message is published from the renderer process to set the preferences.
|
||||
* The preferences are stored in the electron store 'preferences.json'.
|
||||
* The electron process uses this module to get the preferences.
|
||||
*
|
||||
* {
|
||||
* preferences {
|
||||
* request: {
|
||||
* sslVerification: boolean
|
||||
* tlsVerification: boolean,
|
||||
* cacert: String (yet not implemented in front end)
|
||||
* }
|
||||
* proxy: { (yet not implemented in front end)
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
let preferences = {};
|
||||
const defaultPreferences = {
|
||||
request: {
|
||||
tlsVerification: true,
|
||||
caCert: ''
|
||||
},
|
||||
proxy: {
|
||||
enabled: false,
|
||||
protocol: 'http',
|
||||
hostnameHttp: '',
|
||||
portHttp: '',
|
||||
auth: {
|
||||
enabled: false,
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
noProxy: ''
|
||||
}
|
||||
};
|
||||
|
||||
class PreferencesStore {
|
||||
constructor() {
|
||||
this.store = new Store({
|
||||
name: 'preferences',
|
||||
clearInvalidConfig: true
|
||||
});
|
||||
}
|
||||
|
||||
get(key) {
|
||||
return this.store.get(key);
|
||||
}
|
||||
|
||||
set(key, value) {
|
||||
this.store.set(key, value);
|
||||
}
|
||||
|
||||
getPath() {
|
||||
return this.store.path;
|
||||
}
|
||||
}
|
||||
const preferencesStore = new PreferencesStore();
|
||||
|
||||
const getPreferences = () => {
|
||||
return preferences;
|
||||
return {
|
||||
...defaultPreferences,
|
||||
...(preferencesStore.get('preferences') || {})
|
||||
};
|
||||
};
|
||||
|
||||
const setPreferences = (newPreferences) => {
|
||||
preferences = newPreferences;
|
||||
const preferences = {
|
||||
getAll() {
|
||||
return getPreferences();
|
||||
},
|
||||
|
||||
getPath() {
|
||||
return preferencesStore.getPath();
|
||||
},
|
||||
|
||||
isTlsVerification: () => {
|
||||
return get(getPreferences(), ['request.tlsVerification'], true);
|
||||
},
|
||||
getCaCert: () => {
|
||||
return get(getPreferences(), 'request.cacert');
|
||||
},
|
||||
|
||||
setPreferences: (validatedPreferences) => {
|
||||
const updatedPreferences = {
|
||||
...getPreferences(),
|
||||
...validatedPreferences
|
||||
};
|
||||
preferencesStore.set('preferences', updatedPreferences);
|
||||
},
|
||||
|
||||
migrateSslVerification: (sslVerification) => {
|
||||
let preferences = getPreferences();
|
||||
if (!preferences.request) {
|
||||
const updatedPreferences = {
|
||||
...preferences,
|
||||
request: {
|
||||
tlsVerification: sslVerification
|
||||
}
|
||||
};
|
||||
preferencesStore.set('preferences', updatedPreferences);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getPreferences,
|
||||
setPreferences
|
||||
};
|
||||
module.exports = preferences;
|
||||
|
Loading…
Reference in New Issue
Block a user