diff options
Diffstat (limited to 'data/extensions/https-everywhere@eff.org/background-scripts')
6 files changed, 156 insertions, 100 deletions
diff --git a/data/extensions/https-everywhere@eff.org/background-scripts/background.js b/data/extensions/https-everywhere@eff.org/background-scripts/background.js index 28c7ead..c432d74 100644 --- a/data/extensions/https-everywhere@eff.org/background-scripts/background.js +++ b/data/extensions/https-everywhere@eff.org/background-scripts/background.js @@ -33,26 +33,22 @@ async function initializeAllRules() { * Load preferences. Structure is: * { * httpNowhere: Boolean, - * showCounter: Boolean, * isExtensionEnabled: Boolean * } */ var httpNowhereOn = false; -var showCounter = true; var isExtensionEnabled = true; let disabledList = new Set(); -function initializeStoredGlobals(){ +function initializeStoredGlobals() { return new Promise(resolve => { store.get({ httpNowhere: false, - showCounter: true, globalEnabled: true, enableMixedRulesets: false, - disabledList: [], + disabledList: [] }, function(item) { httpNowhereOn = item.httpNowhere; - showCounter = item.showCounter; isExtensionEnabled = item.globalEnabled; for (let disabledSite of item.disabledList) { disabledList.add(disabledSite); @@ -92,10 +88,6 @@ chrome.storage.onChanged.addListener(async function(changes, areaName) { httpNowhereOn = changes.httpNowhere.newValue; updateState(); } - if ('showCounter' in changes) { - showCounter = changes.showCounter.newValue; - updateState(); - } if ('globalEnabled' in changes) { isExtensionEnabled = changes.globalEnabled.newValue; updateState(); @@ -160,7 +152,6 @@ function updateState () { if (!tabs || tabs.length === 0) { return; } - const tabId = tabs[0].id; const tabUrl = new URL(tabs[0].url); if (disabledList.has(tabUrl.host) || iconState == "disabled") { @@ -172,7 +163,6 @@ function updateState () { }); } } else { - if ('setIcon' in chrome.browserAction) { chrome.browserAction.setIcon({ path: { @@ -180,18 +170,6 @@ function updateState () { } }); } - - const activeCount = appliedRulesets.getActiveRulesetCount(tabId); - - if ('setBadgeBackgroundColor' in chrome.browserAction) { - chrome.browserAction.setBadgeBackgroundColor({ color: '#666666', tabId }); - } - - const showBadge = activeCount > 0 && isExtensionEnabled && showCounter; - - if ('setBadgeText' in chrome.browserAction) { - chrome.browserAction.setBadgeText({ text: showBadge ? String(activeCount) : '', tabId }); - } } }); } @@ -200,7 +178,7 @@ function updateState () { * The following allows fennec to interact with the popup ui * */ chrome.browserAction.onClicked.addListener(e => { - const url = chrome.extension.getURL("/pages/popup/index.html?tabId=" + e.id); + const url = chrome.runtime.getURL("/pages/popup/index.html?tabId=" + e.id); chrome.tabs.create({ url }); @@ -299,13 +277,13 @@ var redirectCounter = new Map(); // HTTP Nowhere redirect. let simpleHTTPNowhereRedirect = new Map(); -const cancelUrl = chrome.extension.getURL("/pages/cancel/index.html"); +const cancelUrl = chrome.runtime.getURL("/pages/cancel/index.html"); -function redirectOnCancel(shouldCancel, originURL){ +function redirectOnCancel(shouldCancel, originURL) { return shouldCancel ? {redirectUrl: newCancelUrl(originURL)} : {cancel: false}; } -function newCancelUrl(originURL){ +function newCancelUrl(originURL) { return cancelUrl + "?originURL=" + encodeURI(originURL); } @@ -320,6 +298,14 @@ function onBeforeRequest(details) { return; } + // Clear the content shown in the extension popup. + // This needed to be done before this listener returns, + // otherwise, the extension page might include rulesets + // from previous page. + if (details.type == "main_frame") { + appliedRulesets.removeTab(details.tabId); + } + let uri = new URL(details.url); // Check if a user has disabled HTTPS Everywhere on this site. We should @@ -380,12 +366,6 @@ function onBeforeRequest(details) { return redirectOnCancel(shouldCancel, details.url); } - if (details.type == "main_frame") { - appliedRulesets.removeTab(details.tabId); - } - - let potentiallyApplicable = all_rules.potentiallyApplicableRulesets(uri.hostname); - if (redirectCounter.get(details.requestId) >= 8) { util.log(util.NOTE, "Redirect counter hit for " + uri.href); urlBlacklist.add(uri.href); @@ -398,6 +378,8 @@ function onBeforeRequest(details) { let upgradeToSecure = false; let newuristr = null; + let potentiallyApplicable = all_rules.potentiallyApplicableRulesets(uri.hostname); + for (let ruleset of potentiallyApplicable) { if (details.url.match(ruleset.scope)) { appliedRulesets.addRulesetToTab(details.tabId, details.type, ruleset); @@ -549,7 +531,9 @@ function sortSwitchPlanner(tab_id, rewritten) { var score = activeCount * 100 + passiveCount; asset_host_list.push([score, activeCount, passiveCount, asset_host]); } - asset_host_list.sort(function(a,b){return a[0]-b[0];}); + asset_host_list.sort(function(a,b) { + return a[0]-b[0]; + }); return asset_host_list; } @@ -645,8 +629,8 @@ function onErrorOccurred(details) { details.error.indexOf("net::ERR_CERT_") == 0 || details.error.indexOf("net::ERR_CONNECTION_") == 0 || details.error.indexOf("net::ERR_ABORTED") == 0 || + details.error.indexOf("net::ERR_SSL_PROTOCOL_ERROR") == 0 || details.error.indexOf("NS_ERROR_CONNECTION_REFUSED") == 0 || - details.error.indexOf("NS_ERROR_UNKNOWN_HOST") == 0 || details.error.indexOf("NS_ERROR_NET_TIMEOUT") == 0 || details.error.indexOf("NS_ERROR_NET_ON_TLS_HANDSHAKE_ENDED") == 0 || details.error.indexOf("NS_BINDING_ABORTED") == 0 || @@ -655,14 +639,14 @@ function onErrorOccurred(details) { details.error.indexOf("Unable to communicate securely with peer: requested domain name does not match the server’s certificate.") == 0 || details.error.indexOf("Peer’s Certificate issuer is not recognized.") == 0 || details.error.indexOf("Peer’s Certificate has been revoked.") == 0 || + details.error.indexOf("Peer reports it experienced an internal error.") == 0 || details.error.indexOf("The server uses key pinning (HPKP) but no trusted certificate chain could be constructed that matches the pinset. Key pinning violations cannot be overridden.") == 0 || details.error.indexOf("SSL received a weak ephemeral Diffie-Hellman key in Server Key Exchange handshake message.") == 0 || details.error.indexOf("The certificate was signed using a signature algorithm that is disabled because it is not secure.") == 0 || details.error.indexOf("Unable to communicate securely with peer: requested domain name does not match the server’s certificate.") == 0 || details.error.indexOf("Cannot communicate securely with peer: no common encryption algorithm(s).") == 0 || details.error.indexOf("SSL peer has no certificate for the requested DNS name.") == 0 - )) - { + )) { let url = new URL(details.url); if (url.protocol == "https:") { url.protocol = "http:"; @@ -685,13 +669,34 @@ function onErrorOccurred(details) { */ function onHeadersReceived(details) { if (isExtensionEnabled && httpNowhereOn) { - // Do not upgrade the .onion requests in HTTP Nowhere Mode, + // Do not upgrade the .onion requests in EASE mode, // See https://github.com/EFForg/https-everywhere/pull/14600#discussion_r168072480 const uri = new URL(details.url); if (uri.hostname.slice(-6) == '.onion') { return {}; } + // Do not upgrade resources if the first-party domain disbled EASE mode + // This is needed for HTTPS sites serve mixed content and is broken + let firstPartyHost; + if (details.type == "main_frame") { + firstPartyHost = uri.host; + } else { + // In Firefox, documentUrl is preferable here, since it will always be the + // URL in the URL bar, but it was only introduced in FF 54. We should get + // rid of `originUrl` at some point. + if ('documentUrl' in details) { // Firefox 54+ + firstPartyHost = new URL(details.documentUrl).host; + } else if ('originUrl' in details) { // Firefox < 54 + firstPartyHost = new URL(details.originUrl).host; + } else if('initiator' in details) { // Chrome + firstPartyHost = new URL(details.initiator).host; + } + } + if (disabledList.has(firstPartyHost)) { + return {}; + } + let responseHeadersChanged = false; let cspHeaderFound = false; @@ -778,7 +783,7 @@ function enableSwitchPlannerFor(tabId) { // Listen for connection from the DevTools panel so we can set up communication. chrome.runtime.onConnect.addListener(function (port) { if (port.name == "devtools-page") { - chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){ + chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) { var tabId = message.tabId; var disableOnCloseCallback = function() { @@ -811,9 +816,9 @@ chrome.runtime.onConnect.addListener(function (port) { // This is necessary for communication with the popup in Firefox Private // Browsing Mode, see https://bugzilla.mozilla.org/show_bug.cgi?id=1329304 -chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){ +chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) { - function get_update_channels_generic(update_channels){ + function get_update_channels_generic(update_channels) { let last_updated_promises = []; for(let update_channel of update_channels) { last_updated_promises.push(new Promise(resolve => { @@ -940,7 +945,7 @@ chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){ return obj; }, new Set()); - if(update_channel_names.has(message.object)){ + if(update_channel_names.has(message.object)) { return sendResponse(false); } @@ -979,8 +984,8 @@ chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){ store.get({update_channels: []}, item => { let scope_changed = false; item.update_channels = item.update_channels.map(update_channel => { - if(update_channel.name == message.object.name){ - if(update_channel.scope != message.object.scope){ + if(update_channel.name == message.object.name) { + if(update_channel.scope != message.object.scope) { scope_changed = true; } update_channel = message.object; @@ -996,7 +1001,7 @@ chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){ // necesssary to avoid a race condition, see #16673 update.loadUpdateChannelsKeys().then(() => { update.resetTimer(); - if(scope_changed){ + if(scope_changed) { initializeAllRules(); } sendResponse(true); @@ -1023,6 +1028,20 @@ chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){ check_if_site_disabled: () => { sendResponse(disabledList.has(message.object)); return true; + }, + is_firefox: () => { + if(typeof(browser) != "undefined") { + browser.runtime.getBrowserInfo().then(function(info) { + if (info.name == "Firefox") { + sendResponse(true); + } else { + sendResponse(false); + } + }); + } else { + sendResponse(false); + } + return true; } }; if (message.type in responses) { diff --git a/data/extensions/https-everywhere@eff.org/background-scripts/rules.js b/data/extensions/https-everywhere@eff.org/background-scripts/rules.js index 6b42cc6..c4ac18d 100644 --- a/data/extensions/https-everywhere@eff.org/background-scripts/rules.js +++ b/data/extensions/https-everywhere@eff.org/background-scripts/rules.js @@ -29,7 +29,7 @@ const nullIterable = Object.create(null, { const scopes = new Map(); /* Returns the scope object from the map for the given scope string */ -function getScope(scope){ +function getScope(scope) { if (!scopes.has(scope)) { scopes.set(scope, new RegExp(scope)); } @@ -174,7 +174,7 @@ RuleSet.prototype = { } if(this_rules_length > 0) { - for(let x = 0; x < this.rules.length; x++){ + for(let x = 0; x < this.rules.length; x++) { if(this.rules[x].to != ruleset.rules[x].to) { return false; } @@ -363,7 +363,7 @@ RuleSets.prototype = { if (src === 'options') { /** * FIXME: There is nothing we can do if the call comes from the - * option page because isEquivalentTo cannot work reliably. + * option page because isEquivalentTo cannot work reliably. * Leave the heavy duties to background.js to call initializeAllRules */ } @@ -431,7 +431,7 @@ RuleSets.prototype = { } }, - addStoredCustomRulesets: function(){ + addStoredCustomRulesets: function() { return new Promise(resolve => { this.store.get({ legacy_custom_rulesets: [], @@ -445,17 +445,17 @@ RuleSets.prototype = { }, // Load in the legacy custom rulesets, if any - loadCustomRulesets: function(legacy_custom_rulesets){ - for(let legacy_custom_ruleset of legacy_custom_rulesets){ + loadCustomRulesets: function(legacy_custom_rulesets) { + for(let legacy_custom_ruleset of legacy_custom_rulesets) { this.loadCustomRuleset(legacy_custom_ruleset); } }, - loadCustomRuleset: function(ruleset_string){ + loadCustomRuleset: function(ruleset_string) { this.addFromXml((new DOMParser()).parseFromString(ruleset_string, 'text/xml')); }, - setRuleActiveState: async function(ruleset_name, active){ + setRuleActiveState: async function(ruleset_name, active) { if (active == undefined) { delete this.ruleActiveStates[ruleset_name]; } else { @@ -562,22 +562,23 @@ RuleSets.prototype = { return nullIterable; } - // Replace each portion of the domain with a * in turn + // Replace www.example.com with www.example.* + // eat away from the right for once and only once let segmented = host.split("."); - for (let i = 0; i < segmented.length; i++) { - let tmp = segmented[i]; - segmented[i] = "*"; + if (segmented.length > 1) { + const tmp = segmented[segmented.length - 1]; + segmented[segmented.length - 1] = "*"; results = (this.targets.has(segmented.join(".")) ? new Set([...results, ...this.targets.get(segmented.join("."))]) : results); - segmented[i] = tmp; + segmented[segmented.length - 1] = tmp; } // now eat away from the left, with *, so that for x.y.z.google.com we - // check *.z.google.com and *.google.com (we did *.y.z.google.com above) - for (let i = 2; i <= segmented.length - 2; i++) { + // check *.y.z.google.com, *.z.google.com and *.google.com + for (let i = 1; i <= segmented.length - 2; i++) { let t = "*." + segmented.slice(i, segmented.length).join("."); results = (this.targets.has(t) ? @@ -625,11 +626,10 @@ RuleSets.prototype = { } var potentiallyApplicable = this.potentiallyApplicableRulesets(hostname); - for (let ruleset of potentiallyApplicable) { + for (const ruleset of potentiallyApplicable) { if (ruleset.cookierules !== null && ruleset.active) { - for (let cookierules of ruleset.cookierules) { - var cr = cookierules; - if (cr.host_c.test(cookie.domain) && cr.name_c.test(cookie.name)) { + for (const cookierule of ruleset.cookierules) { + if (cookierule.host_c.test(cookie.domain) && cookierule.name_c.test(cookie.name)) { return ruleset; } } @@ -682,10 +682,7 @@ RuleSets.prototype = { util.log(util.INFO, "Testing securecookie applicability with " + test_uri); var potentiallyApplicable = this.potentiallyApplicableRulesets(domain); for (let ruleset of potentiallyApplicable) { - if (!ruleset.active) { - continue; - } - if (ruleset.apply(test_uri)) { + if (ruleset.active && ruleset.apply(test_uri)) { util.log(util.INFO, "Cookie domain could be secured."); this.cookieHostCache.set(domain, true); return true; diff --git a/data/extensions/https-everywhere@eff.org/background-scripts/store.js b/data/extensions/https-everywhere@eff.org/background-scripts/store.js index c41ccd0..9698c18 100644 --- a/data/extensions/https-everywhere@eff.org/background-scripts/store.js +++ b/data/extensions/https-everywhere@eff.org/background-scripts/store.js @@ -8,7 +8,7 @@ function initialize() { return new Promise(resolve => { if (chrome.storage.sync) { chrome.storage.sync.set({"sync-set-test": true}, () => { - if(chrome.runtime.lastError){ + if(chrome.runtime.lastError) { setStorage(chrome.storage.local); } else { setStorage(chrome.storage.sync); @@ -99,9 +99,9 @@ async function performMigrations() { } const local = { - get: chrome.storage.local.get, - set: chrome.storage.local.set, - remove: chrome.storage.local.remove, + get: (...args) => chrome.storage.local.get(...args), + set: (...args) => chrome.storage.local.set(...args), + remove: (...args) => chrome.storage.local.remove(...args), get_promise: local_get_promise, set_promise: local_set_promise }; diff --git a/data/extensions/https-everywhere@eff.org/background-scripts/update.js b/data/extensions/https-everywhere@eff.org/background-scripts/update.js index 7e4eedf..1363384 100644 --- a/data/extensions/https-everywhere@eff.org/background-scripts/update.js +++ b/data/extensions/https-everywhere@eff.org/background-scripts/update.js @@ -2,7 +2,7 @@ "use strict"; -let combined_update_channels; +let combined_update_channels, extension_version; const { update_channels } = require('./update_channels'); // Determine if we're in the tests. If so, define some necessary components. @@ -14,9 +14,14 @@ if (typeof window === "undefined") { pako = require('../external/pako-1.0.5/pako_inflate.min.js'), { TextDecoder } = require('text-encoding'), chrome = require("sinon-chrome"), - window = { atob, btoa, chrome, crypto, pako, TextDecoder }; + window = { atob, btoa, chrome, crypto, pako, TextDecoder }, + fs = require('fs'); + + extension_version = JSON.parse(fs.readFileSync('./manifest.json')).version; combined_update_channels = update_channels; +} else { + extension_version = chrome.runtime.getManifest().version; } (function(exports) { @@ -29,6 +34,9 @@ let store, // how often we should check for new rulesets const periodicity = 86400; +const extension_date = new Date(extension_version.split('.').slice(0,3).join('-')); +const extension_timestamp = extension_date.getTime() / 1000; + let imported_keys; // update channels are loaded from `background-scripts/update_channels.js` as well as the storage api @@ -41,7 +49,7 @@ async function loadUpdateChannelsKeys() { imported_keys = {}; combined_update_channels = []; - for(let update_channel of combined_update_channels_preflight){ + for(let update_channel of combined_update_channels_preflight) { try{ imported_keys[update_channel.name] = await window.crypto.subtle.importKey( @@ -88,7 +96,7 @@ async function checkForNewRulesets(update_channel) { if(timestamp_result.status == 200) { let rulesets_timestamp = Number(await timestamp_result.text()); - if((await store.local.get_promise('rulesets-timestamp: ' + update_channel.name, 0)) < rulesets_timestamp){ + if((await store.local.get_promise('rulesets-timestamp: ' + update_channel.name, 0)) < rulesets_timestamp) { return rulesets_timestamp; } } @@ -96,12 +104,12 @@ async function checkForNewRulesets(update_channel) { } // Retrieve the timestamp for when a stored ruleset bundle was published -async function getRulesetTimestamps(){ +async function getRulesetTimestamps() { let timestamp_promises = []; - for(let update_channel of combined_update_channels){ + for(let update_channel of combined_update_channels) { timestamp_promises.push(new Promise(async resolve => { let timestamp = await store.local.get_promise('rulesets-stored-timestamp: ' + update_channel.name, 0); - resolve([update_channel.name, timestamp]); + resolve([update_channel, timestamp]); })); } let timestamps = await Promise.all(timestamp_promises); @@ -135,7 +143,7 @@ async function getNewRulesets(rulesets_timestamp, update_channel) { // Returns a promise which verifies that the rulesets have a valid EFF // signature, and if so, stores them and returns true. // Otherwise, it throws an exception. -function verifyAndStoreNewRulesets(new_rulesets, rulesets_timestamp, update_channel){ +function verifyAndStoreNewRulesets(new_rulesets, rulesets_timestamp, update_channel) { return new Promise((resolve, reject) => { window.crypto.subtle.verify( { @@ -154,7 +162,7 @@ function verifyAndStoreNewRulesets(new_rulesets, rulesets_timestamp, update_chan const rulesets = new TextDecoder("utf-8").decode(rulesets_byte_array); const rulesets_json = JSON.parse(rulesets); - if(rulesets_json.timestamp != rulesets_timestamp){ + if(rulesets_json.timestamp != rulesets_timestamp) { reject(update_channel.name + ': Downloaded ruleset had an incorrect timestamp. This may be an attempted downgrade attack. Aborting.'); } else { await store.local.set_promise('rulesets: ' + update_channel.name, window.btoa(rulesets_gz)); @@ -170,13 +178,13 @@ function verifyAndStoreNewRulesets(new_rulesets, rulesets_timestamp, update_chan } // Unzip and apply the rulesets we have stored. -async function applyStoredRulesets(rulesets_obj){ +async function applyStoredRulesets(rulesets_obj) { let rulesets_promises = []; - for(let update_channel of combined_update_channels){ + for(let update_channel of combined_update_channels) { rulesets_promises.push(new Promise(resolve => { const key = 'rulesets: ' + update_channel.name; chrome.storage.local.get(key, root => { - if(root[key]){ + if(root[key]) { util.log(util.NOTE, update_channel.name + ': Applying stored rulesets.'); const rulesets_gz = window.atob(root[key]); @@ -184,7 +192,7 @@ async function applyStoredRulesets(rulesets_obj){ const rulesets_string = new TextDecoder("utf-8").decode(rulesets_byte_array); const rulesets_json = JSON.parse(rulesets_string); - resolve({json: rulesets_json, scope: update_channel.scope}); + resolve({json: rulesets_json, scope: update_channel.scope, replaces: update_channel.replaces_default_rulesets}); } else { resolve(); } @@ -192,17 +200,21 @@ async function applyStoredRulesets(rulesets_obj){ })); } - function isNotUndefined(subject){ + function isNotUndefined(subject) { return (typeof subject != 'undefined'); } const channel_results = (await Promise.all(rulesets_promises)).filter(isNotUndefined); - if(channel_results.length > 0){ - for(let channel_result of channel_results){ - rulesets_obj.addFromJson(channel_result.json.rulesets, channel_result.scope); + let replaces = false; + for(const channel_result of channel_results) { + if(channel_result.replaces === true) { + replaces = true; } - } else { + rulesets_obj.addFromJson(channel_result.json.rulesets, channel_result.scope); + } + + if(!replaces) { rulesets_obj.addFromJson(util.loadExtensionFile('rules/default.rulesets', 'json')); } } @@ -215,9 +227,15 @@ async function performCheck() { store.local.set_promise('last-checked', current_timestamp); let num_updates = 0; - for(let update_channel of combined_update_channels){ + for(let update_channel of combined_update_channels) { let new_rulesets_timestamp = await checkForNewRulesets(update_channel); - if(new_rulesets_timestamp){ + if(new_rulesets_timestamp) { + + if(update_channel.replaces_default_rulesets && extension_timestamp > new_rulesets_timestamp) { + util.log(util.NOTE, update_channel.name + ': A new ruleset bundle has been released, but it is older than the extension-bundled rulesets it replaces. Skipping.'); + continue; + } + util.log(util.NOTE, update_channel.name + ': A new ruleset bundle has been released. Downloading now.'); let new_rulesets = await getNewRulesets(new_rulesets_timestamp, update_channel); try{ @@ -229,7 +247,7 @@ async function performCheck() { } } } - if(num_updates > 0){ + if(num_updates > 0) { background_callback(); } }; @@ -253,7 +271,7 @@ chrome.storage.onChanged.addListener(async function(changes, areaName) { let initialCheck, subsequentChecks; -async function createTimer(){ +async function createTimer() { const time_to_next_check = await timeToNextCheck(); initialCheck = setTimeout(() => { @@ -262,7 +280,7 @@ async function createTimer(){ }, time_to_next_check * 1000); } -function destroyTimer(){ +function destroyTimer() { if (initialCheck) { clearTimeout(initialCheck); } @@ -271,12 +289,33 @@ function destroyTimer(){ } } -async function initialize(store_param, cb){ +function clear_replacement_update_channels() { + let keys = []; + for (const update_channel of combined_update_channels) { + if(update_channel.replaces_default_rulesets) { + util.log(util.NOTE, update_channel.name + ': You have a new version of the extension. Clearing any stored rulesets, which replace the new extension-bundled ones.'); + keys.push('rulesets-timestamp: ' + update_channel.name); + keys.push('rulesets-stored-timestamp: ' + update_channel.name); + keys.push('rulesets: ' + update_channel.name); + } + } + + return new Promise(resolve => { + chrome.storage.local.remove(keys, resolve); + }); +} + +async function initialize(store_param, cb) { store = store_param; background_callback = cb; await loadUpdateChannelsKeys(); + if (await store.local.get_promise('extensionTimestamp', 0) !== extension_timestamp) { + await clear_replacement_update_channels(); + await store.local.set_promise('extensionTimestamp', extension_timestamp); + } + if (await store.get_promise('autoUpdateRulesets', false)) { await createTimer(); } diff --git a/data/extensions/https-everywhere@eff.org/background-scripts/update_channels.js b/data/extensions/https-everywhere@eff.org/background-scripts/update_channels.js index 71b1080..f21b332 100644 --- a/data/extensions/https-everywhere@eff.org/background-scripts/update_channels.js +++ b/data/extensions/https-everywhere@eff.org/background-scripts/update_channels.js @@ -18,7 +18,8 @@ exports.update_channels = [{ '-sbyMKGJ5j1BWTnibCklDXtWzXtuiz18EgE' }, update_path_prefix: 'https://www.https-rulesets.org/v1/', - scope: '' + scope: '', + replaces_default_rulesets: true }]; })(typeof exports === 'undefined' ? require.scopes.update_channels = {} : exports); diff --git a/data/extensions/https-everywhere@eff.org/background-scripts/util.js b/data/extensions/https-everywhere@eff.org/background-scripts/util.js index 06c87ad..1946e14 100644 --- a/data/extensions/https-everywhere@eff.org/background-scripts/util.js +++ b/data/extensions/https-everywhere@eff.org/background-scripts/util.js @@ -45,7 +45,7 @@ function loadExtensionFile(url, returnType) { var xhr = new XMLHttpRequest(); // Use blocking XHR to ensure everything is loaded by the time // we return. - xhr.open("GET", chrome.extension.getURL(url), false); + xhr.open("GET", chrome.runtime.getURL(url), false); xhr.send(null); // Get file contents if (xhr.readyState !== 4) { @@ -69,7 +69,7 @@ function ArrayBufferToString(ab) { let array = new Uint8Array(ab); let string = ""; - for (let byte of array){ + for (let byte of array) { string += String.fromCharCode(byte); } |