Skip to content
This repository has been archived by the owner on Dec 3, 2020. It is now read-only.

Commit

Permalink
Fix #72: Disable telemetry/price updates based on privacy settings.
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Kelly committed Oct 15, 2018
1 parent b6473f7 commit 565941f
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 28 deletions.
21 changes: 0 additions & 21 deletions src/background/extraction.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,24 +54,3 @@ export async function handleExtractedProductData({extractedProduct}, sender) {
// Update saved product data if it exists
updateProductWithExtracted(extractedProduct);
}

/**
* Check whether extraction should proceed based on current privacy settings.
* @param {object} message
* @param {MessageSender} sender
* @return {boolean} True if extraction should proceed, false if it shouldn't.
*/
export async function handleExtractionPrivacyMessage(message, sender) {
// Err on the side of caution if we can't find privacy info.
if (!sender.tab) {
return false;
}

// Private mode windows should not perform extraction.
const senderWindow = await browser.windows.get(sender.tab.windowId);
if (senderWindow.incognito) {
return false;
}

return true;
}
5 changes: 3 additions & 2 deletions src/background/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
*/

import {handleConfigMessage} from 'commerce/config/background';
import {handleExtractedProductData, handleExtractionPrivacyMessage} from 'commerce/background/extraction';
import {handleExtractedProductData} from 'commerce/background/extraction';
import {handlePrivacyMessage} from 'commerce/background/privacy';

export const handlers = new Map([
['extracted-product', handleExtractedProductData],
['config', handleConfigMessage],
['extraction-privacy', handleExtractionPrivacyMessage],
['privacy', handlePrivacyMessage],
]);

export default async function handleMessage(message, sender) {
Expand Down
5 changes: 5 additions & 0 deletions src/background/price_updates.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import config from 'commerce/config';
import store from 'commerce/state';
import {shouldUpdatePrices} from 'commerce/background/privacy';
import {addPriceFromExtracted, getLatestPriceForProduct} from 'commerce/state/prices';
import {getAllProducts, getProduct, getProductIdFromExtracted} from 'commerce/state/products';

Expand All @@ -31,6 +32,10 @@ export function handleWebRequest(details) {
* Find products that are due for price updates and update them.
*/
export async function updatePrices() {
if (!(await shouldUpdatePrices())) {
return;
}

const state = store.getState();
const products = getAllProducts(state);
const now = new Date();
Expand Down
72 changes: 72 additions & 0 deletions src/background/privacy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/* 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/. */

/**
* Handles checking privacy settings to gate functionality across the add-on.
* @module
*/

/**
* Listener for content scripts that want to gate functionality on privacy
* settings that only the background script can read.
* @param {object} message
* @param {MessageSender} sender
* @return {object} Object containing flags for what features should be enabled
*/
export async function handlePrivacyMessage(message, sender) {
return {
shouldExtract: await shouldExtract(message, sender),
};
}

/**
* Determine if a content script should extract a product from a specific tab.
* @param {object} message
* @param {MessageSender} sender
* @return {boolean}
*/
async function shouldExtract(message, sender) {
if (sender.tab) {
// Private mode windows should not perform extraction.
const senderWindow = await browser.windows.get(sender.tab.windowId);
if (!senderWindow.incognito) {
return true;
}
}

return false;
}

export async function shouldCollectTelemetry() {
return !(await arePrivacyControlsActive());
}

export async function shouldUpdatePrices() {
return !(await arePrivacyControlsActive());
}

/**
* Helper for checking privacy flags that are used in multiple feature flags.
*/
async function arePrivacyControlsActive() {
// Tracking Protection
if ((await browser.privacy.websites.trackingProtectionMode.get({})).value === 'always') {
return true;
}

// Do Not Track
if (navigator.doNotTrack === '1') {
return true;
}

// Cookie blocking
if (browser.privacy.websites.cookieConfig) {
const {behavior} = (await browser.privacy.websites.cookieConfig.get({})).value;
if (['reject_all', 'reject_third_party', 'reject_trackers'].includes(behavior)) {
return true;
}
}

return false;
}
5 changes: 4 additions & 1 deletion src/background/telemetry.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
* @module
*/

import {shouldCollectTelemetry} from 'commerce/background/privacy';

const CATEGORY = 'extension.price_alerts';

const EVENTS = {
Expand Down Expand Up @@ -156,9 +158,10 @@ export async function registerEvents() {
}

export async function recordEvent(method, object, value, extra) {
if (!browser.telemetry.canUpload()) {
if (!browser.telemetry.canUpload() || !(await shouldCollectTelemetry())) {
return;
}

await browser.telemetry.recordEvent(
CATEGORY,
method,
Expand Down
11 changes: 7 additions & 4 deletions src/extraction/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,13 @@ async function attemptExtraction() {
return;
}

// Check privacy settings to determine if we should extract.
const shouldExtract = await browser.runtime.sendMessage({type: 'extraction-privacy'});
if (!shouldExtract) {
return;
// Check privacy settings to determine if we should extract. Background
// updates don't have a window and just skip the check.
if (!isBackgroundUpdate) {
const {shouldExtract} = await browser.runtime.sendMessage({type: 'privacy'});
if (!shouldExtract) {
return;
}
}

// Only perform extraction on allowlisted sites. Background updates get a
Expand Down
1 change: 1 addition & 0 deletions src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"storage",
"unlimitedStorage",
"notifications",
"privacy",
"webRequest",
"webRequestBlocking",
"telemetry"
Expand Down

0 comments on commit 565941f

Please sign in to comment.