From 56844504e7c58708d23e37cf9c9c3a099a4c0072 Mon Sep 17 00:00:00 2001 From: Ame <76390419+driedpampas@users.noreply.github.com> Date: Tue, 19 Sep 2023 15:54:13 +0300 Subject: [PATCH] feat: consent page (firefox only) --- src/html/consent.html | 145 ++++++++----------- src/html/consent.js | 42 +++--- src/js/background.js | 313 ++++++++++++++++++++++-------------------- 3 files changed, 246 insertions(+), 254 deletions(-) diff --git a/src/html/consent.html b/src/html/consent.html index f06425990..9c812f26a 100644 --- a/src/html/consent.html +++ b/src/html/consent.html @@ -1,90 +1,63 @@ - - FastForward - - - - - - - -
-

Welcome to Your FastForward

-

- warning!! are you sure you want this extension to do what it says it does? here at fastforward we care about your privacy and want to make sure you don't accidentally use this extension because that could be disastrous. are you sure you want this button that you don't have to press to function when you press it? -

-

- this message was brought to you because of mozilla" -

- - - - - -
- - + + FastForward + + + + + + + + +
+
+

Thank you for installing FastForward

+

+ This extension collects the tab url when you choose to add a website to the whitelist. +

+

+ If you consent to this data collection hit "Agree" to continue. Otherwise hit "Refuse" and the extension will be uninstalled. +

