Skip to content

Commit

Permalink
feat: initial mTLS support
Browse files Browse the repository at this point in the history
  • Loading branch information
phoval committed Oct 4, 2023
1 parent bf2d122 commit 59e5a42
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import styled from 'styled-components';

const StyledWrapper = styled.div`
color: ${(props) => props.theme.text};
.settings-label {
width: 80px;
}
`;

export default StyledWrapper;
50 changes: 50 additions & 0 deletions packages/bruno-app/src/components/Preferences/General/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useState } from 'react';
import toast from 'react-hot-toast';
import { usePreferences } from 'providers/Preferences';
import StyledWrapper from './StyledWrapper';

Expand All @@ -7,6 +8,11 @@ const General = () => {

const [sslVerification, setSslVerification] = useState(preferences.request.sslVerification);

const [mTlsDomain, setMTlsDomain] = useState(preferences.request.mTlsDomain);
const [mTlsCert, setMTlsCert] = useState(preferences.request.mTlsCert);
const [mTlsKey, setMTlsKey] = useState(preferences.request.mTlsKey);
const [mTlsPassphrase, setMtlPassphrase] = useState(preferences.request.mTlsPassphrase);

const handleCheckboxChange = () => {
const updatedPreferences = {
...preferences,
Expand All @@ -25,12 +31,56 @@ const General = () => {
});
};

const handleMTls = () => {
const updatedPreferences = {
...preferences,
request: {
...preferences.request,
mTlsDomain: mTlsDomain,
mTlsCert: mTlsCert,
mTlsKey: mTlsKey,
mTlsPassphrase: mTlsPassphrase
}
};
setPreferences(updatedPreferences)
.then(() => toast.success(`Mutual TLS config saved`));
}

return (
<StyledWrapper>
<div className="flex items-center mt-2">
<input type="checkbox" checked={sslVerification} onChange={handleCheckboxChange} className="mr-3 mousetrap" />
SSL Certificate Verification
</div>
<div className="mt-4">
<h1 className="font-medium mb-2">Mutual TLS</h1>

<div className="ml-4 mb-2 flex items-center">
<label className="settings-label">Domain</label>
<input type="text" placeholder="*.example.org" onChange={e => setMTlsDomain(e.target.value)} value={mTlsDomain} className="block textbox" />
</div>

<div className="ml-4 mb-2 flex items-center">
<label className="settings-label">Client cert</label>
<input type="file" onChange={e => setMTlsCert(e.target.files[0].path)} className="block textbox" />
</div>

<div className="ml-4 mb-2 flex items-center">
<label className="settings-label">Client key</label>
<input type="file" onChange={e => setMTlsKey(e.target.files[0].path)} className="block textbox" />
</div>

<div className="ml-4 mb-2 flex items-center">
<label className="settings-label">Passphrase</label>
<input type="text" onChange={e => setMtlPassphrase(e.target.value)} value={mTlsPassphrase} className="block textbox" />
</div>

<div className="mt-8 ml-4">
<button onClick={handleMTls} className="submit btn btn-md btn-secondary">
Save mTLS
</button>
</div>
</div>
</StyledWrapper>
);
};
Expand Down
12 changes: 10 additions & 2 deletions packages/bruno-app/src/providers/Preferences/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,21 @@ import toast from 'react-hot-toast';

const defaultPreferences = {
request: {
sslVerification: true
sslVerification: true,
mTlsDomain: null,
mTlsCert: null,
mTlsKey: null,
mTlsPassphrase: null,
}
};

const preferencesSchema = Yup.object().shape({
request: Yup.object().shape({
sslVerification: Yup.boolean()
sslVerification: Yup.boolean(),
mTlsDomain: Yup.string().nullable(),
mTlsCert: Yup.string().nullable(),
mTlsKey: Yup.string().nullable(),
mTlsPassphrase: Yup.string().nullable()
})
});

Expand Down
21 changes: 20 additions & 1 deletion packages/bruno-electron/src/ipc/network/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const qs = require('qs');
const fs = require('fs');
const https = require('https');
const axios = require('axios');
const Mustache = require('mustache');
Expand Down Expand Up @@ -225,7 +226,6 @@ const registerNetworkIpc = (mainWindow) => {
cacertFile = cacertArray.find((el) => el);
if (cacertFile && cacertFile.length > 1) {
try {
const fs = require('fs');
caCrt = fs.readFileSync(cacertFile);
httpsAgentRequestFields['ca'] = caCrt;
} catch (err) {
Expand All @@ -234,6 +234,25 @@ const registerNetworkIpc = (mainWindow) => {
}
}

const mTlsDomain = get(preferences, 'request.mTlsDomain', null);
const mTlsCert = get(preferences, 'request.mTlsCert', null);
const mTlsKey = get(preferences, 'request.mTlsKey', null);
const mTlsPassphrase = get(preferences, 'request.mTlsPassphrase', null);

if (mTlsDomain && mTlsCert && mTlsKey) {
const hostRegex = '^https:\\\/\\\/' + mTlsDomain.replaceAll('.', '\\.').replaceAll('*', '.*');

if (request.url.match(hostRegex)) {
try {
httpsAgentRequestFields['cert'] = fs.readFileSync(mTlsCert);
httpsAgentRequestFields['key'] = fs.readFileSync(mTlsKey);
} catch (err) {
console.log('Error loading mTLS cert/key', err);
}
httpsAgentRequestFields['passphrase'] = mTlsPassphrase;
}
}

if (Object.keys(httpsAgentRequestFields).length > 0) {
request.httpsAgent = new https.Agent({
...httpsAgentRequestFields
Expand Down

0 comments on commit 59e5a42

Please sign in to comment.