diff --git a/src/background/autoconsent.js b/src/background/autoconsent.js index 93f251798..d915c1ff0 100644 --- a/src/background/autoconsent.js +++ b/src/background/autoconsent.js @@ -15,15 +15,24 @@ import { parse } from 'tldts-experimental'; import { store } from 'hybrids'; import Options, { isPaused } from '/store/options.js'; +import Config, { ACTION_DISABLE_AUTOCONSENT } from '/store/config.js'; async function initialize(msg, tab, frameId) { - const options = await store.resolve(Options); + const [options, config] = await Promise.all([ + store.resolve(Options), + store.resolve(Config), + ]); + + if (options.terms && options.blockAnnoyances) { + const domain = tab.url ? parse(tab.url).hostname.replace(/^www\./, '') : ''; + + if ( + isPaused(options, domain) || + config.hasAction(domain, ACTION_DISABLE_AUTOCONSENT) + ) { + return; + } - if ( - options.terms && - options.blockAnnoyances && - !isPaused(options, tab.url ? parse(tab.url).hostname : '') - ) { try { chrome.tabs.sendMessage( tab.id, diff --git a/src/background/config.js b/src/background/config.js new file mode 100644 index 000000000..6c7ecfbac --- /dev/null +++ b/src/background/config.js @@ -0,0 +1,114 @@ +/** + * Ghostery Browser Extension + * https://www.ghostery.com/ + * + * Copyright 2017-present Ghostery GmbH. All rights reserved. + * + * 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 { store } from 'hybrids'; + +import Config from '/store/config.js'; + +function filter(item) { + if (item.filter) { + const { platform } = item.filter; + let check = true; + + // Browser check + if (check && Array.isArray(platform)) { + check = platform.includes(__PLATFORM__); + } + + return check; + } + + return true; +} + +// Fetch the remote config, update the local config +// with current domains and add new flags (not initialized yet) +(async function syncRemoteConfig() { + // TODO: implement fetching remote config from the server + // This is a mock of the fetched config + const fetchedConfig = { + 'domains': { + 'ghostery.com': { + 'actions': ['assist'], + 'filter': { + 'platform': ['chromium'], + }, + }, + 'consent.google.pl': { + 'actions': ['disable-autoconsent'], + }, + }, + 'flags': { + 'assist': [ + { + percentage: 100, + }, + ], + 'firefox-content-script-scriptlets': [ + { + 'percentage': 20, + 'filter': { + 'platform': ['firefox'], + }, + }, + ], + }, + }; + + const config = await store.resolve(Config); + + // -- domains -- + + const domains = { ...config.domains }; + + // Clear out domains removed from the config + for (const name of Object.keys(domains)) { + if (fetchedConfig.domains[name] === undefined) { + domains[name] = null; + } + } + + // Update the config with new values + for (const [name, item] of Object.entries(fetchedConfig.domains)) { + domains[name] = filter(item) ? item : null; + } + + // -- flags -- + + const flags = { ...config.flags }; + + // Clear out flags removed from the config + for (const name of Object.keys(flags)) { + if (fetchedConfig.flags[name] === undefined) { + flags[name] = null; + } + } + + // Update the config with the new values + for (const [name, items] of Object.entries(fetchedConfig.flags)) { + const item = items.find((item) => filter(item)); + if (!item) { + flags[name] = null; + continue; + } + // Generate local percentage only once for each flag + const percentage = + flags[name]?.percentage || Math.floor(Math.random() * 100) + 1; + + flags[name] = { + percentage, + enabled: percentage <= item.percentage, + }; + } + + // Update the config + store.set(Config, { domains, flags }); +})(); diff --git a/src/background/index.js b/src/background/index.js index 5235b6b04..b9529cf73 100644 --- a/src/background/index.js +++ b/src/background/index.js @@ -10,6 +10,7 @@ */ import './onboarding.js'; +import './config.js'; import './autoconsent.js'; import './adblocker.js'; diff --git a/src/store/config.js b/src/store/config.js new file mode 100644 index 000000000..458d0fef4 --- /dev/null +++ b/src/store/config.js @@ -0,0 +1,57 @@ +/** + * Ghostery Browser Extension + * https://www.ghostery.com/ + * + * Copyright 2017-present Ghostery GmbH. All rights reserved. + * + * 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 { store } from 'hybrids'; + +export const ACTION_DISABLE_AUTOCONSENT = 'disable-autoconsent'; +export const ACTION_ASSIST = 'assist'; + +export const FLAG_ASSIST = 'assist'; +export const FLAG_FIREFOX_CONTENT_SCRIPT_SCRIPTLETS = + 'firefox-content-script-scriptlets'; + +export default { + enabled: true, + domains: store.record({ + actions: [String], + }), + flags: store.record({ + percentage: 0, + enabled: false, + }), + + // Helper methods + + hasAction({ domains }) { + return (domain, action) => + !!(domain && domains[domain]?.actions.includes(action)); + }, + + hasFlag({ flags }) { + return (flag) => !!(flag && flags[flag]?.enabled); + }, + + [store.connect]: { + async get() { + const { config = {} } = await chrome.storage.local.get(['config']); + return config; + }, + async set(_, values) { + await chrome.storage.local.set({ + config: + __PLATFORM__ === 'firefox' + ? JSON.parse(JSON.stringify(values)) + : values, + }); + return values; + }, + }, +};