+ + +
+ + diff --git a/src/html/consent.js b/src/html/consent.js index 8851108c9..2d284ce8d 100644 --- a/src/html/consent.js +++ b/src/html/consent.js @@ -1,28 +1,26 @@ -// Check if the user has already given or declined consent -const consentStatus = localStorage.getItem('consentStatus'); +// Function to save consent status +async function saveConsentStatus(consentStatus) { + return browser.storage.local.set({ consentStatus: consentStatus }); +} -// Handle the "I Agree" button click event -document.getElementById("consentButton").addEventListener("click", function () { - // Save consent in localStorage - localStorage.setItem('consentStatus', 'granted'); +// Function to get consent status +async function getConsentStatus() { + return new Promise((resolve) => { + browser.storage.local.get('consentStatus').then((result) => { + resolve(result.consentStatus); + }); + }); +} - // You can add additional logic here, such as performing actions that require consent. - - // Example: Redirect to another page after consent +// Event listener for "Agree" button +document.querySelector('#agree').addEventListener('click', async function () { + console.log("Agree button clicked."); + await saveConsentStatus('consent-granted'); window.location.href = 'options.html'; }); -document.getElementById("declineButton").addEventListener("click", function () { - // Save decline status in localStorage - localStorage.setItem('consentStatus', 'declined'); - console.log("Decline button clicked"); - - // Show the popup - document.getElementById("popup").style.display = "block"; -}); - -// Handle the "Uninstall" button click event within the popup -document.getElementById("uninstallPopupButton").addEventListener("click", function () { - // Uninstall the extension +// Event listener for "Refuse" button +document.querySelector('#refuse').addEventListener('click', async function () { + console.log("Uninstalling extension."); browser.management.uninstallSelf(); -}); +}); \ No newline at end of file diff --git a/src/js/background.js b/src/js/background.js index b5af38feb..24db0b9a6 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -1,172 +1,193 @@ -import * as constants from './constants.js'; -const brws = typeof browser !== 'undefined' ? browser : chrome; -const fetchDomains = ['crowd.fastforward.team', 'redirect-api.work.ink']; //only allow requests to these domains - -async function getOptions() { - return new Promise((resolve) => { - brws.storage.local.get('options').then((result) => { - resolve(result.options); - }); - }); -} +const isFirefox = /Firefox/i.test(navigator.userAgent); -function ffclipboardClear() { - brws.storage.local.set({ ff_clipboard: '{}' }); +// Check if the browser is Firefox +if (isFirefox) { + browser.runtime.onInstalled.addListener((details) => { + if (details.reason === "install") { + browser.storage.local.get('consentStatus').then(function (data) { + const consentStatus = data.consentStatus; + if (consentStatus !== 'granted') { + browser.tabs.create({ + url: "html/consent.html" + }); + } else { + executeBackgroundScript(); + } + }); + } + }); +} else { + // For non-Firefox browsers, execute background script + executeBackgroundScript(); } -function clearCrowdIgnoredURLs() { - brws.storage.local.set({ crowd_ignore: '{}' }); -} +function executeBackgroundScript() { + const brws = typeof browser !== 'undefined' ? browser : chrome; + const fetchDomains = ['crowd.fastforward.team', 'redirect-api.work.ink']; //only allow requests to these domains -function firstrun(details) { - if (details.reason == 'install' || details.reason == 'update') { - brws.tabs.create({ url: 'https://fastforward.team/firstrun' }); - ffclipboardClear(); - brws.storage.local.set({ tempDisableCrowd: 'false' }); - brws.storage.local.set({ version: brws.runtime.getManifest().version }); - brws.runtime.openOptionsPage(); //required for loading default options, to do: implement a better way - brws.declarativeNetRequest.updateDynamicRules({ - addRules: constants.beforeNavigateRules, - removeRuleIds: constants.beforeNavigateRules.map((rule) => rule.id), + async function getOptions() { + return new Promise((resolve) => { + brws.storage.local.get('options').then((result) => { + resolve(result.options); + }); }); } -} -function preflight(details) { - let url = new URL(details.url); - if (url.hostname !== 'fastforward.team') { - return; + function ffclipboardClear() { + brws.storage.local.set({ ff_clipboard: '{}' }); } - //navigate - if (url.pathname === '/bypassed') { - let ext_url = new URL(brws.runtime.getURL('')); - url.hostname = ext_url.hostname; - url.protocol = ext_url.protocol; - url.pathname = '/html' + url.pathname; - if (url.searchParams.get('crowd') === 'true') { - url.pathname = - url.pathname.split('/').slice(0, -1).join('/') + '/crowd-bypassed.html'; - } else { - url.pathname = - url.pathname.split('/').slice(0, -1).join('/') + - '/before-navigate.html'; - } - brws.tabs.update(details.tabId, { - url: url.href, - }); + function clearCrowdIgnoredURLs() { + brws.storage.local.set({ crowd_ignore: '{}' }); } -} -// If user restarts the browser before the is alarm triggered -function reEnableCrowdBypassStartup() { - brws.storage.local.get(['tempDisableCrowd']).then((result) => { - if (result.tempDisableCrowd === 'true') { - brws.storage.local.get(['options']).then((result) => { - let opt = result.options; - opt.optionCrowdBypass = true; - brws.storage.local.set({ options: opt }); + function firstrun(details) { + if (details.reason == 'install' || details.reason == 'update') { + brws.tabs.create({ url: 'https://fastforward.team/firstrun' }); + ffclipboardClear(); + brws.storage.local.set({ tempDisableCrowd: 'false' }); + brws.storage.local.set({ version: brws.runtime.getManifest().version }); + brws.runtime.openOptionsPage(); //required for loading default options, to do: implement a better way + brws.declarativeNetRequest.updateDynamicRules({ + addRules: constants.beforeNavigateRules, + removeRuleIds: constants.beforeNavigateRules.map((rule) => rule.id), }); } - brws.storage.local.set({ tempDisableCrowd: 'false' }); - }); -} + } + + function preflight(details) { + let url = new URL(details.url); + if (url.hostname !== 'fastforward.team') { + return; + } + //navigate + if (url.pathname === '/bypassed') { + let ext_url = new URL(brws.runtime.getURL('')); + url.hostname = ext_url.hostname; + url.protocol = ext_url.protocol; + url.pathname = '/html' + url.pathname; + if (url.searchParams.get('crowd') === 'true') { + url.pathname = + url.pathname.split('/').slice(0, -1).join('/') + '/crowd-bypassed.html'; + } else { + url.pathname = + url.pathname.split('/').slice(0, -1).join('/') + + '/before-navigate.html'; + } -// Add a listener for the temp crowd disable alarm -brws.alarms.onAlarm.addListener((alarm) => { - brws.storage.local.get(['tempDisableCrowd']).then((result) => { - if ( - alarm.name === 'enableCrowdBypass' && - result.tempDisableCrowd === 'true' - ) { - brws.storage.local.get(['options']).then((result) => { - let opt = result.options; - opt.optionCrowdBypass = true; - brws.storage.local.set({ options: opt }); - brws.storage.local.set({ tempDisableCrowd: 'false' }); + brws.tabs.update(details.tabId, { + url: url.href, }); } + } + + function reEnableCrowdBypassStartup() { + brws.storage.local.get(['tempDisableCrowd']).then((result) => { + if (result.tempDisableCrowd === 'true') { + brws.storage.local.get(['options']).then((result) => { + let opt = result.options; + opt.optionCrowdBypass = true; + brws.storage.local.set({ options: opt }); + }); + } + brws.storage.local.set({ tempDisableCrowd: 'false' }); + }); + } + + brws.alarms.onAlarm.addListener((alarm) => { + brws.storage.local.get(['tempDisableCrowd']).then((result) => { + if ( + alarm.name === 'enableCrowdBypass' && + result.tempDisableCrowd === 'true' + ) { + brws.storage.local.get(['options']).then((result) => { + let opt = result.options; + opt.optionCrowdBypass = true; + brws.storage.local.set({ options: opt }); + brws.storage.local.set({ tempDisableCrowd: 'false' }); + }); + } + }); }); -}); - -brws.runtime.onInstalled.addListener(firstrun); -brws.runtime.onStartup.addListener(() => { - ffclipboardClear(); - clearCrowdIgnoredURLs(); - reEnableCrowdBypassStartup(); - brws.storage.local.set({ version: brws.runtime.getManifest().version }); -}); - -brws.runtime.onMessage.addListener((request, _, sendResponse) => { - (async () => { - let options = await getOptions(); - if (options.optionCrowdBypass === false) { - return; - } - let url; - request.type === 'crowdQuery' - ? (url = 'https://crowd.fastforward.team/crowd/query_v1') - : (url = 'https://crowd.fastforward.team/crowd/contribute_v1'); - let params = new URLSearchParams(); + brws.runtime.onInstalled.addListener(firstrun); + brws.runtime.onStartup.addListener(() => { + ffclipboardClear(); + clearCrowdIgnoredURLs(); + reEnableCrowdBypassStartup(); + brws.storage.local.set({ version: brws.runtime.getManifest().version }); + }); - if (request.type !== 'followAndContribute') { - for (let key in request.detail) { - params.append(key, request.detail[key]); + brws.runtime.onMessage.addListener((request, _, sendResponse) => { + (async () => { + let options = await getOptions(); + if (options.optionCrowdBypass === false) { + return; } - } else { - //use fetch api to get final url after redirects from detail.target - for (let key in request.detail) { - if (key === 'target') { - let dest = new URL(request.detail[key]); - if (!fetchDomains.includes(dest.hostname)) { - return; - } - let res = await fetch(dest.href, { - method: 'GET', - redirect: 'follow', - }); - params.append(key, res.url); - } else { + let url; + request.type === 'crowdQuery' + ? (url = 'https://crowd.fastforward.team/crowd/query_v1') + : (url = 'https://crowd.fastforward.team/crowd/contribute_v1'); + + let params = new URLSearchParams(); + + if (request.type !== 'followAndContribute') { + for (let key in request.detail) { params.append(key, request.detail[key]); } + } else { + for (let key in request.detail) { + if (key === 'target') { + let dest = new URL(request.detail[key]); + if (!fetchDomains.includes(dest.hostname)) { + return; + } + let res = await fetch(dest.href, { + method: 'GET', + redirect: 'follow', + }); + params.append(key, res.url); + } else { + params.append(key, request.detail[key]); + } + } } - } - let response = await fetch(url, { - method: 'POST', - body: params.toString(), - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - }); - if (request.type === 'crowdQuery') - response.text().then((res) => { - sendResponse(res); - }); - })(); - return true; -}); - -brws.storage.onChanged.addListener(() => { - getOptions().then((options) => { - if (options.optionBlockIpLoggers === false) { - brws.declarativeNetRequest.updateEnabledRulesets({ - disableRulesetIds: ['ipLoggerRuleset'], - }); - } else { - brws.declarativeNetRequest.updateEnabledRulesets({ - enableRulesetIds: ['ipLoggerRuleset'], - }); - } - if (options.optionTrackerBypass === false) { - brws.declarativeNetRequest.updateEnabledRulesets({ - disableRulesetIds: ['trackerRuleset'], + let response = await fetch(url, { + method: 'POST', + body: params.toString(), + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, }); - } else { - brws.declarativeNetRequest.updateEnabledRulesets({ - enableRulesetIds: ['trackerRuleset'], - }); - } + if (request.type === 'crowdQuery') + response.text().then((res) => { + sendResponse(res); + }); + })(); + return true; + }); + + brws.storage.onChanged.addListener(() => { + getOptions().then((options) => { + if (options.optionBlockIpLoggers === false) { + brws.declarativeNetRequest.updateEnabledRulesets({ + disableRulesetIds: ['ipLoggerRuleset'], + }); + } else { + brws.declarativeNetRequest.updateEnabledRulesets({ + enableRulesetIds: ['ipLoggerRuleset'], + }); + } + if (options.optionTrackerBypass === false) { + brws.declarativeNetRequest.updateEnabledRulesets({ + disableRulesetIds: ['trackerRuleset'], + }); + } else { + brws.declarativeNetRequest.updateEnabledRulesets({ + enableRulesetIds: ['trackerRuleset'], + }); + } + }); }); -}); +} \ No newline at end of file