@@ -91,19 +94,26 @@ const Sidebar = () => {
dispatch(showPreferences(true))}
/>
+ setCookiesOpen(true)}
+ />
-
Star
-
+ */}
v1.1.1
diff --git a/packages/bruno-app/src/providers/App/useIpcEvents.js b/packages/bruno-app/src/providers/App/useIpcEvents.js
index e5c1bdb64..3f251f2fe 100644
--- a/packages/bruno-app/src/providers/App/useIpcEvents.js
+++ b/packages/bruno-app/src/providers/App/useIpcEvents.js
@@ -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]);
};
diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/app.js b/packages/bruno-app/src/providers/ReduxStore/slices/app.js
index 4605f051a..7d717722f 100644
--- a/packages/bruno-app/src/providers/ReduxStore/slices/app.js
+++ b/packages/bruno-app/src/providers/ReduxStore/slices/app.js
@@ -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) => {
diff --git a/packages/bruno-electron/package.json b/packages/bruno-electron/package.json
index 7fa75c1bc..6c91e90c7 100644
--- a/packages/bruno-electron/package.json
+++ b/packages/bruno-electron/package.json
@@ -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"
diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js
index d6afbe6f5..cef305f11 100644
--- a/packages/bruno-electron/src/ipc/network/index.js
+++ b/packages/bruno-electron/src/ipc/network/index.js
@@ -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,
diff --git a/packages/bruno-electron/src/utils/cookies.js b/packages/bruno-electron/src/utils/cookies.js
new file mode 100644
index 000000000..1ad535aa8
--- /dev/null
+++ b/packages/bruno-electron/src/utils/cookies.js
@@ -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
+};