diff options
-rw-r--r-- | devtools/client/locales/en-US/storage.dtd | 3 | ||||
-rw-r--r-- | devtools/client/storage/storage.xul | 4 | ||||
-rw-r--r-- | devtools/client/storage/test/browser_storage_basic.js | 11 | ||||
-rw-r--r-- | devtools/client/storage/test/browser_storage_cookies_delete_all.js | 72 | ||||
-rw-r--r-- | devtools/client/storage/test/browser_storage_delete_tree.js | 4 | ||||
-rw-r--r-- | devtools/client/storage/test/storage-listings.html | 5 | ||||
-rw-r--r-- | devtools/client/storage/test/storage-secured-iframe.html | 5 | ||||
-rw-r--r-- | devtools/client/storage/test/storage-unsecured-iframe.html | 3 | ||||
-rw-r--r-- | devtools/client/storage/ui.js | 82 | ||||
-rw-r--r-- | devtools/server/actors/storage.js | 23 | ||||
-rw-r--r-- | devtools/shared/specs/storage.js | 8 |
11 files changed, 186 insertions, 34 deletions
diff --git a/devtools/client/locales/en-US/storage.dtd b/devtools/client/locales/en-US/storage.dtd index 211c79436..adfc03183 100644 --- a/devtools/client/locales/en-US/storage.dtd +++ b/devtools/client/locales/en-US/storage.dtd @@ -9,3 +9,6 @@ <!-- LOCALIZATION NOTE : Label of popup menu action to delete all storage items. --> <!ENTITY storage.popupMenu.deleteAllLabel "Delete All"> + +<!-- LOCALIZATION NOTE : Label of popup menu action to delete all session cookies. --> +<!ENTITY storage.popupMenu.deleteAllSessionCookiesLabel "Delete All Session Cookies"> diff --git a/devtools/client/storage/storage.xul b/devtools/client/storage/storage.xul index 9fbef5199..85425912c 100644 --- a/devtools/client/storage/storage.xul +++ b/devtools/client/storage/storage.xul @@ -26,6 +26,8 @@ <menupopup id="storage-tree-popup"> <menuitem id="storage-tree-popup-delete-all" label="&storage.popupMenu.deleteAllLabel;"/> + <menuitem id="storage-tree-popup-delete-all-session-cookies" + label="&storage.popupMenu.deleteAllSessionCookiesLabel;"/> <menuitem id="storage-tree-popup-delete"/> </menupopup> <menupopup id="storage-table-popup"> @@ -33,6 +35,8 @@ <menuitem id="storage-table-popup-delete-all-from"/> <menuitem id="storage-table-popup-delete-all" label="&storage.popupMenu.deleteAllLabel;"/> + <menuitem id="storage-table-popup-delete-all-session-cookies" + label="&storage.popupMenu.deleteAllSessionCookiesLabel;"/> </menupopup> </popupset> diff --git a/devtools/client/storage/test/browser_storage_basic.js b/devtools/client/storage/test/browser_storage_basic.js index 72582e32f..7585eed1f 100644 --- a/devtools/client/storage/test/browser_storage_basic.js +++ b/devtools/client/storage/test/browser_storage_basic.js @@ -29,15 +29,22 @@ const testCases = [ getCookieId("c1", "test1.example.org", "/browser"), getCookieId("cs2", ".example.org", "/"), getCookieId("c3", "test1.example.org", "/"), - getCookieId("uc1", ".example.org", "/") + getCookieId("c4", ".example.org", "/"), + getCookieId("uc1", ".example.org", "/"), + getCookieId("uc2", ".example.org", "/") ] ], [ ["cookies", "sectest1.example.org"], [ getCookieId("uc1", ".example.org", "/"), + getCookieId("uc2", ".example.org", "/"), getCookieId("cs2", ".example.org", "/"), - getCookieId("sc1", "sectest1.example.org", "/browser/devtools/client/storage/test/") + getCookieId("c4", ".example.org", "/"), + getCookieId("sc1", "sectest1.example.org", + "/browser/devtools/client/storage/test/"), + getCookieId("sc2", "sectest1.example.org", + "/browser/devtools/client/storage/test/") ] ], [["localStorage", "http://test1.example.org"], diff --git a/devtools/client/storage/test/browser_storage_cookies_delete_all.js b/devtools/client/storage/test/browser_storage_cookies_delete_all.js index ba64014fd..4640ebecb 100644 --- a/devtools/client/storage/test/browser_storage_cookies_delete_all.js +++ b/devtools/client/storage/test/browser_storage_cookies_delete_all.js @@ -8,11 +8,13 @@ // Test deleting all cookies -function* performDelete(store, rowName, deleteAll) { +function* performDelete(store, rowName, action) { let contextMenu = gPanelWindow.document.getElementById( "storage-table-popup"); let menuDeleteAllItem = contextMenu.querySelector( "#storage-table-popup-delete-all"); + let menuDeleteAllSessionCookiesItem = contextMenu.querySelector( + "#storage-table-popup-delete-all-session-cookies"); let menuDeleteAllFromItem = contextMenu.querySelector( "#storage-table-popup-delete-all-from"); @@ -25,13 +27,19 @@ function* performDelete(store, rowName, deleteAll) { yield waitForContextMenu(contextMenu, cells.name, () => { info(`Opened context menu in ${storeName}, row '${rowName}'`); - if (deleteAll) { - menuDeleteAllItem.click(); - } else { - menuDeleteAllFromItem.click(); - let hostName = cells.host.value; - ok(menuDeleteAllFromItem.getAttribute("label").includes(hostName), + switch (action) { + case "deleteAll": + menuDeleteAllItem.click(); + break; + case "deleteAllSessionCookies": + menuDeleteAllSessionCookiesItem.click(); + break; + case "deleteAllFrom": + menuDeleteAllFromItem.click(); + let hostName = cells.host.value; + ok(menuDeleteAllFromItem.getAttribute("label").includes(hostName), `Context menu item label contains '${hostName}'`); + break; } }); @@ -48,15 +56,21 @@ add_task(function* () { getCookieId("c1", "test1.example.org", "/browser"), getCookieId("c3", "test1.example.org", "/"), getCookieId("cs2", ".example.org", "/"), - getCookieId("uc1", ".example.org", "/") + getCookieId("c4", ".example.org", "/"), + getCookieId("uc1", ".example.org", "/"), + getCookieId("uc2", ".example.org", "/") ] ], [ ["cookies", "sectest1.example.org"], [ getCookieId("cs2", ".example.org", "/"), + getCookieId("c4", ".example.org", "/"), getCookieId("sc1", "sectest1.example.org", "/browser/devtools/client/storage/test/"), - getCookieId("uc1", ".example.org", "/") + getCookieId("sc2", "sectest1.example.org", + "/browser/devtools/client/storage/test/"), + getCookieId("uc1", ".example.org", "/"), + getCookieId("uc2", ".example.org", "/") ] ], ]); @@ -64,6 +78,7 @@ add_task(function* () { info("delete all from domain"); // delete only cookies that match the host exactly let id = getCookieId("c1", "test1.example.org", "/browser"); + yield performDelete(["cookies", "test1.example.org"], id, "deleteAllFrom"); yield performDelete(["cookies", "test1.example.org"], id, false); info("test state after delete all from domain"); @@ -73,24 +88,57 @@ add_task(function* () { ["cookies", "test1.example.org"], [ getCookieId("cs2", ".example.org", "/"), - getCookieId("uc1", ".example.org", "/") + getCookieId("c4", ".example.org", "/"), + getCookieId("uc1", ".example.org", "/"), + getCookieId("uc2", ".example.org", "/") ] ], [ ["cookies", "sectest1.example.org"], [ getCookieId("cs2", ".example.org", "/"), + getCookieId("c4", ".example.org", "/"), getCookieId("uc1", ".example.org", "/"), + getCookieId("uc2", ".example.org", "/"), getCookieId("sc1", "sectest1.example.org", "/browser/devtools/client/storage/test/"), + getCookieId("sc2", "sectest1.example.org", + "/browser/devtools/client/storage/test/") + ] + ], + ]); + + info("delete all session cookies"); + // delete only session cookies + id = getCookieId("cs2", ".example.org", "/"); + yield performDelete(["cookies", "sectest1.example.org"], id, + "deleteAllSessionCookies"); + + info("test state after delete all session cookies"); + yield checkState([ + // Cookies with expiry date must not be deleted. + [ + ["cookies", "test1.example.org"], + [ + getCookieId("c4", ".example.org", "/"), + getCookieId("uc2", ".example.org", "/") + ] + ], + [ + ["cookies", "sectest1.example.org"], + [ + getCookieId("c4", ".example.org", "/"), + getCookieId("uc2", ".example.org", "/"), + getCookieId("sc2", "sectest1.example.org", + "/browser/devtools/client/storage/test/") ] ], ]); info("delete all"); // delete all cookies for host, including domain cookies - id = getCookieId("uc1", ".example.org", "/"); - yield performDelete(["cookies", "sectest1.example.org"], id, true); + id = getCookieId("uc2", ".example.org", "/"); + yield performDelete(["cookies", "sectest1.example.org"], id, "deleteAll"); info("test state after delete all"); yield checkState([ diff --git a/devtools/client/storage/test/browser_storage_delete_tree.js b/devtools/client/storage/test/browser_storage_delete_tree.js index 0a7a7e645..2bca4c344 100644 --- a/devtools/client/storage/test/browser_storage_delete_tree.js +++ b/devtools/client/storage/test/browser_storage_delete_tree.js @@ -23,7 +23,9 @@ add_task(function* () { getCookieId("c1", "test1.example.org", "/browser"), getCookieId("cs2", ".example.org", "/"), getCookieId("c3", "test1.example.org", "/"), - getCookieId("uc1", ".example.org", "/") + getCookieId("c4", ".example.org", "/"), + getCookieId("uc1", ".example.org", "/"), + getCookieId("uc2", ".example.org", "/") ] ], [["localStorage", "http://test1.example.org"], ["ls1", "ls2"]], diff --git a/devtools/client/storage/test/storage-listings.html b/devtools/client/storage/test/storage-listings.html index 89ae5a332..313b36b71 100644 --- a/devtools/client/storage/test/storage-listings.html +++ b/devtools/client/storage/test/storage-listings.html @@ -20,7 +20,10 @@ document.cookie = "c1=foobar; expires=" + new Date(cookieExpiresTime1).toGMTString() + "; path=/browser"; document.cookie = "cs2=sessionCookie; path=/; domain=" + partialHostname; document.cookie = "c3=foobar-2; expires=" + - new Date(cookieExpiresTime2).toGMTString() + "; path=/"; + new Date(cookieExpiresTime1).toGMTString() + "; path=/"; +document.cookie = "c4=foobar-3; expires=" + + new Date(cookieExpiresTime2).toGMTString() + "; path=/; domain=" + + partialHostname; // ... and some local storage items .. localStorage.setItem("ls1", "foobar"); localStorage.setItem("ls2", "foobar-2"); diff --git a/devtools/client/storage/test/storage-secured-iframe.html b/devtools/client/storage/test/storage-secured-iframe.html index 8424fd4cd..9e1ef60a0 100644 --- a/devtools/client/storage/test/storage-secured-iframe.html +++ b/devtools/client/storage/test/storage-secured-iframe.html @@ -1,4 +1,4 @@ -<!DOCTYPE HTML> +<!DOCTYPE HTML> <html> <!-- Iframe for testing multiple host detetion in storage actor @@ -9,7 +9,10 @@ Iframe for testing multiple host detetion in storage actor <body> <script type="application/javascript;version=1.7"> "use strict"; +let cookieExpiresTime = 2000000000000; document.cookie = "sc1=foobar;"; +document.cookie = "sc2=foobar-2; expires=" + + new Date(cookieExpiresTime).toGMTString() + ";"; localStorage.setItem("iframe-s-ls1", "foobar"); sessionStorage.setItem("iframe-s-ss1", "foobar-2"); dump("added cookies and storage from secured iframe\n"); diff --git a/devtools/client/storage/test/storage-unsecured-iframe.html b/devtools/client/storage/test/storage-unsecured-iframe.html index a69ffdfd1..cd08a6164 100644 --- a/devtools/client/storage/test/storage-unsecured-iframe.html +++ b/devtools/client/storage/test/storage-unsecured-iframe.html @@ -9,7 +9,10 @@ Iframe for testing multiple host detetion in storage actor <body> <script> "use strict"; +let cookieExpiresTime = 2000000000000; document.cookie = "uc1=foobar; domain=.example.org; path=/"; +document.cookie = "uc2=foobar-2; expires=" + + new Date(cookieExpiresTime).toGMTString() + "; path=/; domain=.example.org"; localStorage.setItem("iframe-u-ls1", "foobar"); sessionStorage.setItem("iframe-u-ss1", "foobar1"); sessionStorage.setItem("iframe-u-ss2", "foobar2"); diff --git a/devtools/client/storage/ui.js b/devtools/client/storage/ui.js index 946db68a2..af0bfa375 100644 --- a/devtools/client/storage/ui.js +++ b/devtools/client/storage/ui.js @@ -163,6 +163,7 @@ function StorageUI(front, target, panelWin, toolbox) { this.onRemoveItem = this.onRemoveItem.bind(this); this.onRemoveAllFrom = this.onRemoveAllFrom.bind(this); this.onRemoveAll = this.onRemoveAll.bind(this); + this.onRemoveAllSessionCookies = this.onRemoveAllSessionCookies.bind(this); this.onRemoveTreeItem = this.onRemoveTreeItem.bind(this); this._tablePopupDelete = this._panelDoc.getElementById( @@ -178,10 +179,20 @@ function StorageUI(front, target, panelWin, toolbox) { "storage-table-popup-delete-all"); this._tablePopupDeleteAll.addEventListener("command", this.onRemoveAll); + this._tablePopupDeleteAllSessionCookies = this._panelDoc.getElementById( + "storage-table-popup-delete-all-session-cookies"); + this._tablePopupDeleteAllSessionCookies.addEventListener("command", + this.onRemoveAllSessionCookies); + this._treePopupDeleteAll = this._panelDoc.getElementById( "storage-tree-popup-delete-all"); this._treePopupDeleteAll.addEventListener("command", this.onRemoveAll); + this._treePopupDeleteAllSessionCookies = this._panelDoc.getElementById( + "storage-tree-popup-delete-all-session-cookies"); + this._treePopupDeleteAllSessionCookies.addEventListener("command", + this.onRemoveAllSessionCookies); + this._treePopupDelete = this._panelDoc.getElementById("storage-tree-popup-delete"); this._treePopupDelete.addEventListener("command", this.onRemoveTreeItem); } @@ -211,12 +222,16 @@ StorageUI.prototype = { this._treePopup.removeEventListener("popupshowing", this.onTreePopupShowing); this._treePopupDeleteAll.removeEventListener("command", this.onRemoveAll); + this._treePopupDeleteAllSessionCookies.removeEventListener("command", + this.onRemoveAllSessionCookies); this._treePopupDelete.removeEventListener("command", this.onRemoveTreeItem); this._tablePopup.removeEventListener("popupshowing", this.onTablePopupShowing); this._tablePopupDelete.removeEventListener("command", this.onRemoveItem); this._tablePopupDeleteAllFrom.removeEventListener("command", this.onRemoveAllFrom); this._tablePopupDeleteAll.removeEventListener("command", this.onRemoveAll); + this._tablePopupDeleteAllSessionCookies.removeEventListener("command", + this.onRemoveAllSessionCookies); }, /** @@ -453,22 +468,24 @@ StorageUI.prototype = { * @param {object} See onUpdate docs */ handleChangedItems: function (changed) { - let [type, host, db, objectStore] = this.tree.selectedItem; - if (!changed[type] || !changed[type][host] || - changed[type][host].length == 0) { - return; - } - try { - let toUpdate = []; - for (let name of changed[type][host]) { - let names = JSON.parse(name); - if (names[0] == db && names[1] == objectStore && names[2]) { - toUpdate.push(name); + if (this.tree.selectedItem) { + let [type, host, db, objectStore] = this.tree.selectedItem; + if (!changed[type] || !changed[type][host] || + changed[type][host].length == 0) { + return; + } + try { + let toUpdate = []; + for (let name of changed[type][host]) { + let names = JSON.parse(name); + if (names[0] == db && names[1] == objectStore && names[2]) { + toUpdate.push(name); + } } + this.fetchStorageObjects(type, host, toUpdate, REASON.UPDATE); + } catch (ex) { + this.fetchStorageObjects(type, host, changed[type][host], REASON.UPDATE); } - this.fetchStorageObjects(type, host, toUpdate, REASON.UPDATE); - } catch (ex) { - this.fetchStorageObjects(type, host, changed[type][host], REASON.UPDATE); } }, @@ -957,6 +974,15 @@ StorageUI.prototype = { this._tablePopupDelete.setAttribute("label", L10N.getFormatStr("storage.popupMenu.deleteLabel", label)); + let showDeleteAllSessionCookies = false; + if (selectedItem && actor.removeAllSessionCookies) { + if (type === "cookies" && selectedItem.length === 2) { + showDeleteAllSessionCookies = true; + } + } + + this._tablePopupDeleteAllSessionCookies.hidden = !showDeleteAllSessionCookies; + if (type === "cookies") { let host = addEllipsis(data.host); @@ -997,6 +1023,17 @@ StorageUI.prototype = { this._treePopupDeleteAll.hidden = !showDeleteAll; + // The delete all session cookies action is displayed for cookie object stores + // (level 2 of tree) + let showDeleteAllSessionCookies = false; + if (actor.removeAllSessionCookies) { + if (type === "cookies" && selectedItem.length === 2) { + showDeleteAllSessionCookies = true; + } + } + + this._treePopupDeleteAllSessionCookies.hidden = !showDeleteAllSessionCookies; + // The delete action is displayed for: // - IndexedDB databases (level 3 of the tree) // - Cache objects (level 3 of the tree) @@ -1037,8 +1074,8 @@ StorageUI.prototype = { */ onRemoveAll: function () { // Cannot use this.currentActor() if the handler is called from the - // tree context menu: it returns correct value only after the table - // data from server are successfully fetched (and that's async). + // tree context menu: it returns the correct value only after the + // table data from server are successfully fetched (and that's async). let [type, host, ...path] = this.tree.selectedItem; let actor = this.storageTypes[type]; let name = path.length > 0 ? JSON.stringify(path) : undefined; @@ -1046,6 +1083,19 @@ StorageUI.prototype = { }, /** + * Handles removing all session cookies from the storage + */ + onRemoveAllSessionCookies: function () { + // Cannot use this.currentActor() if the handler is called from the + // tree context menu: it returns the correct value only after the + // table data from server is successfully fetched (and that's async). + let [, host, ...path] = this.tree.selectedItem; + let actor = this.getCurrentActor(); + let name = path.length > 0 ? JSON.stringify(path) : undefined; + actor.removeAllSessionCookies(host, name); + }, + + /** * Handles removing all cookies with exactly the same domain as the * cookie in the selected row. */ diff --git a/devtools/server/actors/storage.js b/devtools/server/actors/storage.js index 6d069939d..6d1e2dc99 100644 --- a/devtools/server/actors/storage.js +++ b/devtools/server/actors/storage.js @@ -628,6 +628,12 @@ StorageActors.createActor({ .originAttributes); }), + removeAllSessionCookies: Task.async(function* (host, domain) { + let doc = this.storageActor.document; + this.removeAllSessionCookies(host, domain, doc.nodePrincipal + .originAttributes); + }), + maybeSetupChildProcess() { cookieHelpers.onCookieChanged = this.onCookieChanged.bind(this); @@ -644,6 +650,8 @@ StorageActors.createActor({ cookieHelpers.removeCookie.bind(cookieHelpers); this.removeAllCookies = cookieHelpers.removeAllCookies.bind(cookieHelpers); + this.removeAllSessionCookies = + cookieHelpers.removeAllSessionCookies.bind(cookieHelpers); return; } @@ -667,6 +675,8 @@ StorageActors.createActor({ callParentProcess.bind(null, "removeCookie"); this.removeAllCookies = callParentProcess.bind(null, "removeAllCookies"); + this.removeAllSessionCookies = + callParentProcess.bind(null, "removeAllSessionCookies"); addMessageListener("debug:storage-cookie-request-child", cookieHelpers.handleParentRequest); @@ -853,7 +863,8 @@ var cookieHelpers = { if (hostMatches(cookie.host, host) && (!opts.name || cookie.name === opts.name) && (!opts.domain || cookie.host === opts.domain) && - (!opts.path || cookie.path === opts.path)) { + (!opts.path || cookie.path === opts.path) && + (!opts.session || (!cookie.expires && !cookie.maxAge))) { Services.cookies.remove( cookie.host, cookie.name, @@ -875,6 +886,10 @@ var cookieHelpers = { this._removeCookies(host, { domain, originAttributes }); }, + removeAllSessionCookies(host, domain, originAttributes) { + this._removeCookies(host, { domain, originAttributes, session: true }); + }, + addCookieObservers() { Services.obs.addObserver(cookieHelpers, "cookie-changed", false); return null; @@ -951,6 +966,12 @@ var cookieHelpers = { let originAttributes = msg.data.args[2]; return cookieHelpers.removeAllCookies(host, domain, originAttributes); } + case "removeAllSessionCookies": { + let host = msg.data.args[0]; + let domain = msg.data.args[1]; + let originAttributes = msg.data.args[2]; + return cookieHelpers.removeAllSessionCookies(host, domain, originAttributes); + } default: console.error("ERR_DIRECTOR_PARENT_UNKNOWN_METHOD", msg.json.method); throw new Error("ERR_DIRECTOR_PARENT_UNKNOWN_METHOD"); diff --git a/devtools/shared/specs/storage.js b/devtools/shared/specs/storage.js index 77f90323f..be56678b7 100644 --- a/devtools/shared/specs/storage.js +++ b/devtools/shared/specs/storage.js @@ -97,6 +97,14 @@ createStorageSpec({ }, response: {} } + }, { + removeAllSessionCookies: { + request: { + host: Arg(0, "string"), + domain: Arg(1, "nullable:string") + }, + response: {} + } } ) }); |