summaryrefslogtreecommitdiffstats
path: root/toolkit/components/cleardata/ServiceWorkerCleanUp.sys.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/cleardata/ServiceWorkerCleanUp.sys.mjs')
-rw-r--r--toolkit/components/cleardata/ServiceWorkerCleanUp.sys.mjs87
1 files changed, 87 insertions, 0 deletions
diff --git a/toolkit/components/cleardata/ServiceWorkerCleanUp.sys.mjs b/toolkit/components/cleardata/ServiceWorkerCleanUp.sys.mjs
new file mode 100644
index 0000000000..1c49b2be08
--- /dev/null
+++ b/toolkit/components/cleardata/ServiceWorkerCleanUp.sys.mjs
@@ -0,0 +1,87 @@
+/* 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/. */
+
+import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
+
+const lazy = {};
+
+XPCOMUtils.defineLazyServiceGetter(
+ lazy,
+ "serviceWorkerManager",
+ "@mozilla.org/serviceworkers/manager;1",
+ "nsIServiceWorkerManager"
+);
+
+if (Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_CONTENT) {
+ throw new Error(
+ "ServiceWorkerCleanUp.jsm can only be used in the parent process"
+ );
+}
+
+function unregisterServiceWorker(aSW) {
+ return new Promise(resolve => {
+ let unregisterCallback = {
+ unregisterSucceeded: resolve,
+ unregisterFailed: resolve, // We don't care about failures.
+ QueryInterface: ChromeUtils.generateQI([
+ "nsIServiceWorkerUnregisterCallback",
+ ]),
+ };
+ lazy.serviceWorkerManager.propagateUnregister(
+ aSW.principal,
+ unregisterCallback,
+ aSW.scope
+ );
+ });
+}
+
+function unregisterServiceWorkersMatching(filterFn) {
+ let promises = [];
+ let serviceWorkers = lazy.serviceWorkerManager.getAllRegistrations();
+ for (let i = 0; i < serviceWorkers.length; i++) {
+ let sw = serviceWorkers.queryElementAt(
+ i,
+ Ci.nsIServiceWorkerRegistrationInfo
+ );
+ if (filterFn(sw)) {
+ promises.push(unregisterServiceWorker(sw));
+ }
+ }
+ return Promise.all(promises);
+}
+
+export const ServiceWorkerCleanUp = {
+ removeFromHost(aHost) {
+ return unregisterServiceWorkersMatching(sw =>
+ Services.eTLD.hasRootDomain(sw.principal.host, aHost)
+ );
+ },
+
+ removeFromBaseDomain(aBaseDomain) {
+ // Service workers are disabled in partitioned contexts. This means we don't
+ // have to check for a partitionKey, but only look at the top level base
+ // domain. If this ever changes we need to update this method to account for
+ // partitions. See Bug 1495241.
+ return unregisterServiceWorkersMatching(
+ sw => sw.principal.baseDomain == aBaseDomain
+ );
+ },
+
+ removeFromPrincipal(aPrincipal) {
+ return unregisterServiceWorkersMatching(sw =>
+ sw.principal.equals(aPrincipal)
+ );
+ },
+
+ removeFromOriginAttributes(aOriginAttributesString) {
+ lazy.serviceWorkerManager.removeRegistrationsByOriginAttributes(
+ aOriginAttributesString
+ );
+ return Promise.resolve();
+ },
+
+ removeAll() {
+ return unregisterServiceWorkersMatching(() => true);
+ },
+};