mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-29 03:13:45 +01:00
proxy settings global and collection level
This commit is contained in:
parent
f2bdf2eaf6
commit
6dd6879e8f
@ -19,7 +19,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
|||||||
port: Yup.number()
|
port: Yup.number()
|
||||||
.when('enabled', {
|
.when('enabled', {
|
||||||
is: 'enabled',
|
is: 'enabled',
|
||||||
then: (port) => port.typeError('Specify port between 1 and 65535'),
|
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))
|
otherwise: (port) => port.nullable().transform((_, val) => (val ? Number(val) : null))
|
||||||
})
|
})
|
||||||
.min(1)
|
.min(1)
|
||||||
@ -208,7 +208,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
|||||||
value={formik.values.hostname || ''}
|
value={formik.values.hostname || ''}
|
||||||
/>
|
/>
|
||||||
{formik.touched.hostname && formik.errors.hostname ? (
|
{formik.touched.hostname && formik.errors.hostname ? (
|
||||||
<div className="text-red-500">{formik.errors.hostname}</div>
|
<div className="ml-3 text-red-500">{formik.errors.hostname}</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3 flex items-center">
|
<div className="mb-3 flex items-center">
|
||||||
@ -227,7 +227,9 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
|||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
value={formik.values.port}
|
value={formik.values.port}
|
||||||
/>
|
/>
|
||||||
{formik.touched.port && formik.errors.port ? <div className="text-red-500">{formik.errors.port}</div> : null}
|
{formik.touched.port && formik.errors.port ? (
|
||||||
|
<div className="ml-3 text-red-500">{formik.errors.port}</div>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3 flex items-center">
|
<div className="mb-3 flex items-center">
|
||||||
<label className="settings-label" htmlFor="auth.enabled">
|
<label className="settings-label" htmlFor="auth.enabled">
|
||||||
@ -258,7 +260,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
|||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
/>
|
/>
|
||||||
{formik.touched.auth?.username && formik.errors.auth?.username ? (
|
{formik.touched.auth?.username && formik.errors.auth?.username ? (
|
||||||
<div className="text-red-500">{formik.errors.auth.username}</div>
|
<div className="ml-3 text-red-500">{formik.errors.auth.username}</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3 flex items-center">
|
<div className="mb-3 flex items-center">
|
||||||
@ -278,7 +280,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
|||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
/>
|
/>
|
||||||
{formik.touched.auth?.password && formik.errors.auth?.password ? (
|
{formik.touched.auth?.password && formik.errors.auth?.password ? (
|
||||||
<div className="text-red-500">{formik.errors.auth.password}</div>
|
<div className="ml-3 text-red-500">{formik.errors.auth.password}</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -299,7 +301,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
|||||||
value={formik.values.noProxy || ''}
|
value={formik.values.noProxy || ''}
|
||||||
/>
|
/>
|
||||||
{formik.touched.noProxy && formik.errors.noProxy ? (
|
{formik.touched.noProxy && formik.errors.noProxy ? (
|
||||||
<div className="text-red-500">{formik.errors.noProxy}</div>
|
<div className="ml-3 text-red-500">{formik.errors.noProxy}</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-6">
|
<div className="mt-6">
|
||||||
|
@ -2,12 +2,55 @@ import React, { useEffect } from 'react';
|
|||||||
import { useFormik } from 'formik';
|
import { useFormik } from 'formik';
|
||||||
import * as Yup from 'yup';
|
import * as Yup from 'yup';
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
|
import { savePreferences } from 'providers/ReduxStore/slices/app';
|
||||||
|
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
import { usePreferences } from 'providers/Preferences';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
const ProxySettings = () => {
|
const ProxySettings = ({ close }) => {
|
||||||
const { preferences, setPreferences } = usePreferences();
|
const preferences = useSelector((state) => state.app.preferences);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const proxySchema = Yup.object({
|
||||||
|
enabled: Yup.boolean(),
|
||||||
|
protocol: Yup.string().required().oneOf(['http', 'https', 'socks4', 'socks5']),
|
||||||
|
hostname: Yup.string()
|
||||||
|
.when('enabled', {
|
||||||
|
is: true,
|
||||||
|
then: (hostname) => hostname.required('Specify the hostname for your proxy.'),
|
||||||
|
otherwise: (hostname) => hostname.nullable()
|
||||||
|
})
|
||||||
|
.max(1024),
|
||||||
|
port: Yup.number()
|
||||||
|
.when('enabled', {
|
||||||
|
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))
|
||||||
|
})
|
||||||
|
.min(1)
|
||||||
|
.max(65535),
|
||||||
|
auth: Yup.object()
|
||||||
|
.when('enabled', {
|
||||||
|
is: true,
|
||||||
|
then: Yup.object({
|
||||||
|
enabled: Yup.boolean(),
|
||||||
|
username: Yup.string()
|
||||||
|
.when(['enabled'], {
|
||||||
|
is: true,
|
||||||
|
then: (username) => username.required('Specify username for proxy authentication.')
|
||||||
|
})
|
||||||
|
.max(1024),
|
||||||
|
password: Yup.string()
|
||||||
|
.when('enabled', {
|
||||||
|
is: true,
|
||||||
|
then: (password) => password.required('Specify password for proxy authentication.')
|
||||||
|
})
|
||||||
|
.max(1024)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
|
noProxy: Yup.string().optional().max(1024)
|
||||||
|
});
|
||||||
|
|
||||||
const formik = useFormik({
|
const formik = useFormik({
|
||||||
initialValues: {
|
initialValues: {
|
||||||
@ -22,35 +65,28 @@ const ProxySettings = () => {
|
|||||||
},
|
},
|
||||||
noProxy: preferences.proxy.noProxy || ''
|
noProxy: preferences.proxy.noProxy || ''
|
||||||
},
|
},
|
||||||
validationSchema: Yup.object({
|
validationSchema: proxySchema,
|
||||||
enabled: Yup.boolean(),
|
|
||||||
protocol: Yup.string().oneOf(['http', 'https', 'socks4', '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) => {
|
onSubmit: (values) => {
|
||||||
onUpdate(values);
|
onUpdate(values);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const onUpdate = (values) => {
|
const onUpdate = (values) => {
|
||||||
const updatedPreferences = {
|
proxySchema
|
||||||
|
.validate(values, { abortEarly: true })
|
||||||
|
.then((validatedProxy) => {
|
||||||
|
dispatch(
|
||||||
|
savePreferences({
|
||||||
...preferences,
|
...preferences,
|
||||||
proxy: values
|
proxy: validatedProxy
|
||||||
};
|
|
||||||
|
|
||||||
setPreferences(updatedPreferences)
|
|
||||||
.then(() => {
|
|
||||||
toast.success('Proxy settings updated successfully.');
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
).then(() => {
|
||||||
console.error(err);
|
close();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
let errMsg = error.message || 'Preferences validation error';
|
||||||
|
toast.error(errMsg);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -147,7 +183,7 @@ const ProxySettings = () => {
|
|||||||
value={formik.values.hostname || ''}
|
value={formik.values.hostname || ''}
|
||||||
/>
|
/>
|
||||||
{formik.touched.hostname && formik.errors.hostname ? (
|
{formik.touched.hostname && formik.errors.hostname ? (
|
||||||
<div className="text-red-500">{formik.errors.hostname}</div>
|
<div className="ml-3 text-red-500">{formik.errors.hostname}</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<div className="ml-4 mb-3 flex items-center">
|
<div className="ml-4 mb-3 flex items-center">
|
||||||
@ -166,7 +202,9 @@ const ProxySettings = () => {
|
|||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
value={formik.values.port}
|
value={formik.values.port}
|
||||||
/>
|
/>
|
||||||
{formik.touched.port && formik.errors.port ? <div className="text-red-500">{formik.errors.port}</div> : null}
|
{formik.touched.port && formik.errors.port ? (
|
||||||
|
<div className="ml-3 text-red-500">{formik.errors.port}</div>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<div className="ml-4 mb-3 flex items-center">
|
<div className="ml-4 mb-3 flex items-center">
|
||||||
<label className="settings-label" htmlFor="auth.enabled">
|
<label className="settings-label" htmlFor="auth.enabled">
|
||||||
@ -197,7 +235,7 @@ const ProxySettings = () => {
|
|||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
/>
|
/>
|
||||||
{formik.touched.auth?.username && formik.errors.auth?.username ? (
|
{formik.touched.auth?.username && formik.errors.auth?.username ? (
|
||||||
<div className="text-red-500">{formik.errors.auth.username}</div>
|
<div className="ml-3 text-red-500">{formik.errors.auth.username}</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<div className="ml-4 mb-3 flex items-center">
|
<div className="ml-4 mb-3 flex items-center">
|
||||||
@ -217,7 +255,7 @@ const ProxySettings = () => {
|
|||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
/>
|
/>
|
||||||
{formik.touched.auth?.password && formik.errors.auth?.password ? (
|
{formik.touched.auth?.password && formik.errors.auth?.password ? (
|
||||||
<div className="text-red-500">{formik.errors.auth.password}</div>
|
<div className="ml-3 text-red-500">{formik.errors.auth.password}</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -238,7 +276,7 @@ const ProxySettings = () => {
|
|||||||
value={formik.values.noProxy || ''}
|
value={formik.values.noProxy || ''}
|
||||||
/>
|
/>
|
||||||
{formik.touched.noProxy && formik.errors.noProxy ? (
|
{formik.touched.noProxy && formik.errors.noProxy ? (
|
||||||
<div className="text-red-500">{formik.errors.noProxy}</div>
|
<div className="ml-3 text-red-500">{formik.errors.noProxy}</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-6">
|
<div className="mt-6">
|
||||||
|
@ -87,8 +87,7 @@ const runSingleRequest = async function (
|
|||||||
const httpsAgentRequestFields = {};
|
const httpsAgentRequestFields = {};
|
||||||
if (insecure) {
|
if (insecure) {
|
||||||
httpsAgentRequestFields['rejectUnauthorized'] = false;
|
httpsAgentRequestFields['rejectUnauthorized'] = false;
|
||||||
}
|
} else {
|
||||||
|
|
||||||
const caCertArray = [options['cacert'], process.env.SSL_CERT_FILE, process.env.NODE_EXTRA_CA_CERTS];
|
const caCertArray = [options['cacert'], process.env.SSL_CERT_FILE, process.env.NODE_EXTRA_CA_CERTS];
|
||||||
const caCert = caCertArray.find((el) => el);
|
const caCert = caCertArray.find((el) => el);
|
||||||
if (caCert && caCert.length > 1) {
|
if (caCert && caCert.length > 1) {
|
||||||
@ -98,11 +97,12 @@ const runSingleRequest = async function (
|
|||||||
console.log('Error reading CA cert file:' + caCert, err);
|
console.log('Error reading CA cert file:' + caCert, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// set proxy if enabled
|
// set proxy if enabled
|
||||||
const proxyEnabled = get(brunoConfig, 'proxy.enabled', false);
|
const proxyEnabled = get(brunoConfig, 'proxy.enabled', false);
|
||||||
const proxyByPass = shouldUseProxy(request.url, get(brunoConfig, 'proxy.noProxy', ''));
|
const shouldProxy = shouldUseProxy(request.url, get(brunoConfig, 'proxy.noProxy', ''));
|
||||||
if (proxyEnabled && !proxyByPass) {
|
if (proxyEnabled && shouldProxy) {
|
||||||
let proxyUri;
|
let proxyUri;
|
||||||
const interpolationOptions = {
|
const interpolationOptions = {
|
||||||
envVars: envVariables,
|
envVars: envVariables,
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
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;
|
|
@ -16,7 +16,7 @@ const { uuid } = require('../../utils/common');
|
|||||||
const interpolateVars = require('./interpolate-vars');
|
const interpolateVars = require('./interpolate-vars');
|
||||||
const { interpolateString } = require('./interpolate-string');
|
const { interpolateString } = require('./interpolate-string');
|
||||||
const { sortFolder, getAllRequestsInFolderRecursively } = require('./helper');
|
const { sortFolder, getAllRequestsInFolderRecursively } = require('./helper');
|
||||||
const preferences = require('../../store/preferences');
|
const { preferences } = require('../../store/preferences');
|
||||||
const { getProcessEnvVars } = require('../../store/process-env');
|
const { getProcessEnvVars } = require('../../store/process-env');
|
||||||
const { getBrunoConfig } = require('../../store/bruno-config');
|
const { getBrunoConfig } = require('../../store/bruno-config');
|
||||||
const { HttpsProxyAgent } = require('https-proxy-agent');
|
const { HttpsProxyAgent } = require('https-proxy-agent');
|
||||||
@ -84,12 +84,11 @@ const getSize = (data) => {
|
|||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
function getHttpsAgentRequestFields() {
|
const configureRequest = async (collectionUid, request, envVars, collectionVariables, processEnvVars) => {
|
||||||
const httpsAgentRequestFields = {};
|
const httpsAgentRequestFields = {};
|
||||||
if (!preferences.isTlsVerification()) {
|
if (!preferences.isTlsVerification()) {
|
||||||
httpsAgentRequestFields['rejectUnauthorized'] = false;
|
httpsAgentRequestFields['rejectUnauthorized'] = false;
|
||||||
}
|
} else {
|
||||||
|
|
||||||
const cacCrtArray = [preferences.getCaCert(), process.env.SSL_CERT_FILE, process.env.NODE_EXTRA_CA_CERTS];
|
const cacCrtArray = [preferences.getCaCert(), process.env.SSL_CERT_FILE, process.env.NODE_EXTRA_CA_CERTS];
|
||||||
let caCertFile = cacCrtArray.find((el) => el);
|
let caCertFile = cacCrtArray.find((el) => el);
|
||||||
if (caCertFile && caCertFile.length > 1) {
|
if (caCertFile && caCertFile.length > 1) {
|
||||||
@ -99,8 +98,67 @@ function getHttpsAgentRequestFields() {
|
|||||||
console.log('Error reading CA cert file:' + caCertFile, err);
|
console.log('Error reading CA cert file:' + caCertFile, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return httpsAgentRequestFields;
|
}
|
||||||
}
|
|
||||||
|
// proxy configuration
|
||||||
|
const brunoConfig = getBrunoConfig(collectionUid);
|
||||||
|
let proxyConfig = get(brunoConfig, 'proxy', {});
|
||||||
|
let proxyEnabled = get(proxyConfig, 'enabled', 'disabled');
|
||||||
|
if (proxyEnabled === 'global') {
|
||||||
|
proxyConfig = preferences.getProxyConfig();
|
||||||
|
proxyEnabled = get(proxyConfig, 'enabled', false);
|
||||||
|
}
|
||||||
|
const shouldProxy = shouldUseProxy(request.url, get(proxyConfig, 'noProxy', ''));
|
||||||
|
if ((proxyEnabled === true || proxyEnabled === 'enabled') && shouldProxy) {
|
||||||
|
let proxyUri;
|
||||||
|
const interpolationOptions = {
|
||||||
|
envVars,
|
||||||
|
collectionVariables,
|
||||||
|
processEnvVars
|
||||||
|
};
|
||||||
|
|
||||||
|
const proxyProtocol = interpolateString(get(proxyConfig, 'protocol'), interpolationOptions);
|
||||||
|
const proxyHostname = interpolateString(get(proxyConfig, 'hostname'), interpolationOptions);
|
||||||
|
const proxyPort = interpolateString(get(proxyConfig, 'port'), interpolationOptions);
|
||||||
|
const proxyAuthEnabled = get(proxyConfig, 'auth.enabled', false);
|
||||||
|
const socksEnabled = proxyProtocol.includes('socks');
|
||||||
|
|
||||||
|
if (proxyAuthEnabled) {
|
||||||
|
const proxyAuthUsername = interpolateString(get(proxyConfig, 'auth.username'), interpolationOptions);
|
||||||
|
const proxyAuthPassword = interpolateString(get(proxyConfig, 'auth.password'), interpolationOptions);
|
||||||
|
|
||||||
|
proxyUri = `${proxyProtocol}://${proxyAuthUsername}:${proxyAuthPassword}@${proxyHostname}:${proxyPort}`;
|
||||||
|
} else {
|
||||||
|
proxyUri = `${proxyProtocol}://${proxyHostname}:${proxyPort}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (socksEnabled) {
|
||||||
|
const socksProxyAgent = new SocksProxyAgent(proxyUri);
|
||||||
|
request.httpsAgent = socksProxyAgent;
|
||||||
|
request.httpAgent = socksProxyAgent;
|
||||||
|
} else {
|
||||||
|
request.httpsAgent = new HttpsProxyAgent(
|
||||||
|
proxyUri,
|
||||||
|
Object.keys(httpsAgentRequestFields).length > 0 ? { ...httpsAgentRequestFields } : undefined
|
||||||
|
);
|
||||||
|
request.httpAgent = new HttpProxyAgent(proxyUri);
|
||||||
|
}
|
||||||
|
} else if (Object.keys(httpsAgentRequestFields).length > 0) {
|
||||||
|
request.httpsAgent = new https.Agent({
|
||||||
|
...httpsAgentRequestFields
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const axiosInstance = makeAxiosInstance();
|
||||||
|
|
||||||
|
if (request.awsv4config) {
|
||||||
|
request.awsv4config = await resolveCredentials(request);
|
||||||
|
addAwsV4Interceptor(axiosInstance, request);
|
||||||
|
delete request.awsv4config;
|
||||||
|
}
|
||||||
|
|
||||||
|
return axiosInstance;
|
||||||
|
};
|
||||||
|
|
||||||
const registerNetworkIpc = (mainWindow) => {
|
const registerNetworkIpc = (mainWindow) => {
|
||||||
// handler for sending http request
|
// handler for sending http request
|
||||||
@ -224,64 +282,13 @@ const registerNetworkIpc = (mainWindow) => {
|
|||||||
cancelTokenUid
|
cancelTokenUid
|
||||||
});
|
});
|
||||||
|
|
||||||
const httpsAgentRequestFields = getHttpsAgentRequestFields();
|
const axiosInstance = await configureRequest(
|
||||||
|
collectionUid,
|
||||||
// proxy configuration
|
request,
|
||||||
const brunoConfig = getBrunoConfig(collectionUid);
|
|
||||||
let proxyConfig = get(brunoConfig, 'proxy', {});
|
|
||||||
let proxyEnabled = get(proxyConfig, 'enabled', 'disabled');
|
|
||||||
if (proxyEnabled === 'global') {
|
|
||||||
proxyConfig = preferences.getProxyConfig();
|
|
||||||
proxyEnabled = get(proxyConfig, 'enabled', false);
|
|
||||||
}
|
|
||||||
const proxyByPass = shouldUseProxy(request.url, get(proxyConfig, 'noProxy', ''));
|
|
||||||
if ((proxyEnabled === true || proxyEnabled === 'enabled') && !proxyByPass) {
|
|
||||||
let proxyUri;
|
|
||||||
const interpolationOptions = {
|
|
||||||
envVars,
|
envVars,
|
||||||
collectionVariables,
|
collectionVariables,
|
||||||
processEnvVars
|
processEnvVars
|
||||||
};
|
|
||||||
|
|
||||||
const proxyProtocol = interpolateString(get(proxyConfig, 'protocol'), interpolationOptions);
|
|
||||||
const proxyHostname = interpolateString(get(proxyConfig, 'hostname'), interpolationOptions);
|
|
||||||
const proxyPort = interpolateString(get(proxyConfig, 'port'), interpolationOptions);
|
|
||||||
const proxyAuthEnabled = get(proxyConfig, 'auth.enabled', false);
|
|
||||||
const socksEnabled = proxyProtocol.includes('socks');
|
|
||||||
|
|
||||||
if (proxyAuthEnabled) {
|
|
||||||
const proxyAuthUsername = interpolateString(get(proxyConfig, 'auth.username'), interpolationOptions);
|
|
||||||
const proxyAuthPassword = interpolateString(get(proxyConfig, 'auth.password'), interpolationOptions);
|
|
||||||
|
|
||||||
proxyUri = `${proxyProtocol}://${proxyAuthUsername}:${proxyAuthPassword}@${proxyHostname}:${proxyPort}`;
|
|
||||||
} else {
|
|
||||||
proxyUri = `${proxyProtocol}://${proxyHostname}:${proxyPort}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (socksEnabled) {
|
|
||||||
const socksProxyAgent = new SocksProxyAgent(proxyUri);
|
|
||||||
request.httpsAgent = socksProxyAgent;
|
|
||||||
request.httpAgent = socksProxyAgent;
|
|
||||||
} else {
|
|
||||||
request.httpsAgent = new HttpsProxyAgent(
|
|
||||||
proxyUri,
|
|
||||||
Object.keys(httpsAgentRequestFields).length > 0 ? { ...httpsAgentRequestFields } : undefined
|
|
||||||
);
|
);
|
||||||
request.httpAgent = new HttpProxyAgent(proxyUri);
|
|
||||||
}
|
|
||||||
} else if (Object.keys(httpsAgentRequestFields).length > 0) {
|
|
||||||
request.httpsAgent = new https.Agent({
|
|
||||||
...httpsAgentRequestFields
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const axiosInstance = makeAxiosInstance();
|
|
||||||
|
|
||||||
if (request.awsv4config) {
|
|
||||||
request.awsv4config = await resolveCredentials(request);
|
|
||||||
addAwsV4Interceptor(axiosInstance, request);
|
|
||||||
delete request.awsv4config;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @type {import('axios').AxiosResponse} */
|
/** @type {import('axios').AxiosResponse} */
|
||||||
const response = await axiosInstance(request);
|
const response = await axiosInstance(request);
|
||||||
@ -684,60 +691,17 @@ const registerNetworkIpc = (mainWindow) => {
|
|||||||
...eventData
|
...eventData
|
||||||
});
|
});
|
||||||
|
|
||||||
const httpsAgentRequestFields = getHttpsAgentRequestFields();
|
const axiosInstance = await configureRequest(
|
||||||
|
collectionUid,
|
||||||
// proxy configuration
|
request,
|
||||||
const brunoConfig = getBrunoConfig(collectionUid);
|
|
||||||
let proxyConfig = get(brunoConfig, 'proxy', {});
|
|
||||||
let proxyEnabled = get(proxyConfig, 'enabled', 'disabled');
|
|
||||||
if (proxyEnabled === 'global') {
|
|
||||||
proxyConfig = preferences.getProxyConfig();
|
|
||||||
proxyEnabled = get(proxyConfig, 'enabled', false);
|
|
||||||
}
|
|
||||||
const proxyByPass = shouldUseProxy(request.url, get(proxyConfig, 'noProxy', ''));
|
|
||||||
if ((proxyEnabled === true || proxyEnabled === 'enabled') && !proxyByPass) {
|
|
||||||
let proxyUri;
|
|
||||||
const interpolationOptions = {
|
|
||||||
envVars,
|
envVars,
|
||||||
collectionVariables,
|
collectionVariables,
|
||||||
processEnvVars
|
processEnvVars
|
||||||
};
|
|
||||||
|
|
||||||
const proxyProtocol = interpolateString(get(proxyConfig, 'protocol'), interpolationOptions);
|
|
||||||
const proxyHostname = interpolateString(get(proxyConfig, 'hostname'), interpolationOptions);
|
|
||||||
const proxyPort = interpolateString(get(proxyConfig, 'port'), interpolationOptions);
|
|
||||||
const proxyAuthEnabled = get(proxyConfig, 'auth.enabled', false);
|
|
||||||
const socksEnabled = proxyProtocol.includes('socks');
|
|
||||||
|
|
||||||
if (proxyAuthEnabled) {
|
|
||||||
const proxyAuthUsername = interpolateString(get(proxyConfig, 'auth.username'), interpolationOptions);
|
|
||||||
const proxyAuthPassword = interpolateString(get(proxyConfig, 'auth.password'), interpolationOptions);
|
|
||||||
|
|
||||||
proxyUri = `${proxyProtocol}://${proxyAuthUsername}:${proxyAuthPassword}@${proxyHostname}:${proxyPort}`;
|
|
||||||
} else {
|
|
||||||
proxyUri = `${proxyProtocol}://${proxyHostname}:${proxyPort}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (socksEnabled) {
|
|
||||||
const socksProxyAgent = new SocksProxyAgent(proxyUri);
|
|
||||||
request.httpsAgent = socksProxyAgent;
|
|
||||||
request.httpAgent = socksProxyAgent;
|
|
||||||
} else {
|
|
||||||
request.httpsAgent = new HttpsProxyAgent(
|
|
||||||
proxyUri,
|
|
||||||
Object.keys(httpsAgentRequestFields).length > 0 ? { ...httpsAgentRequestFields } : undefined
|
|
||||||
);
|
);
|
||||||
request.httpAgent = new HttpProxyAgent(proxyUri);
|
|
||||||
}
|
|
||||||
} else if (Object.keys(httpsAgentRequestFields).length > 0) {
|
|
||||||
request.httpsAgent = new https.Agent({
|
|
||||||
...httpsAgentRequestFields
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// send request
|
|
||||||
timeStart = Date.now();
|
timeStart = Date.now();
|
||||||
const response = await axios(request);
|
/** @type {import('axios').AxiosResponse} */
|
||||||
|
const response = await axiosInstance(request);
|
||||||
timeEnd = Date.now();
|
timeEnd = Date.now();
|
||||||
|
|
||||||
// run post-response vars
|
// run post-response vars
|
||||||
|
@ -1,9 +1,64 @@
|
|||||||
const { ipcMain } = require('electron');
|
const { ipcMain } = require('electron');
|
||||||
const { getPreferences, savePreferences } = require('../store/preferences');
|
const { getPreferences, savePreferences, getPath } = require('../store/preferences');
|
||||||
const { isDirectory } = require('../utils/filesystem');
|
const { isDirectory } = require('../utils/filesystem');
|
||||||
const { openCollection } = require('../app/collections');
|
const { openCollection } = require('../app/collections');
|
||||||
|
const stores = require('../store');
|
||||||
|
const chokidar = require('chokidar');
|
||||||
|
|
||||||
const registerPreferencesIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
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) => {
|
ipcMain.handle('renderer:ready', async (event) => {
|
||||||
// load preferences
|
// load preferences
|
||||||
const preferences = getPreferences();
|
const preferences = getPreferences();
|
||||||
@ -15,7 +70,7 @@ const registerPreferencesIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
|||||||
if (lastOpened && lastOpened.length) {
|
if (lastOpened && lastOpened.length) {
|
||||||
for (let collectionPath of lastOpened) {
|
for (let collectionPath of lastOpened) {
|
||||||
if (isDirectory(collectionPath)) {
|
if (isDirectory(collectionPath)) {
|
||||||
openCollection(mainWindow, watcher, collectionPath, {
|
await openCollection(mainWindow, watcher, collectionPath, {
|
||||||
dontSendDisplayErrors: true
|
dontSendDisplayErrors: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,18 @@ const preferencesSchema = Yup.object().shape({
|
|||||||
}),
|
}),
|
||||||
font: Yup.object().shape({
|
font: Yup.object().shape({
|
||||||
codeFont: Yup.string().nullable()
|
codeFont: Yup.string().nullable()
|
||||||
|
}),
|
||||||
|
proxy: Yup.object({
|
||||||
|
enabled: Yup.boolean(),
|
||||||
|
protocol: Yup.string().oneOf(['http', 'https', 'socks4', 'socks5']),
|
||||||
|
hostname: Yup.string().max(1024),
|
||||||
|
port: Yup.number().min(1).max(65535),
|
||||||
|
auth: Yup.object({
|
||||||
|
enabled: Yup.boolean(),
|
||||||
|
username: Yup.string().max(1024),
|
||||||
|
password: Yup.string().max(1024)
|
||||||
|
}).optional(),
|
||||||
|
noProxy: Yup.string().optional().max(1024)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -58,9 +70,13 @@ class PreferencesStore {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPath() {
|
||||||
|
return this.store.path;
|
||||||
|
}
|
||||||
|
|
||||||
getPreferences() {
|
getPreferences() {
|
||||||
return {
|
return {
|
||||||
defaultPreferences,
|
...defaultPreferences,
|
||||||
...this.store.get('preferences')
|
...this.store.get('preferences')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -90,17 +106,13 @@ const savePreferences = async (newPreferences) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const preferences = {
|
const getPath = () => {
|
||||||
getAll() {
|
|
||||||
return getPreferences();
|
|
||||||
},
|
|
||||||
|
|
||||||
getPath() {
|
|
||||||
return preferencesStore.getPath();
|
return preferencesStore.getPath();
|
||||||
},
|
};
|
||||||
|
|
||||||
|
const preferences = {
|
||||||
isTlsVerification: () => {
|
isTlsVerification: () => {
|
||||||
return get(getPreferences(), 'request.tlsVerification', true);
|
return get(getPreferences(), 'request.sslVerification', true);
|
||||||
},
|
},
|
||||||
|
|
||||||
getCaCert: () => {
|
getCaCert: () => {
|
||||||
@ -115,5 +127,6 @@ const preferences = {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
getPreferences,
|
getPreferences,
|
||||||
savePreferences,
|
savePreferences,
|
||||||
|
getPath,
|
||||||
preferences
|
preferences
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user