mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1188686 - Clear push subscriptions when forgetting about site. r=kitcambridge
--HG-- extra : commitid : 4z3omFAziAN extra : transplant_source : %0A%E7%85%26%EE9%CE%95%0C/%AC%7E%89%ED%08%9A%3C%99mA
This commit is contained in:
parent
839a3bc3fb
commit
97ea06c0c0
@ -11,7 +11,7 @@
|
||||
* uses service workers to notify applications. This interface exists to allow
|
||||
* privileged code to receive messages without migrating to service workers.
|
||||
*/
|
||||
[scriptable, uuid(abde228b-7d14-4cab-b1f9-9f87750ede0f)]
|
||||
[scriptable, uuid(74586476-d73f-4867-bece-87c1dea35750)]
|
||||
interface nsIPushNotificationService : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -48,7 +48,12 @@ interface nsIPushNotificationService : nsISupports
|
||||
jsval registration(in string scope, in jsval originAttributes);
|
||||
|
||||
/**
|
||||
* Clear all subscriptions
|
||||
* Clear all subscriptions.
|
||||
*/
|
||||
jsval clearAll();
|
||||
jsval clearAll();
|
||||
|
||||
/**
|
||||
* Clear subscriptions for a domain.
|
||||
*/
|
||||
jsval clearForDomain(in string domain);
|
||||
};
|
||||
|
@ -154,6 +154,36 @@ this.PushDB.prototype = {
|
||||
);
|
||||
},
|
||||
|
||||
// testFn(record) is called with a database record and should return true if
|
||||
// that record should be deleted.
|
||||
clearIf: function(testFn) {
|
||||
debug("clearIf()");
|
||||
return new Promise((resolve, reject) =>
|
||||
this.newTxn(
|
||||
"readwrite",
|
||||
this._dbStoreName,
|
||||
(aTxn, aStore) => {
|
||||
aTxn.result = undefined;
|
||||
|
||||
aStore.openCursor().onsuccess = event => {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
if (testFn(this.toPushRecord(cursor.value))) {
|
||||
let deleteRequest = cursor.delete();
|
||||
deleteRequest.onerror = e => {
|
||||
debug("Failed to delete entry even when test succeeded!");
|
||||
}
|
||||
}
|
||||
cursor.continue();
|
||||
}
|
||||
}
|
||||
},
|
||||
resolve,
|
||||
reject
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
getByPushEndpoint: function(aPushEndpoint) {
|
||||
debug("getByPushEndpoint()");
|
||||
|
||||
|
@ -58,6 +58,10 @@ PushNotificationService.prototype = {
|
||||
return PushService._clearAll();
|
||||
},
|
||||
|
||||
clearForDomain: function(domain) {
|
||||
return PushService._clearForDomain(domain);
|
||||
},
|
||||
|
||||
observe: function observe(subject, topic, data) {
|
||||
switch (topic) {
|
||||
case "app-startup":
|
||||
|
@ -1027,7 +1027,47 @@ this.PushService = {
|
||||
_clearAll: function _clearAll() {
|
||||
return this._checkActivated()
|
||||
.then(_ => this._db.clearAll())
|
||||
.catch(_ => {
|
||||
.catch(_ => Promise.resolve());
|
||||
},
|
||||
|
||||
_clearForDomain: function(domain) {
|
||||
/**
|
||||
* Copied from ForgetAboutSite.jsm.
|
||||
*
|
||||
* Returns true if the string passed in is part of the root domain of the
|
||||
* current string. For example, if this is "www.mozilla.org", and we pass in
|
||||
* "mozilla.org", this will return true. It would return false the other way
|
||||
* around.
|
||||
*/
|
||||
function hasRootDomain(str, aDomain)
|
||||
{
|
||||
let index = str.indexOf(aDomain);
|
||||
// If aDomain is not found, we know we do not have it as a root domain.
|
||||
if (index == -1)
|
||||
return false;
|
||||
|
||||
// If the strings are the same, we obviously have a match.
|
||||
if (str == aDomain)
|
||||
return true;
|
||||
|
||||
// Otherwise, we have aDomain as our root domain iff the index of aDomain is
|
||||
// aDomain.length subtracted from our length and (since we do not have an
|
||||
// exact match) the character before the index is a dot or slash.
|
||||
let prevChar = str[index - 1];
|
||||
return (index == (str.length - aDomain.length)) &&
|
||||
(prevChar == "." || prevChar == "/");
|
||||
}
|
||||
|
||||
let clear = (db, domain) => {
|
||||
db.clearIf(record => {
|
||||
return hasRootDomain(record.origin, domain);
|
||||
});
|
||||
}
|
||||
|
||||
return this._checkActivated()
|
||||
.then(_ => clear(this._db, domain))
|
||||
.catch(e => {
|
||||
debug("Error forgetting about domain! " + e);
|
||||
return Promise.resolve();
|
||||
});
|
||||
},
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
let {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
|
@ -181,6 +181,16 @@ this.ForgetAboutSite = {
|
||||
let np = Cc["@mozilla.org/network/predictor;1"].
|
||||
getService(Ci.nsINetworkPredictor);
|
||||
np.reset();
|
||||
|
||||
// Push notifications.
|
||||
try {
|
||||
var push = Cc["@mozilla.org/push/NotificationService;1"]
|
||||
.getService(Ci.nsIPushNotificationService);
|
||||
push.clearForDomain(aDomain);
|
||||
} catch (e) {
|
||||
dump("Web Push may not be available.\n");
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
};
|
||||
|
@ -2,9 +2,9 @@
|
||||
* 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/. */
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
let Cu = Components.utils;
|
||||
|
||||
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
|
||||
var profileDir = do_get_profile();
|
||||
|
@ -462,6 +462,67 @@ function test_content_preferences_not_cleared_with_uri_contains_domain()
|
||||
do_check_false(yield preference_exists(TEST_URI));
|
||||
}
|
||||
|
||||
// Push
|
||||
function test_push_cleared()
|
||||
{
|
||||
let ps;
|
||||
try {
|
||||
ps = Cc["@mozilla.org/push/NotificationService;1"].
|
||||
getService(Ci.nsIPushNotificationService);
|
||||
} catch(e) {
|
||||
// No push service, skip test.
|
||||
return;
|
||||
}
|
||||
|
||||
do_get_profile();
|
||||
setPrefs();
|
||||
const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
|
||||
const userAgentID = 'bd744428-f125-436a-b6d0-dd0c9845837f';
|
||||
const channelID = '0ef2ad4a-6c49-41ad-af6e-95d2425276bf';
|
||||
|
||||
let db = PushServiceWebSocket.newPushDB();
|
||||
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
|
||||
|
||||
PushService.init({
|
||||
serverURI: "wss://push.example.org/",
|
||||
networkInfo: new MockDesktopNetworkInfo(),
|
||||
db,
|
||||
makeWebSocket(uri) {
|
||||
return new MockWebSocket(uri, {
|
||||
onHello(request) {
|
||||
this.serverSendMsg(JSON.stringify({
|
||||
messageType: 'hello',
|
||||
status: 200,
|
||||
uaid: userAgentID,
|
||||
}));
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function push_registration_exists(aURL, ps)
|
||||
{
|
||||
return ps.registration(aURL, ChromeUtils.originAttributesToSuffix({ appId: Ci.nsIScriptSecurityManager.NO_APP_ID, inBrowser: false }))
|
||||
.then(record => !!record)
|
||||
.catch(_ => false);
|
||||
}
|
||||
|
||||
const TEST_URL = "https://www.mozilla.org/scope/";
|
||||
do_check_false(yield push_registration_exists(TEST_URL, ps));
|
||||
yield db.put({
|
||||
channelID,
|
||||
pushEndpoint: 'https://example.org/update/clear-success',
|
||||
scope: TEST_URL,
|
||||
version: 1,
|
||||
originAttributes: '',
|
||||
quota: Infinity,
|
||||
});
|
||||
do_check_true(yield push_registration_exists(TEST_URL, ps));
|
||||
ForgetAboutSite.removeDataFromDomain("mozilla.org");
|
||||
yield waitForPurgeNotification();
|
||||
do_check_false(yield push_registration_exists(TEST_URL, ps));
|
||||
}
|
||||
|
||||
// Cache
|
||||
function test_cache_cleared()
|
||||
{
|
||||
@ -555,6 +616,9 @@ let tests = [
|
||||
test_content_preferences_cleared_with_subdomain,
|
||||
test_content_preferences_not_cleared_with_uri_contains_domain,
|
||||
|
||||
// Push
|
||||
test_push_cleared,
|
||||
|
||||
// Storage
|
||||
test_storage_cleared,
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
[DEFAULT]
|
||||
head = head_forgetaboutsite.js
|
||||
head = head_forgetaboutsite.js ../../../../dom/push/test/xpcshell/head.js
|
||||
tail =
|
||||
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user