mirror of
https://github.com/usebruno/bruno.git
synced 2024-12-26 00:29:11 +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()
|
||||
.when('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))
|
||||
})
|
||||
.min(1)
|
||||
@ -208,7 +208,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
value={formik.values.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}
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
@ -227,7 +227,9 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
onChange={formik.handleChange}
|
||||
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 className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="auth.enabled">
|
||||
@ -258,7 +260,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
{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}
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
@ -278,7 +280,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
{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}
|
||||
</div>
|
||||
</div>
|
||||
@ -299,7 +301,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
value={formik.values.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}
|
||||
</div>
|
||||
<div className="mt-6">
|
||||
|
@ -2,12 +2,55 @@ import React, { useEffect } from 'react';
|
||||
import { useFormik } from 'formik';
|
||||
import * as Yup from 'yup';
|
||||
import toast from 'react-hot-toast';
|
||||
import { savePreferences } from 'providers/ReduxStore/slices/app';
|
||||
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { usePreferences } from 'providers/Preferences';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
const ProxySettings = () => {
|
||||
const { preferences, setPreferences } = usePreferences();
|
||||
const ProxySettings = ({ close }) => {
|
||||
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({
|
||||
initialValues: {
|
||||
@ -22,35 +65,28 @@ const ProxySettings = () => {
|
||||
},
|
||||
noProxy: preferences.proxy.noProxy || ''
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
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)
|
||||
}),
|
||||
validationSchema: proxySchema,
|
||||
onSubmit: (values) => {
|
||||
onUpdate(values);
|
||||
}
|
||||
});
|
||||
|
||||
const onUpdate = (values) => {
|
||||
const updatedPreferences = {
|
||||
...preferences,
|
||||
proxy: values
|
||||
};
|
||||
|
||||
setPreferences(updatedPreferences)
|
||||
.then(() => {
|
||||
toast.success('Proxy settings updated successfully.');
|
||||
proxySchema
|
||||
.validate(values, { abortEarly: true })
|
||||
.then((validatedProxy) => {
|
||||
dispatch(
|
||||
savePreferences({
|
||||
...preferences,
|
||||
proxy: validatedProxy
|
||||
})
|
||||
).then(() => {
|
||||
close();
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
.catch((error) => {
|
||||
let errMsg = error.message || 'Preferences validation error';
|
||||
toast.error(errMsg);
|
||||
});
|
||||
};
|
||||
|
||||
@ -147,7 +183,7 @@ const ProxySettings = () => {
|
||||
value={formik.values.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}
|
||||
</div>
|
||||
<div className="ml-4 mb-3 flex items-center">
|
||||
@ -166,7 +202,9 @@ const ProxySettings = () => {
|
||||
onChange={formik.handleChange}
|
||||
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 className="ml-4 mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="auth.enabled">
|
||||
@ -197,7 +235,7 @@ const ProxySettings = () => {
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
{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}
|
||||
</div>
|
||||
<div className="ml-4 mb-3 flex items-center">
|
||||
@ -217,7 +255,7 @@ const ProxySettings = () => {
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
{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}
|
||||
</div>
|
||||
</div>
|
||||
@ -238,7 +276,7 @@ const ProxySettings = () => {
|
||||
value={formik.values.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}
|
||||
</div>
|
||||
<div className="mt-6">
|
||||
|
@ -87,22 +87,22 @@ const runSingleRequest = async function (
|
||||
const httpsAgentRequestFields = {};
|
||||
if (insecure) {
|
||||
httpsAgentRequestFields['rejectUnauthorized'] = false;
|
||||
}
|
||||
|
||||
const caCertArray = [options['cacert'], process.env.SSL_CERT_FILE, process.env.NODE_EXTRA_CA_CERTS];
|
||||
const caCert = caCertArray.find((el) => el);
|
||||
if (caCert && caCert.length > 1) {
|
||||
try {
|
||||
httpsAgentRequestFields['ca'] = fs.readFileSync(caCert);
|
||||
} catch (err) {
|
||||
console.log('Error reading CA cert file:' + caCert, err);
|
||||
} else {
|
||||
const caCertArray = [options['cacert'], process.env.SSL_CERT_FILE, process.env.NODE_EXTRA_CA_CERTS];
|
||||
const caCert = caCertArray.find((el) => el);
|
||||
if (caCert && caCert.length > 1) {
|
||||
try {
|
||||
httpsAgentRequestFields['ca'] = fs.readFileSync(caCert);
|
||||
} catch (err) {
|
||||
console.log('Error reading CA cert file:' + caCert, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set proxy if enabled
|
||||
const proxyEnabled = get(brunoConfig, 'proxy.enabled', false);
|
||||
const proxyByPass = shouldUseProxy(request.url, get(brunoConfig, 'proxy.noProxy', ''));
|
||||
if (proxyEnabled && !proxyByPass) {
|
||||
const shouldProxy = shouldUseProxy(request.url, get(brunoConfig, 'proxy.noProxy', ''));
|
||||
if (proxyEnabled && shouldProxy) {
|
||||
let proxyUri;
|
||||
const interpolationOptions = {
|
||||
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 { interpolateString } = require('./interpolate-string');
|
||||
const { sortFolder, getAllRequestsInFolderRecursively } = require('./helper');
|
||||
const preferences = 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');
|
||||
@ -84,23 +84,81 @@ const getSize = (data) => {
|
||||
return 0;
|
||||
};
|
||||
|
||||
function getHttpsAgentRequestFields() {
|
||||
const configureRequest = async (collectionUid, request, envVars, collectionVariables, processEnvVars) => {
|
||||
const httpsAgentRequestFields = {};
|
||||
if (!preferences.isTlsVerification()) {
|
||||
httpsAgentRequestFields['rejectUnauthorized'] = false;
|
||||
}
|
||||
|
||||
const cacCrtArray = [preferences.getCaCert(), process.env.SSL_CERT_FILE, process.env.NODE_EXTRA_CA_CERTS];
|
||||
let caCertFile = cacCrtArray.find((el) => el);
|
||||
if (caCertFile && caCertFile.length > 1) {
|
||||
try {
|
||||
httpsAgentRequestFields['ca'] = fs.readFileSync(caCertFile);
|
||||
} catch (err) {
|
||||
console.log('Error reading CA cert file:' + caCertFile, err);
|
||||
} else {
|
||||
const cacCrtArray = [preferences.getCaCert(), process.env.SSL_CERT_FILE, process.env.NODE_EXTRA_CA_CERTS];
|
||||
let caCertFile = cacCrtArray.find((el) => el);
|
||||
if (caCertFile && caCertFile.length > 1) {
|
||||
try {
|
||||
httpsAgentRequestFields['ca'] = fs.readFileSync(caCertFile);
|
||||
} catch (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) => {
|
||||
// handler for sending http request
|
||||
@ -224,64 +282,13 @@ const registerNetworkIpc = (mainWindow) => {
|
||||
cancelTokenUid
|
||||
});
|
||||
|
||||
const httpsAgentRequestFields = getHttpsAgentRequestFields();
|
||||
|
||||
// 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 proxyByPass = shouldUseProxy(request.url, get(proxyConfig, 'noProxy', ''));
|
||||
if ((proxyEnabled === true || proxyEnabled === 'enabled') && !proxyByPass) {
|
||||
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;
|
||||
}
|
||||
const axiosInstance = await configureRequest(
|
||||
collectionUid,
|
||||
request,
|
||||
envVars,
|
||||
collectionVariables,
|
||||
processEnvVars
|
||||
);
|
||||
|
||||
/** @type {import('axios').AxiosResponse} */
|
||||
const response = await axiosInstance(request);
|
||||
@ -684,60 +691,17 @@ const registerNetworkIpc = (mainWindow) => {
|
||||
...eventData
|
||||
});
|
||||
|
||||
const httpsAgentRequestFields = getHttpsAgentRequestFields();
|
||||
const axiosInstance = await configureRequest(
|
||||
collectionUid,
|
||||
request,
|
||||
envVars,
|
||||
collectionVariables,
|
||||
processEnvVars
|
||||
);
|
||||
|
||||
// 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 proxyByPass = shouldUseProxy(request.url, get(proxyConfig, 'noProxy', ''));
|
||||
if ((proxyEnabled === true || proxyEnabled === 'enabled') && !proxyByPass) {
|
||||
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
|
||||
});
|
||||
}
|
||||
|
||||
// send request
|
||||
timeStart = Date.now();
|
||||
const response = await axios(request);
|
||||
/** @type {import('axios').AxiosResponse} */
|
||||
const response = await axiosInstance(request);
|
||||
timeEnd = Date.now();
|
||||
|
||||
// run post-response vars
|
||||
|
@ -1,9 +1,64 @@
|
||||
const { ipcMain } = require('electron');
|
||||
const { getPreferences, savePreferences } = require('../store/preferences');
|
||||
const { getPreferences, savePreferences, getPath } = 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();
|
||||
@ -15,7 +70,7 @@ const registerPreferencesIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
||||
if (lastOpened && lastOpened.length) {
|
||||
for (let collectionPath of lastOpened) {
|
||||
if (isDirectory(collectionPath)) {
|
||||
openCollection(mainWindow, watcher, collectionPath, {
|
||||
await openCollection(mainWindow, watcher, collectionPath, {
|
||||
dontSendDisplayErrors: true
|
||||
});
|
||||
}
|
||||
|
@ -47,6 +47,18 @@ const preferencesSchema = Yup.object().shape({
|
||||
}),
|
||||
font: Yup.object().shape({
|
||||
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() {
|
||||
return {
|
||||
defaultPreferences,
|
||||
...defaultPreferences,
|
||||
...this.store.get('preferences')
|
||||
};
|
||||
}
|
||||
@ -90,17 +106,13 @@ const savePreferences = async (newPreferences) => {
|
||||
});
|
||||
};
|
||||
|
||||
const getPath = () => {
|
||||
return preferencesStore.getPath();
|
||||
};
|
||||
|
||||
const preferences = {
|
||||
getAll() {
|
||||
return getPreferences();
|
||||
},
|
||||
|
||||
getPath() {
|
||||
return preferencesStore.getPath();
|
||||
},
|
||||
|
||||
isTlsVerification: () => {
|
||||
return get(getPreferences(), 'request.tlsVerification', true);
|
||||
return get(getPreferences(), 'request.sslVerification', true);
|
||||
},
|
||||
|
||||
getCaCert: () => {
|
||||
@ -115,5 +127,6 @@ const preferences = {
|
||||
module.exports = {
|
||||
getPreferences,
|
||||
savePreferences,
|
||||
getPath,
|
||||
preferences
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user