chore: pr polish (#596)

This commit is contained in:
Anoop M D 2023-10-18 10:25:01 +05:30
parent d767a144f2
commit d809a58deb
12 changed files with 103 additions and 162 deletions

View File

@ -1,24 +1,24 @@
import React, { useEffect } from 'react';
import { useFormik } from 'formik';
import Tooltip from 'components/Tooltip';
import StyledWrapper from './StyledWrapper';
import * as Yup from 'yup';
import toast from 'react-hot-toast';
const ProxySettings = ({ proxyConfig, onUpdate }) => {
const proxySchema = Yup.object({
enabled: Yup.string().oneOf(['global', 'enabled', 'disabled']),
use: Yup.string().oneOf(['global', 'true', 'false']),
protocol: Yup.string().oneOf(['http', 'https', 'socks4', 'socks5']),
hostname: Yup.string()
.when('enabled', {
is: 'enabled',
.when('use', {
is: true,
then: (hostname) => hostname.required('Specify the hostname for your proxy.'),
otherwise: (hostname) => hostname.nullable()
})
.max(1024),
port: Yup.number()
.when('enabled', {
is: 'enabled',
.when('use', {
is: true,
then: (port) => port.required('Specify port between 1 and 65535').typeError('Specify port between 1 and 65535'),
otherwise: (port) => port.nullable().transform((_, val) => (val ? Number(val) : null))
})
@ -26,11 +26,11 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
.max(65535),
auth: Yup.object()
.when('enabled', {
is: 'enabled',
is: true,
then: Yup.object({
enabled: Yup.boolean(),
username: Yup.string()
.when(['enabled'], {
.when('enabled', {
is: true,
then: (username) => username.required('Specify username for proxy authentication.')
})
@ -44,12 +44,12 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
})
})
.optional(),
noProxy: Yup.string().optional().max(1024)
bypassProxy: Yup.string().optional().max(1024)
});
const formik = useFormik({
initialValues: {
enabled: proxyConfig.enabled || 'global',
use: proxyConfig.use || 'global',
protocol: proxyConfig.protocol || 'http',
hostname: proxyConfig.hostname || '',
port: proxyConfig.port || '',
@ -58,13 +58,20 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
username: proxyConfig.auth ? proxyConfig.auth.username || '' : '',
password: proxyConfig.auth ? proxyConfig.auth.password || '' : ''
},
noProxy: proxyConfig.noProxy || ''
bypassProxy: proxyConfig.bypassProxy || ''
},
validationSchema: proxySchema,
onSubmit: (values) => {
proxySchema
.validate(values, { abortEarly: true })
.then((validatedProxy) => {
// serialize 'use' to boolean
if (validatedProxy.use === 'true') {
validatedProxy.use = true;
} else if (validatedProxy.use === 'false') {
validatedProxy.use = false;
}
onUpdate(validatedProxy);
})
.catch((error) => {
@ -76,7 +83,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
useEffect(() => {
formik.setValues({
enabled: proxyConfig.enabled || 'global',
use: proxyConfig.use === true ? 'true' : proxyConfig.use === false ? 'false' : 'global',
protocol: proxyConfig.protocol || 'http',
hostname: proxyConfig.hostname || '',
port: proxyConfig.port || '',
@ -85,32 +92,37 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
username: proxyConfig.auth ? proxyConfig.auth.username || '' : '',
password: proxyConfig.auth ? proxyConfig.auth.password || '' : ''
},
noProxy: proxyConfig.noProxy || ''
bypassProxy: proxyConfig.bypassProxy || ''
});
}, [proxyConfig]);
return (
<StyledWrapper>
<h1 className="font-medium mb-3">Proxy Settings</h1>
<label className="settings-label">
<ul className="mb-3">
<li>global - use global config</li>
<li>enabled - use collection config</li>
<li>disable - disable proxy</li>
</ul>
</label>
<form className="bruno-form" onSubmit={formik.handleSubmit}>
<div className="mb-3 flex items-center">
<label className="settings-label" htmlFor="enabled">
<label className="settings-label flex items-center" htmlFor="enabled">
Config
<Tooltip
text={`
<div>
<ul>
<li><span style="width: 50px;display:inline-block;">global</span> - use global proxy config</li>
<li><span style="width: 50px;display:inline-block;">enabled</span> - use collection proxy config</li>
<li><span style="width: 50px;display:inline-block;">disable</span> - disable proxy</li>
</ul>
</div>
`}
tooltipId="request-var"
/>
</label>
<div className="flex items-center">
<label className="flex items-center">
<input
type="radio"
name="enabled"
name="use"
value="global"
checked={formik.values.enabled === 'global'}
checked={formik.values.use === 'global'}
onChange={formik.handleChange}
className="mr-1"
/>
@ -119,9 +131,9 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
<label className="flex items-center ml-4">
<input
type="radio"
name="enabled"
value="enabled"
checked={formik.values.enabled === 'enabled'}
name="use"
value={'true'}
checked={formik.values.use === 'true'}
onChange={formik.handleChange}
className="mr-1"
/>
@ -130,9 +142,9 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
<label className="flex items-center ml-4">
<input
type="radio"
name="enabled"
value="disabled"
checked={formik.values.enabled === 'disabled'}
name="use"
value={'false'}
checked={formik.values.use === 'false'}
onChange={formik.handleChange}
className="mr-1"
/>
@ -285,23 +297,23 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
</div>
</div>
<div className="mb-3 flex items-center">
<label className="settings-label" htmlFor="noProxy">
<label className="settings-label" htmlFor="bypassProxy">
Proxy Bypass
</label>
<input
id="noProxy"
id="bypassProxy"
type="text"
name="noProxy"
name="bypassProxy"
className="block textbox"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
onChange={formik.handleChange}
value={formik.values.noProxy || ''}
value={formik.values.bypassProxy || ''}
/>
{formik.touched.noProxy && formik.errors.noProxy ? (
<div className="ml-3 text-red-500">{formik.errors.noProxy}</div>
{formik.touched.bypassProxy && formik.errors.bypassProxy ? (
<div className="ml-3 text-red-500">{formik.errors.bypassProxy}</div>
) : null}
</div>
<div className="mt-6">

View File

@ -33,7 +33,7 @@ const General = ({ close }) => {
<StyledWrapper>
<div className="flex items-center mt-2">
<label className="mr-2 select-none" style={{ minWidth: 200 }} htmlFor="ssl-cert-verification">
TLS Certificate Verification
SSL/TLS Certificate Verification
</label>
<input
id="ssl-cert-verification"

View File

@ -49,7 +49,7 @@ const ProxySettings = ({ close }) => {
})
})
.optional(),
noProxy: Yup.string().optional().max(1024)
bypassProxy: Yup.string().optional().max(1024)
});
const formik = useFormik({
@ -63,7 +63,7 @@ const ProxySettings = ({ close }) => {
username: preferences.proxy.auth ? preferences.proxy.auth.username || '' : '',
password: preferences.proxy.auth ? preferences.proxy.auth.password || '' : ''
},
noProxy: preferences.proxy.noProxy || ''
bypassProxy: preferences.proxy.bypassProxy || ''
},
validationSchema: proxySchema,
onSubmit: (values) => {
@ -101,21 +101,21 @@ const ProxySettings = ({ close }) => {
username: preferences.proxy.auth ? preferences.proxy.auth.username || '' : '',
password: preferences.proxy.auth ? preferences.proxy.auth.password || '' : ''
},
noProxy: preferences.proxy.noProxy || ''
bypassProxy: preferences.proxy.bypassProxy || ''
});
}, [preferences]);
return (
<StyledWrapper>
<h1 className="font-medium mb-3">Proxy Settings</h1>
<h1 className="font-medium mb-3">Global Proxy Settings</h1>
<form className="bruno-form" onSubmit={formik.handleSubmit}>
<div className="ml-4 mb-3 flex items-center">
<div className="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">
<div className="mb-3 flex items-center">
<label className="settings-label" htmlFor="protocol">
Protocol
</label>
@ -166,7 +166,7 @@ const ProxySettings = ({ close }) => {
</label>
</div>
</div>
<div className="ml-4 mb-3 flex items-center">
<div className="mb-3 flex items-center">
<label className="settings-label" htmlFor="hostname">
Hostname
</label>
@ -186,7 +186,7 @@ const ProxySettings = ({ close }) => {
<div className="ml-3 text-red-500">{formik.errors.hostname}</div>
) : null}
</div>
<div className="ml-4 mb-3 flex items-center">
<div className="mb-3 flex items-center">
<label className="settings-label" htmlFor="port">
Port
</label>
@ -206,7 +206,7 @@ const ProxySettings = ({ close }) => {
<div className="ml-3 text-red-500">{formik.errors.port}</div>
) : null}
</div>
<div className="ml-4 mb-3 flex items-center">
<div className="mb-3 flex items-center">
<label className="settings-label" htmlFor="auth.enabled">
Auth
</label>
@ -218,7 +218,7 @@ const ProxySettings = ({ close }) => {
/>
</div>
<div>
<div className="ml-4 mb-3 flex items-center">
<div className="mb-3 flex items-center">
<label className="settings-label" htmlFor="auth.username">
Username
</label>
@ -238,7 +238,7 @@ const ProxySettings = ({ close }) => {
<div className="ml-3 text-red-500">{formik.errors.auth.username}</div>
) : null}
</div>
<div className="ml-4 mb-3 flex items-center">
<div className="mb-3 flex items-center">
<label className="settings-label" htmlFor="auth.password">
Password
</label>
@ -259,24 +259,24 @@ const ProxySettings = ({ close }) => {
) : null}
</div>
</div>
<div className="ml-4 mb-3 flex items-center">
<label className="settings-label" htmlFor="noProxy">
<div className="mb-3 flex items-center">
<label className="settings-label" htmlFor="bypassProxy">
Proxy Bypass
</label>
<input
id="noProxy"
id="bypassProxy"
type="text"
name="noProxy"
name="bypassProxy"
className="block textbox"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
onChange={formik.handleChange}
value={formik.values.noProxy || ''}
value={formik.values.bypassProxy || ''}
/>
{formik.touched.noProxy && formik.errors.noProxy ? (
<div className="ml-3 text-red-500">{formik.errors.noProxy}</div>
{formik.touched.bypassProxy && formik.errors.bypassProxy ? (
<div className="ml-3 text-red-500">{formik.errors.bypassProxy}</div>
) : null}
</div>
<div className="mt-6">

View File

@ -129,7 +129,7 @@ const runSingleRequest = async function (
// set proxy if enabled
const proxyEnabled = get(brunoConfig, 'proxy.enabled', false);
const shouldProxy = shouldUseProxy(request.url, get(brunoConfig, 'proxy.noProxy', ''));
const shouldProxy = shouldUseProxy(request.url, get(brunoConfig, 'proxy.bypassProxy', ''));
if (proxyEnabled && shouldProxy) {
const proxyProtocol = interpolateString(get(brunoConfig, 'proxy.protocol'), interpolationOptions);
const proxyHostname = interpolateString(get(brunoConfig, 'proxy.hostname'), interpolationOptions);

View File

@ -11,13 +11,14 @@ const DEFAULT_PORTS = {
/**
* check for proxy bypass, Copied form 'proxy-from-env'
*/
const shouldUseProxy = (url, proxyByPass) => {
if (proxyByPass === '*') {
const shouldUseProxy = (url, proxyBypass) => {
if (proxyBypass === '*') {
return false; // Never proxy if wildcard is set.
}
if (!proxyByPass) {
return true; // use proxy if enabled
// use proxy if no proxyBypass is set
if (!proxyBypass || typeof proxyBypass !== 'string' || isEmpty(proxyBypass.trim())) {
return true;
}
const parsedUrl = typeof url === 'string' ? parseUrl(url) : url || {};
@ -34,7 +35,7 @@ const shouldUseProxy = (url, proxyByPass) => {
hostname = hostname.replace(/:\d*$/, '');
port = parseInt(port) || DEFAULT_PORTS[proto] || 0;
return proxyByPass.split(/[,;\s]/).every(function (dontProxyFor) {
return proxyBypass.split(/[,;\s]/).every(function (dontProxyFor) {
if (!dontProxyFor) {
return true; // Skip zero-length hosts.
}

View File

@ -18,7 +18,6 @@ const { stringifyJson } = require('../utils/common');
const { openCollectionDialog } = 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();

View File

@ -5,7 +5,7 @@ function isStrPresent(str) {
return str && str !== '' && str !== 'undefined';
}
async function resolveCredentials(request) {
async function resolveAwsV4Credentials(request) {
const awsv4 = request.awsv4config;
if (isStrPresent(awsv4.profileName)) {
try {
@ -52,5 +52,5 @@ function addAwsV4Interceptor(axiosInstance, request) {
module.exports = {
addAwsV4Interceptor,
resolveCredentials
resolveAwsV4Credentials
};

View File

@ -16,14 +16,14 @@ const { uuid } = require('../../utils/common');
const interpolateVars = require('./interpolate-vars');
const { interpolateString } = require('./interpolate-string');
const { sortFolder, getAllRequestsInFolderRecursively } = require('./helper');
const { preferences } = require('../../store/preferences');
const { preferencesUtil } = require('../../store/preferences');
const { getProcessEnvVars } = require('../../store/process-env');
const { getBrunoConfig } = require('../../store/bruno-config');
const { HttpsProxyAgent } = require('https-proxy-agent');
const { HttpProxyAgent } = require('http-proxy-agent');
const { SocksProxyAgent } = require('socks-proxy-agent');
const { makeAxiosInstance } = require('./axios-instance');
const { addAwsV4Interceptor, resolveCredentials } = require('./awsv4auth-helper');
const { addAwsV4Interceptor, resolveAwsV4Credentials } = require('./awsv4auth-helper');
const { shouldUseProxy } = require('../../utils/proxy-util');
// override the default escape function to prevent escaping
@ -86,7 +86,7 @@ const getSize = (data) => {
const configureRequest = async (collectionUid, request, envVars, collectionVariables, processEnvVars) => {
const httpsAgentRequestFields = {};
if (!preferences.isTlsVerification()) {
if (!preferencesUtil.shouldVerifyTls()) {
httpsAgentRequestFields['rejectUnauthorized'] = false;
}
@ -123,10 +123,10 @@ const configureRequest = async (collectionUid, request, envVars, collectionVaria
let proxyConfig = get(brunoConfig, 'proxy', {});
let proxyEnabled = get(proxyConfig, 'enabled', 'disabled');
if (proxyEnabled === 'global') {
proxyConfig = preferences.getProxyConfig();
proxyConfig = preferencesUtil.getGlobalProxyConfig();
proxyEnabled = get(proxyConfig, 'enabled', false);
}
const shouldProxy = shouldUseProxy(request.url, get(proxyConfig, 'noProxy', ''));
const shouldProxy = shouldUseProxy(request.url, get(proxyConfig, 'bypassProxy', ''));
if ((proxyEnabled === true || proxyEnabled === 'enabled') && shouldProxy) {
const proxyProtocol = interpolateString(get(proxyConfig, 'protocol'), interpolationOptions);
const proxyHostname = interpolateString(get(proxyConfig, 'hostname'), interpolationOptions);
@ -164,12 +164,12 @@ const configureRequest = async (collectionUid, request, envVars, collectionVaria
const axiosInstance = makeAxiosInstance();
if (request.awsv4config) {
request.awsv4config = await resolveCredentials(request);
request.awsv4config = await resolveAwsV4Credentials(request);
addAwsV4Interceptor(axiosInstance, request);
delete request.awsv4config;
}
request.timeout = preferences.getTimeout();
request.timeout = preferencesUtil.getRequestTimeout();
return axiosInstance;
};
@ -530,9 +530,9 @@ const registerNetworkIpc = (mainWindow) => {
const collectionRoot = get(collection, 'root', {});
const preparedRequest = prepareGqlIntrospectionRequest(endpoint, envVars, request, collectionRoot);
request.timeout = preferences.getTimeout();
request.timeout = preferencesUtil.getRequestTimeout();
if (!preferences.isTlsVerification()) {
if (!preferencesUtil.shouldVerifyTls()) {
request.httpsAgent = new https.Agent({
rejectUnauthorized: false
});

View File

@ -1,64 +1,9 @@
const { ipcMain } = require('electron');
const { getPreferences, savePreferences, getPath } = require('../store/preferences');
const { getPreferences, savePreferences } = require('../store/preferences');
const { isDirectory } = require('../utils/filesystem');
const { openCollection } = require('../app/collections');
const stores = require('../store');
const chokidar = require('chokidar');
``;
const registerPreferencesIpc = (mainWindow, watcher, lastOpenedCollections) => {
const change = async (pathname, store) => {
if (store === stores.PREFERENCES) {
mainWindow.webContents.send('main:load-preferences', getPreferences());
}
};
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(getPath(), stores.PREFERENCES);
ipcMain.handle('renderer:ready', async (event) => {
// load preferences
const preferences = getPreferences();

View File

@ -1,7 +0,0 @@
const PREFERENCES = 'PREFERENCES';
const stores = {
PREFERENCES
};
module.exports = stores;

View File

@ -19,14 +19,14 @@ const defaultPreferences = {
proxy: {
enabled: false,
protocol: 'http',
hostnameHttp: '',
portHttp: '',
hostname: '',
port: '',
auth: {
enabled: false,
username: '',
password: ''
},
noProxy: ''
bypassProxy: ''
}
};
@ -42,13 +42,13 @@ const preferencesSchema = Yup.object().shape({
enabled: Yup.boolean(),
protocol: Yup.string().oneOf(['http', 'https', 'socks4', 'socks5']),
hostname: Yup.string().max(1024),
port: Yup.number().min(1).max(65535),
port: Yup.number().min(1).max(65535).nullable(),
auth: Yup.object({
enabled: Yup.boolean(),
username: Yup.string().max(1024),
password: Yup.string().max(1024)
}).optional(),
noProxy: Yup.string().optional().max(1024)
bypassProxy: Yup.string().optional().max(1024)
})
});
@ -60,10 +60,6 @@ class PreferencesStore {
});
}
getPath() {
return this.store.path;
}
getPreferences() {
return {
...defaultPreferences,
@ -96,20 +92,14 @@ const savePreferences = async (newPreferences) => {
});
};
const getPath = () => {
return preferencesStore.getPath();
};
const preferences = {
isTlsVerification: () => {
const preferencesUtil = {
shouldVerifyTls: () => {
return get(getPreferences(), 'request.sslVerification', true);
},
getTimeout: () => {
getRequestTimeout: () => {
return get(getPreferences(), 'request.timeout', 0);
},
getProxyConfig: () => {
getGlobalProxyConfig: () => {
return get(getPreferences(), 'proxy', {});
}
};
@ -117,6 +107,5 @@ const preferences = {
module.exports = {
getPreferences,
savePreferences,
getPath,
preferences
preferencesUtil
};

View File

@ -1,4 +1,5 @@
const parseUrl = require('url').parse;
const { isEmpty } = require('lodash');
const DEFAULT_PORTS = {
ftp: 21,
@ -11,13 +12,14 @@ const DEFAULT_PORTS = {
/**
* check for proxy bypass, copied form 'proxy-from-env'
*/
const shouldUseProxy = (url, proxyByPass) => {
if (proxyByPass === '*') {
const shouldUseProxy = (url, proxyBypass) => {
if (proxyBypass === '*') {
return false; // Never proxy if wildcard is set.
}
if (!proxyByPass) {
return true; // use proxy if enabled
// use proxy if no proxyBypass is set
if (!proxyBypass || typeof proxyBypass !== 'string' || isEmpty(proxyBypass.trim())) {
return true;
}
const parsedUrl = typeof url === 'string' ? parseUrl(url) : url || {};
@ -34,7 +36,7 @@ const shouldUseProxy = (url, proxyByPass) => {
hostname = hostname.replace(/:\d*$/, '');
port = parseInt(port) || DEFAULT_PORTS[proto] || 0;
return proxyByPass.split(/[,;\s]/).every(function (dontProxyFor) {
return proxyBypass.split(/[,;\s]/).every(function (dontProxyFor) {
if (!dontProxyFor) {
return true; // Skip zero-length hosts.
}