summaryrefslogtreecommitdiffstats
path: root/comm/suite/components/permissions/content/cookieViewer.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--comm/suite/components/permissions/content/cookieViewer.js531
1 files changed, 531 insertions, 0 deletions
diff --git a/comm/suite/components/permissions/content/cookieViewer.js b/comm/suite/components/permissions/content/cookieViewer.js
new file mode 100644
index 0000000000..d864f72908
--- /dev/null
+++ b/comm/suite/components/permissions/content/cookieViewer.js
@@ -0,0 +1,531 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
+
+// cookies and permissions list
+var cookies = [];
+var permissions = [];
+var allCookies = [];
+var deletedCookies = [];
+var deletedPermissions = [];
+
+var cookieBundle;
+var gUpdatingBatch = "";
+var lastCookieSortColumn;
+var lastCookieSortAscending;
+var lastPermissionSortColumn;
+var lastPermissionSortAscending;
+
+function Startup() {
+
+ // arguments passed to this routine:
+ // cookieManager
+
+ // intialize string bundle
+ cookieBundle = document.getElementById("cookieBundle");
+
+ // load in the cookies and permissions
+ cookiesTree = document.getElementById("cookiesTree");
+ lastCookieSortAscending = (cookiesTree.getAttribute("sortAscending") == "true");
+ lastCookieSortColumn = cookiesTree.getAttribute("sortColumn");
+ permissionsTree = document.getElementById("permissionsTree");
+ lastPermissionSortAscending = (permissionsTree.getAttribute("sortAscending") == "true");
+ lastPermissionSortColumn = permissionsTree.getAttribute("sortColumn");
+ loadCookies();
+ loadPermissions();
+
+ // be prepared to reload the display if anything changes
+ Services.obs.addObserver(cookieReloadDisplay, "cookie-changed", false);
+ Services.obs.addObserver(cookieReloadDisplay, "perm-changed", false);
+
+ // filter the table if requested by caller
+ if (window.arguments &&
+ window.arguments[0] &&
+ window.arguments[0].filterString)
+ setFilter(window.arguments[0].filterString);
+
+ document.getElementById("filter").focus();
+}
+
+function Shutdown() {
+ Services.obs.removeObserver(cookieReloadDisplay, "cookie-changed");
+ Services.obs.removeObserver(cookieReloadDisplay, "perm-changed");
+}
+
+function PromptConfirm(title, msg, yes) {
+ var flags =
+ ((Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0) +
+ (Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1) +
+ Services.prompt.BUTTON_POS_1_DEFAULT)
+ return Services.prompt.confirmEx(window,
+ cookieBundle.getString(title),
+ cookieBundle.getString(msg),
+ flags,
+ cookieBundle.getString(yes),
+ null, null, null, {value:0});
+}
+
+var cookieReloadDisplay = {
+ observe: function(subject, topic, state) {
+ if (topic == gUpdatingBatch)
+ return;
+ if (topic == "cookie-changed") {
+ allCookies.length = 0;
+ loadCookies();
+ } else if (topic == "perm-changed") {
+ permissions.length = 0;
+ loadPermissions();
+ }
+ }
+}
+
+function doSelectAll() {
+ var elem = document.commandDispatcher.focusedElement;
+ if (elem && "treeBoxObject" in elem)
+ elem.view.selection.selectAll();
+}
+
+/*** =================== COOKIES CODE =================== ***/
+
+var cookiesTreeView = {
+ rowCount : 0,
+ setTree : function(tree){},
+ getImageSrc : function(row,column) {},
+ getProgressMode : function(row,column) {},
+ getCellValue : function(row,column) {},
+ getCellText : function(row,column){ return cookies[row][column.id]; },
+ isSeparator : function(index) {return false;},
+ isSorted: function() { return false; },
+ isContainer : function(index) {return false;},
+ cycleHeader : function(aCol) {},
+ getRowProperties : function(row) { return ""; },
+ getColumnProperties : function(column) { return ""; },
+ getCellProperties : function(row, column) { return ""; }
+};
+var cookiesTree;
+
+function Cookie(id, host, name, path, originAttributes, value,
+ isDomain, rawHost, isSecure, expires) {
+ this.id = id;
+ this.host = host;
+ this.name = name;
+ this.path = path;
+ this.originAttributes = originAttributes;
+ this.value = value;
+ this.isDomain = isDomain;
+ this.rawHost = rawHost;
+ this.isSecure = isSecure;
+ this.expires = GetExpiresString(expires);
+ this.expiresSortValue = expires;
+}
+
+function loadCookies() {
+ // load cookies into a table
+ var enumerator = Services.cookies.enumerator;
+ var count = 0;
+ while (enumerator.hasMoreElements()) {
+ var nextCookie = enumerator.getNext();
+ if (!nextCookie) break;
+ nextCookie = nextCookie.QueryInterface(Ci.nsICookie);
+ var host = nextCookie.host;
+ allCookies.push(
+ new Cookie(count++, host, nextCookie.name,
+ nextCookie.path, nextCookie.originAttributes,
+ nextCookie.value, nextCookie.isDomain,
+ host.charAt(0)=="." ? host.slice(1) : host,
+ nextCookie.isSecure, nextCookie.expires));
+ }
+
+ // filter, sort and display the table
+ cookiesTree.view = cookiesTreeView;
+ filter(document.getElementById("filter").value);
+}
+
+function GetExpiresString(expires) {
+ if (expires) {
+ var date = new Date(1000*expires);
+
+ // if a server manages to set a really long-lived cookie, the dateservice
+ // can't cope with it properly, so we'll just return a blank string
+ // see bug 238045 for details
+ var expiry = "";
+ try {
+ const dateTimeFormatter = new Services.intl.DateTimeFormat(undefined, {
+ dateStyle: "full", timeStyle: "long" });
+ expiry = dateTimeFormatter.format(date);
+ } catch(ex) {
+ // do nothing
+ }
+ return expiry;
+ }
+ return cookieBundle.getString("expireAtEndOfSession");
+}
+
+function CookieSelected() {
+ var selections = GetTreeSelections(cookiesTree);
+ if (selections.length) {
+ document.getElementById("removeCookie").removeAttribute("disabled");
+ } else {
+ document.getElementById("removeCookie").setAttribute("disabled", "true");
+ ClearCookieProperties();
+ return true;
+ }
+
+ var idx = selections[0];
+ if (idx >= cookies.length) {
+ // Something got out of synch. See bug 119812 for details
+ dump("Tree and viewer state are out of sync! " +
+ "Help us figure out the problem in bug 119812");
+ return false;
+ }
+
+ var props = [
+ {id: "ifl_name", value: cookies[idx].name},
+ {id: "ifl_value", value: cookies[idx].value},
+ {id: "ifl_isDomain",
+ value: cookies[idx].isDomain ?
+ cookieBundle.getString("domainColon") : cookieBundle.getString("hostColon")},
+ {id: "ifl_host", value: cookies[idx].host},
+ {id: "ifl_path", value: cookies[idx].path},
+ {id: "ifl_isSecure",
+ value: cookies[idx].isSecure ?
+ cookieBundle.getString("forSecureOnly") :
+ cookieBundle.getString("forAnyConnection")},
+ {id: "ifl_expires", value: cookies[idx].expires}
+ ];
+
+ var value;
+ var field;
+
+ for (let lProp of props)
+ {
+ field = document.getElementById(lProp.id);
+ if ((selections.length > 1) && (lProp.id != "ifl_isDomain")) {
+ value = ""; // clear field if multiple selections
+ } else {
+ value = lProp.value;
+ }
+ field.value = value;
+ }
+ return true;
+}
+
+function ClearCookieProperties() {
+ var properties =
+ ["ifl_name","ifl_value","ifl_host","ifl_path","ifl_isSecure","ifl_expires"];
+ for (let prop of properties) {
+ document.getElementById(prop).value = "";
+ }
+}
+
+function DeleteCookie() {
+ if (cookiesTreeView.selection.count > 1 &&
+ PromptConfirm("deleteSelectedCookiesTitle",
+ "deleteSelectedCookies",
+ "deleteSelectedCookiesYes") == 1) {
+ return;
+ }
+ DeleteSelectedItemFromTree(cookiesTree, cookiesTreeView,
+ cookies, deletedCookies,
+ "removeCookie", "removeAllCookies");
+ if (document.getElementById("filter").value) {
+ // remove selected cookies from unfiltered set
+ for (let cookie of deletedCookies) {
+ allCookies.splice(allCookies.indexOf(cookie), 1);
+ }
+ }
+ if (!cookies.length) {
+ ClearCookieProperties();
+ }
+ FinalizeCookieDeletions();
+}
+
+function DeleteAllCookies() {
+ if (PromptConfirm("deleteAllCookiesTitle",
+ "deleteAllCookies",
+ "deleteAllCookiesYes") == 1) {
+ return;
+ }
+
+ ClearCookieProperties();
+ DeleteAllFromTree(cookiesTree, cookiesTreeView,
+ cookies, deletedCookies,
+ "removeCookie", "removeAllCookies");
+ allCookies.length = 0;
+ FinalizeCookieDeletions();
+}
+
+function FinalizeCookieDeletions() {
+ gUpdatingBatch = "cookie-changed";
+ for (let delCookie of deletedCookies) {
+ Services.cookies.remove(delCookie.host,
+ delCookie.name,
+ delCookie.path,
+ document.getElementById("checkbox").checked,
+ delCookie.originAttributes);
+ }
+ deletedCookies.length = 0;
+ gUpdatingBatch = "";
+}
+
+function HandleCookieKeyPress(e) {
+ if (e.keyCode == KeyEvent.DOM_VK_DELETE ||
+ (AppConstants.platform == "macosx" &&
+ e.keyCode == KeyEvent.DOM_VK_BACK_SPACE)) {
+ DeleteCookie();
+ }
+}
+
+function CookieColumnSort(column, updateSelection) {
+ lastCookieSortAscending =
+ SortTree(cookiesTree, cookiesTreeView, cookies,
+ column, lastCookieSortColumn, lastCookieSortAscending,
+ updateSelection);
+ lastCookieSortColumn = column;
+
+ SetSortDirection(cookiesTree, column, lastCookieSortAscending);
+}
+
+/*** =================== PERMISSIONS CODE =================== ***/
+
+var permissionsTreeView = {
+ rowCount : 0,
+ setTree : function(tree){},
+ getImageSrc : function(row,column) {},
+ getProgressMode : function(row,column) {},
+ getCellValue : function(row,column) {},
+ getCellText : function(row,column) { return permissions[row][column.id]; },
+ isSeparator : function(index) {return false;},
+ isSorted: function() { return false; },
+ isContainer : function(index) {return false;},
+ cycleHeader : function(aCol) {},
+ getRowProperties : function(row) { return ""; },
+ getColumnProperties : function(column) { return ""; },
+ getCellProperties : function(row, column) { return ""; }
+};
+var permissionsTree;
+
+function Permission(id, principal, type, capability) {
+ this.id = id;
+ this.principal = principal;
+ this.host = principal.URI.hostPort;
+ this.scheme = principal.URI.scheme;
+ this.type = type;
+ this.capability = capability;
+}
+
+function loadPermissions() {
+ // load permissions into a table
+ var enumerator = Services.perms.enumerator;
+ var canStr = cookieBundle.getString("can");
+ var canSessionStr = cookieBundle.getString("canSession");
+ var cannotStr = cookieBundle.getString("cannot");
+ var capability;
+ var count = 0;
+ var permission;
+ while (enumerator.hasMoreElements()) {
+ permission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
+ // We are only interested in cookie permissions in this code.
+ if (permission.type == "cookie") {
+ // It is currently possible to add a cookie permission for about:xxx
+ // and other internal pages. They are probably invalid and will be
+ // ignored for now.
+ // Test if the permission has a host.
+ try {
+ permission.principal.URI.host;
+ }
+ catch (e) {
+ Cu.reportError("Invalid permission found: " +
+ permission.principal.origin + " " + permission.type);
+ continue;
+ }
+
+ switch (permission.capability) {
+ case Ci.nsIPermissionManager.ALLOW_ACTION:
+ capability = canStr;
+ break;
+ case Ci.nsIPermissionManager.DENY_ACTION:
+ capability = cannotStr;
+ break;
+ case Ci.nsICookiePermission.ACCESS_SESSION:
+ capability = canSessionStr;
+ break;
+ default:
+ continue;
+ }
+ permissions.push(new Permission(count++,
+ permission.principal,
+ permission.type,
+ capability));
+ }
+ }
+ permissionsTreeView.rowCount = permissions.length;
+
+ // sort and display the table
+ permissionsTree.view = permissionsTreeView;
+ permissionsTreeView.selection.clearSelection();
+ SortTree(permissionsTree, permissionsTreeView, permissions,
+ lastPermissionSortColumn, lastPermissionSortColumn,
+ !lastPermissionSortAscending);
+
+ // disable "remove all" button if there are no cookies
+ document.getElementById("removeAllPermissions").disabled = permissions.length == 0;
+}
+
+function DeletePermission() {
+ if (permissionsTreeView.selection.count > 1 &&
+ PromptConfirm("deleteSelectedSitesTitle",
+ "deleteSelectedCookiesSites",
+ "deleteSelectedSitesYes") == 1) {
+ return;
+ }
+ DeleteSelectedItemFromTree(permissionsTree, permissionsTreeView,
+ permissions, deletedPermissions,
+ "removePermission", "removeAllPermissions");
+ FinalizePermissionDeletions();
+}
+
+function setCookiePermissions(action) {
+ var site = document.getElementById("cookie-site");
+
+ // let the backend do the validation
+ try {
+ var url = new URL(site.value);
+ } catch (e) {
+ // show an error if URL is invalid
+ window.alert(cookieBundle.getString("allowedURLSchemes"));
+ return;
+ }
+
+ try {
+ var uri = Services.io.newURI(url);
+ } catch (e) {
+ // show an error if URI can not be constructed or adding it failed
+ window.alert(cookieBundle.getString("errorAddPermission"));
+ return;
+ }
+ // only allow a few schemes here
+ // others like file:// would produce an invalid entry in the database
+ if (uri.scheme != "http" &&
+ uri.scheme != "https") {
+ // show an error if uri uses invalid scheme
+ window.alert(uri.scheme + ": " + cookieBundle.getString("allowedURLSchemes"));
+ return;
+ }
+
+ if (Services.perms.testPermission(uri, "cookie") != action)
+ Services.perms.add(uri, "cookie", action);
+
+ site.focus();
+ site.value = "";
+}
+
+function DeleteAllPermissions() {
+ if (PromptConfirm("deleteAllSitesTitle",
+ "deleteAllCookiesSites",
+ "deleteAllSitesYes") == 1) {
+ return;
+ }
+
+ DeleteAllFromTree(permissionsTree, permissionsTreeView,
+ permissions, deletedPermissions,
+ "removePermission", "removeAllPermissions");
+ FinalizePermissionDeletions();
+}
+
+function FinalizePermissionDeletions() {
+ if (!deletedPermissions.length)
+ return;
+
+ gUpdatingBatch = "perm-changed";
+ for (let permission of deletedPermissions)
+ Services.perms.removeFromPrincipal(permission.principal, permission.type);
+ deletedPermissions.length = 0;
+ gUpdatingBatch = "";
+}
+
+function HandlePermissionKeyPress(e) {
+ if (e.keyCode == KeyEvent.DOM_VK_DELETE ||
+ (AppConstants.platform == "macosx" &&
+ e.keyCode == KeyEvent.DOM_VK_BACK_SPACE)) {
+ DeletePermission();
+ }
+}
+
+function PermissionColumnSort(column, updateSelection) {
+ lastPermissionSortAscending =
+ SortTree(permissionsTree, permissionsTreeView, permissions,
+ column, lastPermissionSortColumn, lastPermissionSortAscending,
+ updateSelection);
+ lastPermissionSortColumn = column;
+
+ SetSortDirection(permissionsTree, column, lastPermissionSortAscending);
+}
+
+/*** ============ CODE FOR HELP BUTTON =================== ***/
+
+function doHelpButton()
+{
+ var selTab = document.getElementById("tabbox").selectedTab;
+ var key = selTab.getAttribute("help");
+ openHelp(key, "chrome://communicator/locale/help/suitehelp.rdf");
+}
+
+/*** =================== FILTER CODE =================== ***/
+
+function filterCookies(aFilterValue)
+{
+ var filterSet = [];
+ for (let cookie of allCookies) {
+ if (cookie.rawHost.includes(aFilterValue) ||
+ cookie.name.includes(aFilterValue) ||
+ cookie.value.includes(aFilterValue))
+ filterSet.push(cookie);
+ }
+ return filterSet;
+}
+
+function filter(filter)
+{
+ // clear the display
+ var oldCount = cookiesTreeView.rowCount;
+ cookiesTreeView.rowCount = 0;
+ cookiesTree.treeBoxObject.rowCountChanged(0, -oldCount);
+
+ // set up the display
+ cookies = filter ? filterCookies(filter) : allCookies;
+ cookiesTreeView.rowCount = cookies.length;
+ cookiesTree.treeBoxObject.rowCountChanged(0, cookiesTreeView.rowCount);
+
+ // sort the tree according to the last sort parameters
+ SortTree(cookiesTree, cookiesTreeView, cookies, lastCookieSortColumn,
+ lastCookieSortColumn, !lastCookieSortAscending);
+
+ // disable Remove All Cookies button if the view is filtered or there are no cookies
+ if (filter || !cookies.length)
+ document.getElementById("removeAllCookies").setAttribute("disabled", "true");
+ else
+ document.getElementById("removeAllCookies").removeAttribute("disabled");
+
+ // if the view is filtered and not empty then select the first item
+ if (filter && cookies.length)
+ cookiesTreeView.selection.select(0);
+}
+
+function setFilter(aFilterString)
+{
+ document.getElementById("filter").value = aFilterString;
+ filter(aFilterString);
+}
+
+function focusFilterBox()
+{
+ var filterBox = document.getElementById("filter");
+ filterBox.focus();
+ filterBox.select();
+}