diff --git a/packages/bruno-app/src/components/Cookies/StyledWrapper.js b/packages/bruno-app/src/components/Cookies/StyledWrapper.js new file mode 100644 index 000000000..102558382 --- /dev/null +++ b/packages/bruno-app/src/components/Cookies/StyledWrapper.js @@ -0,0 +1,16 @@ +import styled from 'styled-components'; + +const Wrapper = styled.div` + table { + width: 100%; + table-layout: fixed; + + thead { + color: ${(props) => props.theme.table.thead.color}; + font-size: 0.8125rem; + user-select: none; + } + } +`; + +export default Wrapper; diff --git a/packages/bruno-app/src/components/Cookies/index.js b/packages/bruno-app/src/components/Cookies/index.js index f57d19213..f7420bed8 100644 --- a/packages/bruno-app/src/components/Cookies/index.js +++ b/packages/bruno-app/src/components/Cookies/index.js @@ -1,28 +1,52 @@ import React from 'react'; -import { useSelector } from 'react-redux'; +import { useSelector, useDispatch } from 'react-redux'; import Modal from 'components/Modal'; +import { IconTrash } from '@tabler/icons'; +import { deleteCookiesForDomain } from 'providers/ReduxStore/slices/app'; +import toast from 'react-hot-toast'; + +import StyledWrapper from './StyledWrapper'; const CollectionProperties = ({ onClose }) => { + const dispatch = useDispatch(); const cookies = useSelector((state) => state.app.cookies) || []; + const handleDeleteDomain = (domain) => { + dispatch(deleteCookiesForDomain(domain)) + .then(() => { + toast.success('Domain deleted successfully'); + }) + .catch((err) => console.log(err) && toast.error('Failed to delete domain')); + }; + return ( - - - - - - - - - {cookies.map((cookie) => ( - - - + +
DomainCookie
{cookie.domain}{cookie.cookieString}
+ + + + + - ))} - -
DomainCookie + Actions +
+ + + {cookies.map((cookie) => ( + + {cookie.domain} + {cookie.cookieString} + + + + + ))} + + +
); }; diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/app.js b/packages/bruno-app/src/providers/ReduxStore/slices/app.js index 7d717722f..0b65a714a 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/app.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/app.js @@ -84,4 +84,12 @@ export const savePreferences = (preferences) => (dispatch, getState) => { }); }; +export const deleteCookiesForDomain = (domain) => (dispatch, getState) => { + return new Promise((resolve, reject) => { + const { ipcRenderer } = window; + + ipcRenderer.invoke('renderer:delete-cookies-for-domain', domain).then(resolve).catch(reject); + }); +}; + export default appSlice.reducer; diff --git a/packages/bruno-electron/src/ipc/collection.js b/packages/bruno-electron/src/ipc/collection.js index fc1e1444e..ba19cfaf2 100644 --- a/packages/bruno-electron/src/ipc/collection.js +++ b/packages/bruno-electron/src/ipc/collection.js @@ -14,10 +14,10 @@ const { searchForBruFiles, sanitizeDirectoryName } = require('../utils/filesystem'); -const { stringifyJson } = require('../utils/common'); const { openCollectionDialog } = require('../app/collections'); -const { generateUidBasedOnHash } = require('../utils/common'); +const { generateUidBasedOnHash, stringifyJson, safeParseJSON, safeStringifyJSON } = require('../utils/common'); const { moveRequestUid, deleteRequestUid } = require('../cache/requestUids'); +const { deleteCookiesForDomain, getDomainsWithCookies } = require('../utils/cookies'); const EnvironmentSecretsStore = require('../store/env-secrets'); const environmentSecretsStore = new EnvironmentSecretsStore(); @@ -511,6 +511,17 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection return Promise.reject(new Error('Failed to load GraphQL schema file')); } }); + + ipcMain.handle('renderer:delete-cookies-for-domain', async (event, domain) => { + try { + await deleteCookiesForDomain(domain); + + const domainsWithCookies = await getDomainsWithCookies(); + mainWindow.webContents.send('main:cookies-update', safeParseJSON(safeStringifyJSON(domainsWithCookies))); + } catch (error) { + return Promise.reject(error); + } + }); }; const registerMainEventHandlers = (mainWindow, watcher, lastOpenedCollections) => { diff --git a/packages/bruno-electron/src/utils/common.js b/packages/bruno-electron/src/utils/common.js index 83d22c7ce..50b17bb38 100644 --- a/packages/bruno-electron/src/utils/common.js +++ b/packages/bruno-electron/src/utils/common.js @@ -25,6 +25,22 @@ const parseJson = async (obj) => { } }; +const safeStringifyJSON = (data) => { + try { + return JSON.stringify(data); + } catch (e) { + return data; + } +}; + +const safeParseJSON = (data) => { + try { + return JSON.parse(data); + } catch (e) { + return data; + } +}; + const simpleHash = (str) => { let hash = 0; for (let i = 0; i < str.length; i++) { @@ -73,6 +89,8 @@ module.exports = { uuid, stringifyJson, parseJson, + safeStringifyJSON, + safeParseJSON, simpleHash, generateUidBasedOnHash, flattenDataForDotNotation diff --git a/packages/bruno-electron/src/utils/cookies.js b/packages/bruno-electron/src/utils/cookies.js index a6d5ce665..5b4d7fc7c 100644 --- a/packages/bruno-electron/src/utils/cookies.js +++ b/packages/bruno-electron/src/utils/cookies.js @@ -64,9 +64,22 @@ const getDomainsWithCookies = () => { }); }; +const deleteCookiesForDomain = (domain) => { + return new Promise((resolve, reject) => { + cookieJar.store.removeCookies(domain, null, (err) => { + if (err) { + return reject(err); + } + + return resolve(); + }); + }); +}; + module.exports = { addCookieToJar, getCookiesForUrl, getCookieStringForUrl, - getDomainsWithCookies + getDomainsWithCookies, + deleteCookiesForDomain };