forked from extern/bruno
feat(#968): cookie support
This commit is contained in:
parent
9f535aeba7
commit
e1a96e0f23
42
package-lock.json
generated
42
package-lock.json
generated
@ -17745,6 +17745,7 @@
|
||||
"node-machine-id": "^1.1.12",
|
||||
"qs": "^6.11.0",
|
||||
"socks-proxy-agent": "^8.0.2",
|
||||
"tough-cookie": "^4.1.3",
|
||||
"uuid": "^9.0.0",
|
||||
"vm2": "^3.9.13",
|
||||
"yup": "^0.32.11"
|
||||
@ -17905,6 +17906,28 @@
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"packages/bruno-electron/node_modules/tough-cookie": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
||||
"integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
|
||||
"dependencies": {
|
||||
"psl": "^1.1.33",
|
||||
"punycode": "^2.1.1",
|
||||
"universalify": "^0.2.0",
|
||||
"url-parse": "^1.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"packages/bruno-electron/node_modules/tough-cookie/node_modules/universalify": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
|
||||
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"packages/bruno-electron/node_modules/uuid": {
|
||||
"version": "9.0.0",
|
||||
"license": "MIT",
|
||||
@ -22828,6 +22851,7 @@
|
||||
"node-machine-id": "^1.1.12",
|
||||
"qs": "^6.11.0",
|
||||
"socks-proxy-agent": "^8.0.2",
|
||||
"tough-cookie": "*",
|
||||
"uuid": "^9.0.0",
|
||||
"vm2": "^3.9.13",
|
||||
"yup": "^0.32.11"
|
||||
@ -22926,6 +22950,24 @@
|
||||
"argparse": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
||||
"integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
|
||||
"requires": {
|
||||
"psl": "^1.1.33",
|
||||
"punycode": "^2.1.1",
|
||||
"universalify": "^0.2.0",
|
||||
"url-parse": "^1.5.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"universalify": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
|
||||
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"uuid": {
|
||||
"version": "9.0.0"
|
||||
}
|
||||
|
30
packages/bruno-app/src/components/Cookies/index.js
Normal file
30
packages/bruno-app/src/components/Cookies/index.js
Normal file
@ -0,0 +1,30 @@
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import Modal from 'components/Modal';
|
||||
|
||||
const CollectionProperties = ({ onClose }) => {
|
||||
const cookies = useSelector((state) => state.app.cookies) || [];
|
||||
|
||||
return (
|
||||
<Modal size="md" title="Cookies" hideFooter={true} handleCancel={onClose}>
|
||||
<table className="w-full border-collapse" style={{ marginTop: '-1rem' }}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="py-2 px-2 text-left">Domain</th>
|
||||
<th className="py-2 px-2 text-left">Cookie</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{cookies.map((cookie) => (
|
||||
<tr key={cookie.id}>
|
||||
<td className="py-2 px-2">{cookie.domain}</td>
|
||||
<td className="py-2 px-2 break-all">{cookie.cookieString}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default CollectionProperties;
|
@ -3,10 +3,11 @@ import Collections from './Collections';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import GitHubButton from 'react-github-btn';
|
||||
import Preferences from 'components/Preferences';
|
||||
import Cookies from 'components/Cookies';
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import { IconSettings } from '@tabler/icons';
|
||||
import { IconSettings, IconCookie } from '@tabler/icons';
|
||||
import { updateLeftSidebarWidth, updateIsDragging, showPreferences } from 'providers/ReduxStore/slices/app';
|
||||
import { useTheme } from 'providers/Theme';
|
||||
|
||||
@ -18,6 +19,7 @@ const Sidebar = () => {
|
||||
const preferencesOpen = useSelector((state) => state.app.showPreferences);
|
||||
|
||||
const [asideWidth, setAsideWidth] = useState(leftSidebarWidth);
|
||||
const [cookiesOpen, setCookiesOpen] = useState(false);
|
||||
|
||||
const { storedTheme } = useTheme();
|
||||
|
||||
@ -79,6 +81,7 @@ const Sidebar = () => {
|
||||
<aside>
|
||||
<div className="flex flex-row h-screen w-full">
|
||||
{preferencesOpen && <Preferences onClose={() => dispatch(showPreferences(false))} />}
|
||||
{cookiesOpen && <Cookies onClose={() => setCookiesOpen(false)} />}
|
||||
|
||||
<div className="flex flex-col w-full" style={{ width: asideWidth }}>
|
||||
<div className="flex flex-col flex-grow">
|
||||
@ -91,19 +94,26 @@ const Sidebar = () => {
|
||||
<IconSettings
|
||||
size={18}
|
||||
strokeWidth={1.5}
|
||||
className="mr-2 hover:text-gray-700"
|
||||
className="mr-2 hover:text-gray-700"
|
||||
onClick={() => dispatch(showPreferences(true))}
|
||||
/>
|
||||
<IconCookie
|
||||
size={18}
|
||||
strokeWidth={1.5}
|
||||
className="mr-2 hover:text-gray-700"
|
||||
onClick={() => setCookiesOpen(true)}
|
||||
/>
|
||||
</div>
|
||||
<div className="pl-1" style={{ position: 'relative', top: '3px' }}>
|
||||
<GitHubButton
|
||||
{/* This will get moved to home page */}
|
||||
{/* <GitHubButton
|
||||
href="https://github.com/usebruno/bruno"
|
||||
data-color-scheme={storedTheme}
|
||||
data-show-count="true"
|
||||
aria-label="Star usebruno/bruno on GitHub"
|
||||
>
|
||||
Star
|
||||
</GitHubButton>
|
||||
</GitHubButton> */}
|
||||
</div>
|
||||
<div className="flex flex-grow items-center justify-end text-xs mr-2">v1.1.1</div>
|
||||
</div>
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
runFolderEvent,
|
||||
brunoConfigUpdateEvent
|
||||
} from 'providers/ReduxStore/slices/collections';
|
||||
import { showPreferences, updatePreferences } from 'providers/ReduxStore/slices/app';
|
||||
import { showPreferences, updatePreferences, updateCookies } from 'providers/ReduxStore/slices/app';
|
||||
import toast from 'react-hot-toast';
|
||||
import { openCollectionEvent, collectionAddEnvFileEvent } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import { isElectron } from 'utils/common/platform';
|
||||
@ -135,6 +135,10 @@ const useIpcEvents = () => {
|
||||
dispatch(updatePreferences(val));
|
||||
});
|
||||
|
||||
const removeCookieUpdateListener = ipcRenderer.on('main:cookies-update', (val) => {
|
||||
dispatch(updateCookies(val));
|
||||
});
|
||||
|
||||
return () => {
|
||||
removeCollectionTreeUpdateListener();
|
||||
removeOpenCollectionListener();
|
||||
@ -149,6 +153,7 @@ const useIpcEvents = () => {
|
||||
removeConfigUpdatesListener();
|
||||
showPreferencesListener();
|
||||
removePreferencesUpdatesListener();
|
||||
removeCookieUpdateListener();
|
||||
};
|
||||
}, [isElectron]);
|
||||
};
|
||||
|
@ -16,7 +16,8 @@ const initialState = {
|
||||
font: {
|
||||
codeFont: 'default'
|
||||
}
|
||||
}
|
||||
},
|
||||
cookies: []
|
||||
};
|
||||
|
||||
export const appSlice = createSlice({
|
||||
@ -46,6 +47,10 @@ export const appSlice = createSlice({
|
||||
},
|
||||
updatePreferences: (state, action) => {
|
||||
state.preferences = action.payload;
|
||||
},
|
||||
updateCookies: (state, action) => {
|
||||
state.cookies = action.payload;
|
||||
console.log(state.cookies);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -58,7 +63,8 @@ export const {
|
||||
showHomePage,
|
||||
hideHomePage,
|
||||
showPreferences,
|
||||
updatePreferences
|
||||
updatePreferences,
|
||||
updateCookies
|
||||
} = appSlice.actions;
|
||||
|
||||
export const savePreferences = (preferences) => (dispatch, getState) => {
|
||||
|
@ -50,6 +50,7 @@
|
||||
"node-machine-id": "^1.1.12",
|
||||
"qs": "^6.11.0",
|
||||
"socks-proxy-agent": "^8.0.2",
|
||||
"tough-cookie": "^4.1.3",
|
||||
"uuid": "^9.0.0",
|
||||
"vm2": "^3.9.13",
|
||||
"yup": "^0.32.11"
|
||||
|
@ -28,6 +28,7 @@ const { addAwsV4Interceptor, resolveAwsV4Credentials } = require('./awsv4auth-he
|
||||
const { addDigestInterceptor } = require('./digestauth-helper');
|
||||
const { shouldUseProxy, PatchedHttpsProxyAgent } = require('../../utils/proxy-util');
|
||||
const { chooseFileToSave, writeBinaryFile } = require('../../utils/filesystem');
|
||||
const { getCookieStringForUrl, addCookieToJar, getDomainsWithCookies } = require('../../utils/cookies');
|
||||
|
||||
// override the default escape function to prevent escaping
|
||||
Mustache.escape = function (value) {
|
||||
@ -181,6 +182,12 @@ const configureRequest = async (
|
||||
|
||||
request.timeout = preferencesUtil.getRequestTimeout();
|
||||
|
||||
// add cookies to request
|
||||
const cookieString = getCookieStringForUrl(request.url);
|
||||
if (cookieString && typeof cookieString === 'string' && cookieString.length) {
|
||||
request.headers['cookie'] = cookieString;
|
||||
}
|
||||
|
||||
return axiosInstance;
|
||||
};
|
||||
|
||||
@ -439,6 +446,22 @@ const registerNetworkIpc = (mainWindow) => {
|
||||
const { data, dataBuffer } = parseDataFromResponse(response);
|
||||
response.data = data;
|
||||
|
||||
// save cookies
|
||||
let setCookieHeaders = [];
|
||||
if (response.headers['set-cookie']) {
|
||||
setCookieHeaders = Array.isArray(response.headers['set-cookie'])
|
||||
? response.headers['set-cookie']
|
||||
: [response.headers['set-cookie']];
|
||||
|
||||
for (let setCookieHeader of setCookieHeaders) {
|
||||
addCookieToJar(setCookieHeader, request.url);
|
||||
}
|
||||
}
|
||||
|
||||
// send domain cookies to renderer
|
||||
const domainsWithCookies = await getDomainsWithCookies();
|
||||
mainWindow.webContents.send('main:cookies-update', safeParseJSON(safeStringifyJSON(domainsWithCookies)));
|
||||
|
||||
await runPostResponse(
|
||||
request,
|
||||
response,
|
||||
|
70
packages/bruno-electron/src/utils/cookies.js
Normal file
70
packages/bruno-electron/src/utils/cookies.js
Normal file
@ -0,0 +1,70 @@
|
||||
const { Cookie, CookieJar } = require('tough-cookie');
|
||||
const each = require('lodash/each');
|
||||
|
||||
const cookieJar = new CookieJar();
|
||||
|
||||
const addCookieToJar = (setCookieHeader, requestUrl) => {
|
||||
const cookie = Cookie.parse(setCookieHeader, { loose: true });
|
||||
cookieJar.setCookieSync(cookie, requestUrl);
|
||||
};
|
||||
|
||||
const getCookiesForUrl = (url) => {
|
||||
return cookieJar.getCookiesSync(url);
|
||||
};
|
||||
|
||||
const getCookieStringForUrl = (url) => {
|
||||
const cookies = getCookiesForUrl(url);
|
||||
|
||||
if (!Array.isArray(cookies) || !cookies.length) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const validCookies = cookies.filter((cookie) => !cookie.expires || cookie.expires > Date.now());
|
||||
|
||||
return validCookies.map((cookie) => cookie.cookieString()).join('; ');
|
||||
};
|
||||
|
||||
const getDomainsWithCookies = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const domainCookieMap = {};
|
||||
|
||||
cookieJar.store.getAllCookies((err, cookies) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
cookies.forEach((cookie) => {
|
||||
if (!domainCookieMap[cookie.domain]) {
|
||||
domainCookieMap[cookie.domain] = [cookie];
|
||||
} else {
|
||||
domainCookieMap[cookie.domain].push(cookie);
|
||||
}
|
||||
});
|
||||
|
||||
const domains = Object.keys(domainCookieMap);
|
||||
const domainsWithCookies = [];
|
||||
|
||||
each(domains, (domain) => {
|
||||
const cookies = domainCookieMap[domain];
|
||||
const validCookies = cookies.filter((cookie) => !cookie.expires || cookie.expires > Date.now());
|
||||
|
||||
if (validCookies.length) {
|
||||
domainsWithCookies.push({
|
||||
domain,
|
||||
cookies: validCookies,
|
||||
cookieString: validCookies.map((cookie) => cookie.cookieString()).join('; ')
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
resolve(domainsWithCookies);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
addCookieToJar,
|
||||
getCookiesForUrl,
|
||||
getCookieStringForUrl,
|
||||
getDomainsWithCookies
|
||||
};
|
Loading…
Reference in New Issue
Block a user