2019-08-06 00:52:36 +03:00
|
|
|
/* 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/. */
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
const { XPCOMUtils } = ChromeUtils.import(
|
|
|
|
"resource://gre/modules/XPCOMUtils.jsm"
|
|
|
|
);
|
|
|
|
|
|
|
|
XPCOMUtils.defineLazyModuleGetters(this, {
|
|
|
|
RemoteSettings: "resource://services-settings/remote-settings.js",
|
|
|
|
RemoteSettingsClient: "resource://services-settings/RemoteSettingsClient.jsm",
|
|
|
|
});
|
|
|
|
|
|
|
|
var EXPORTED_SYMBOLS = ["IgnoreLists"];
|
|
|
|
|
|
|
|
const SETTINGS_IGNORELIST_KEY = "hijack-blocklists";
|
|
|
|
|
|
|
|
class IgnoreListsManager {
|
|
|
|
async init() {
|
|
|
|
if (!this._ignoreListSettings) {
|
|
|
|
this._ignoreListSettings = RemoteSettings(SETTINGS_IGNORELIST_KEY);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async getAndSubscribe(listener) {
|
|
|
|
await this.init();
|
|
|
|
|
|
|
|
// Trigger a get of the initial value.
|
|
|
|
const settings = await this._getIgnoreList();
|
|
|
|
|
|
|
|
// Listen for future updates after we first get the values.
|
|
|
|
this._ignoreListSettings.on("sync", listener);
|
|
|
|
|
|
|
|
return settings;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsubscribe(listener) {
|
|
|
|
if (!this._ignoreListSettings) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._ignoreListSettings.off("sync", listener);
|
|
|
|
}
|
|
|
|
|
|
|
|
async _getIgnoreList() {
|
|
|
|
if (this._getSettingsPromise) {
|
|
|
|
return this._getSettingsPromise;
|
|
|
|
}
|
|
|
|
|
|
|
|
const settings = await (this._getSettingsPromise = this._getIgnoreListSettings());
|
|
|
|
delete this._getSettingsPromise;
|
|
|
|
return settings;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Obtains the current ignore list from remote settings. This includes
|
|
|
|
* verifying the signature of the ignore list within the database.
|
|
|
|
*
|
|
|
|
* If the signature in the database is invalid, the database will be wiped
|
|
|
|
* and the stored dump will be used, until the settings next update.
|
|
|
|
*
|
|
|
|
* Note that this may cause a network check of the certificate, but that
|
|
|
|
* should generally be quick.
|
|
|
|
*
|
|
|
|
* @param {boolean} [firstTime]
|
|
|
|
* Internal boolean to indicate if this is the first time check or not.
|
|
|
|
* @returns {array}
|
|
|
|
* An array of objects in the database, or an empty array if none
|
|
|
|
* could be obtained.
|
|
|
|
*/
|
|
|
|
async _getIgnoreListSettings(firstTime = true) {
|
2019-10-03 23:43:05 +03:00
|
|
|
let result = [];
|
2019-08-06 00:52:36 +03:00
|
|
|
try {
|
2019-10-03 23:43:05 +03:00
|
|
|
result = await this._ignoreListSettings.get({
|
2019-08-06 00:52:36 +03:00
|
|
|
verifySignature: true,
|
|
|
|
});
|
|
|
|
} catch (ex) {
|
|
|
|
if (
|
|
|
|
ex instanceof RemoteSettingsClient.InvalidSignatureError &&
|
|
|
|
firstTime
|
|
|
|
) {
|
|
|
|
// The local database is invalid, try and reset it.
|
2020-03-17 23:21:54 +03:00
|
|
|
await this._ignoreListSettings.db.clear();
|
2019-08-06 00:52:36 +03:00
|
|
|
// Now call this again.
|
2019-10-03 23:43:05 +03:00
|
|
|
return this._getIgnoreListSettings(false);
|
2019-08-06 00:52:36 +03:00
|
|
|
}
|
|
|
|
// Don't throw an error just log it, just continue with no data, and hopefully
|
|
|
|
// a sync will fix things later on.
|
|
|
|
Cu.reportError(ex);
|
|
|
|
}
|
2019-10-03 23:43:05 +03:00
|
|
|
return result;
|
2019-08-06 00:52:36 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const IgnoreLists = new IgnoreListsManager();
|