Merge pull request #2654 from mozilla/feat-#303

#303: Reset cookies in site manager
This commit is contained in:
luke crouch
2024-08-28 11:26:57 -05:00
committed by GitHub
9 changed files with 205 additions and 12 deletions
+10
View File
@@ -577,6 +577,16 @@ window.assignManager = {
return true;
},
async _resetCookiesForSite(hostname, cookieStoreId) {
const hostNameTruncated = hostname.replace(/^www\./, ""); // Remove "www." from the hostname
await browser.browsingData.removeCookies({
cookieStoreId: cookieStoreId,
hostnames: [hostNameTruncated] // This does not remove cookies from associated domains. To remove all cookies, we have a container storage removal option.
});
return true;
},
async _setOrRemoveAssignment(tabId, pageUrl, userContextId, remove) {
let actionName;
// https://github.com/mozilla/testpilot-containers/issues/626
+13
View File
@@ -75,6 +75,19 @@ const backgroundLogic = {
return extensionInfo;
},
// Remove container data (cookies, localStorage and cache)
async deleteContainerDataOnly(userContextId) {
await browser.browsingData.removeCookies({
cookieStoreId: this.cookieStoreId(userContextId)
});
await browser.browsingData.removeLocalStorage({
cookieStoreId: this.cookieStoreId(userContextId)
});
return {done: true, userContextId};
},
getUserContextIdFromCookieStoreId(cookieStoreId) {
if (!cookieStoreId) {
return false;
+6
View File
@@ -23,6 +23,9 @@ const messageHandler = {
case "deleteContainer":
response = backgroundLogic.deleteContainer(m.message.userContextId);
break;
case "deleteContainerDataOnly":
response = backgroundLogic.deleteContainerDataOnly(m.message.userContextId);
break;
case "createOrUpdateContainer":
response = backgroundLogic.createOrUpdateContainer(m.message);
break;
@@ -45,6 +48,9 @@ const messageHandler = {
// m.url is the assignment to be removed/added
response = assignManager._setOrRemoveAssignment(m.tabId, m.url, m.userContextId, m.value);
break;
case "resetCookiesForSite":
response = assignManager._resetCookiesForSite(m.pageUrl, m.cookieStoreId);
break;
case "sortTabs":
backgroundLogic.sortTabs();
break;
+81 -1
View File
@@ -32,6 +32,7 @@ const P_CONTAINER_EDIT = "containerEdit";
const P_CONTAINER_DELETE = "containerDelete";
const P_CONTAINERS_ACHIEVEMENT = "containersAchievement";
const P_CONTAINER_ASSIGNMENTS = "containerAssignments";
const P_CLEAR_CONTAINER_STORAGE = "clearContainerStorage";
const P_MOZILLA_VPN_SERVER_LIST = "moz-vpn-server-list";
const P_ADVANCED_PROXY_SETTINGS = "advanced-proxy-settings-panel";
@@ -122,6 +123,19 @@ const Logic = {
},
notify(i18nOpts) {
const notificationCards = document.querySelectorAll(".popup-notification-card");
const text = browser.i18n.getMessage(i18nOpts.messageId, i18nOpts.placeholders);
notificationCards.forEach(notificationCard => {
notificationCard.textContent = text;
notificationCard.classList.add("is-shown");
setTimeout(() => {
notificationCard.classList.remove("is-shown");
}, 2000);
});
},
async showAchievementOrContainersListPanel() {
// Do we need to show an achievement panel?
let showAchievements = false;
@@ -971,6 +985,7 @@ Logic.registerPanel(P_CONTAINER_INFO, {
Utils.alwaysOpenInContainer(identity);
window.close();
});
// Show or not the has-tabs section.
for (let trHasTabs of document.getElementsByClassName("container-info-has-tabs")) { // eslint-disable-line prefer-const
trHasTabs.style.display = !identity.hasHiddenTabs && !identity.hasOpenTabs ? "none" : "";
@@ -994,6 +1009,13 @@ Logic.registerPanel(P_CONTAINER_INFO, {
Utils.addEnterHandler(manageContainer, async () => {
Logic.showPanel(P_CONTAINER_EDIT, identity);
});
const clearContainerStorageButton = document.getElementById("clear-container-storage-info");
Utils.addEnterHandler(clearContainerStorageButton, async () => {
const granted = await browser.permissions.request({ permissions: ["browsingData"] });
if (granted) {
Logic.showPanel(P_CLEAR_CONTAINER_STORAGE, identity);
}
});
return this.buildOpenTabTable(tabs);
},
@@ -1455,11 +1477,14 @@ Logic.registerPanel(P_CONTAINER_ASSIGNMENTS, {
/* As we don't have the full or correct path the best we can assume is the path is HTTPS and then replace with a broken icon later if it doesn't load.
This is pending a better solution for favicons from web extensions */
const assumedUrl = `https://${site.hostname}/favicon.ico`;
const resetSiteCookiesInfo = browser.i18n.getMessage("clearSiteCookiesTooltipInfo");
const deleteSiteInfo = browser.i18n.getMessage("deleteSiteTooltipInfo");
trElement.innerHTML = Utils.escaped`
<td>
<div class="favicon"></div>
<span title="${site.hostname}" class="menu-text truncate-text">${site.hostname}</span>
<img class="trash-button delete-assignment" src="/img/container-delete.svg" />
<img title="${resetSiteCookiesInfo}" class="reset-button reset-assignment" src="/img/refresh-16.svg" />
<img title="${deleteSiteInfo}" class="trash-button delete-assignment" src="/img/container-delete.svg" />
</td>`;
trElement.getElementsByClassName("favicon")[0].appendChild(Utils.createFavIconElement(assumedUrl));
const deleteButton = trElement.querySelector(".trash-button");
@@ -1471,6 +1496,20 @@ Logic.registerPanel(P_CONTAINER_ASSIGNMENTS, {
delete assignments[siteKey];
this.showAssignedContainers(assignments);
});
const resetButton = trElement.querySelector(".reset-button");
Utils.addEnterHandler(resetButton, async () => {
const cookieStoreId = Logic.currentCookieStoreId();
const granted = await browser.permissions.request({ permissions: ["browsingData"] });
if (!granted) {
return;
}
const result = await Utils.resetCookiesForSite(site.hostname, cookieStoreId);
if (result === true) {
Logic.notify({messageId: "cookiesClearedSuccess", placeholders: [site.hostname]});
} else {
Logic.notify({messageId: "cookiesCouldNotBeCleared", placeholders: [site.hostname]});
}
});
trElement.classList.add("menu-item", "hover-highlight", "keyboard-nav");
tableElement.appendChild(trElement);
});
@@ -2246,6 +2285,47 @@ Logic.registerPanel(P_MOZILLA_VPN_SERVER_LIST, {
}
});
// P_CLEAR_CONTAINER_STORAGE: Page for confirming container storage removal.
// ----------------------------------------------------------------------------
Logic.registerPanel(P_CLEAR_CONTAINER_STORAGE, {
panelSelector: "#clear-container-storage-panel",
// This method is called when the object is registered.
initialize() {
Utils.addEnterHandler(document.querySelector("#clear-container-storage-cancel-link"), () => {
const identity = Logic.currentIdentity();
Logic.showPanel(P_CONTAINER_INFO, identity, false, false);
});
Utils.addEnterHandler(document.querySelector("#close-clear-container-storage-panel"), () => {
const identity = Logic.currentIdentity();
Logic.showPanel(P_CONTAINER_INFO, identity, false, false);
});
Utils.addEnterHandler(document.querySelector("#clear-container-storage-ok-link"), async () => {
const identity = Logic.currentIdentity();
const userContextId = Utils.userContextId(identity.cookieStoreId);
const result = await browser.runtime.sendMessage({
method: "deleteContainerDataOnly",
message: { userContextId }
});
if (result.done === true) {
Logic.notify({messageId: "storageWasClearedConfirmation", placeholders: [identity.name]});
}
Logic.showPanel(P_CONTAINER_INFO, identity, false, false);
});
},
// This method is called when the panel is shown.
prepare() {
const identity = Logic.currentIdentity();
// Populating the panel: name, icon, and warning message
document.getElementById("container-clear-storage-title").textContent = identity.name;
return Promise.resolve(null);
},
});
// P_CONTAINER_DELETE: Delete a container.
// ----------------------------------------------------------------------------
+8
View File
@@ -138,6 +138,14 @@ const Utils = {
});
},
resetCookiesForSite(pageUrl, cookieStoreId) {
return browser.runtime.sendMessage({
method: "resetCookiesForSite",
pageUrl,
cookieStoreId,
});
},
async reloadInContainer(url, currentUserContextId, newUserContextId, tabIndex, active) {
return await browser.runtime.sendMessage({
method: "reloadInContainer",