diff --git a/.eslintignore b/.eslintignore index ffb934815..952a9a6a2 100644 --- a/.eslintignore +++ b/.eslintignore @@ -8,9 +8,6 @@ ## Data Images app/data-images/ -## Vendor Files -app/content-scripts/vendor/ - ## Precompiled app/templates/ build/ diff --git a/app/content-scripts/ghostery_dot_com.js b/app/content-scripts/ghostery_dot_com.js deleted file mode 100644 index 95f61e1bd..000000000 --- a/app/content-scripts/ghostery_dot_com.js +++ /dev/null @@ -1,175 +0,0 @@ -/** - * Ghostery.com Extension Support - * - * This file connects the extension to the Ghostery website - * located at https://www.ghostery.com/products/ - * and Apps pages located at https://apps.ghostery.com/ and - * https://gcache.ghostery.com/ - * - * Ghostery Browser Extension - * https://www.ghostery.com/ - * - * Copyright 2019 Ghostery, Inc. 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 - */ -/** - * @namespace GhosteryDotComContentScript - */ -/* eslint import/no-extraneous-dependencies: 0 */ - -import $ from 'jquery'; -import msgModule from './utils/msg'; -import './vendor/bootstrap_tooltip'; - -const msg = msgModule('ghostery_dot_com'); -const { sendMessage } = msg; -const { onMessage } = chrome.runtime; -/** - * This context script is injected statically through manifest.json - * Along with it a stylesheet ghostery_dot_com_css is injected, also - * through the manifest. Functions in this script refer both to element - * selectors provided by pages and to style class names provided by - * injected stylesheet. - * - * Use this variable to call init and initialize functionality of this script. - * @var {Object} initialized with an object with init as its property - */ -const GhosteryDotComContentScript = (function(window) { - /** - * Update https://www.ghostery.com/Products page to signify - * that Ghostery extension is installed. - * @memberOf GhosteryDotComContentScript - * @package - */ - const productsPage = function() { - const $installButton = $('#ghostery-extension-versions .install-button').not('.disabled'); - $installButton.addClass('success').text('Installed ✓'); - $installButton.removeAttr('onclick'); - $('.success').on('click', (e) => { - e.preventDefault(); - }); - }; - - /** - * Animate blocking tracker button on tracker pages - * https://apps.ghostery.com/en/apps/ - * @memberOf GhosteryDotComContentScript - * @package - */ - const toggleBlocking = function(blocked, duration) { - if (!blocked) { - $('#app-global-blocking').animate({ 'background-position-x': '-17px' }, { - duration, - complete() { - $(this).removeClass('blocked').addClass('unblocked'); - $(this).parent().removeClass('blocked').addClass('unblocked'); - } - }); - } else { - $('#app-global-blocking').animate({ 'background-position-x': '3px' }, { - duration, - complete() { - $(this).removeClass('unblocked').addClass('blocked'); - $(this).parent().removeClass('unblocked').addClass('blocked'); - } - }); - } - }; - /** - * Connect to blocking box on https://apps.ghostery.com/en/apps/ - * @memberOf GhosteryDotComContentScript - * @package - */ - const appsPages = function() { - const $appGlobalBlocking = $('#app-global-blocking'); - const $blockingBox = $('#blockingbox'); - const app_id = $blockingBox.data('id'); - let alreadyLoaded = false; - let tooltipTimeout; - - sendMessage('appsPageLoaded', { - id: app_id - }); - - onMessage.addListener((request) => { - if (request.source === 'cliqz-content-script') { - return false; - } - - const { name } = request; - let { blocked } = request.message; - - if (name === 'appsPageData' && !alreadyLoaded) { - // TODO why does background page occasionally send response twice? - alreadyLoaded = true; - - $('#ghosterybox').hide(); - $blockingBox.show(); - - toggleBlocking(blocked, 0); - - $appGlobalBlocking.on('click', () => { - blocked = !blocked; - - sendMessage('panelSelectedAppsUpdate', { - app_id, - app_selected: blocked - }); - - $('#global-blocking-control') - .tooltip('destroy') - .tooltip({ - trigger: 'manual', - title: `Tracker ${blocked ? 'blocked' : 'unblocked'}`, - placement: 'bottom' - }) - .tooltip('show'); - - window.clearTimeout(tooltipTimeout); - tooltipTimeout = window.setTimeout(() => { - $('#global-blocking-control').tooltip('destroy'); - }, 1400); - - toggleBlocking(blocked, 'fast'); - }); - } - return false; - }); - }; - /** - * Selectively initialize functionality for www.ghostery.com, - * apps.ghostery.com or gcache.ghostery.com platform pages. - * @memberOf GhosteryDotComContentScript - * @package - */ - const _initialize = function() { - // initialize products page - if ($('section.products-template').length) { - productsPage(); - } - // initialize apps pages - if ($('#ghosterybox').length) { - appsPages(); - } - }; - - // Public API - return { - /** - * Initialize functionality for product pages. - * @memberOf GhosteryDotComContentScript - * @public - */ - init() { - _initialize(); - } - }; -}(window)); - -// Run our init on DOMReady -$(document).ready(() => { - GhosteryDotComContentScript.init(); -}); diff --git a/app/content-scripts/vendor/bootstrap_tooltip.js b/app/content-scripts/vendor/bootstrap_tooltip.js deleted file mode 100644 index a0b8a51bd..000000000 --- a/app/content-scripts/vendor/bootstrap_tooltip.js +++ /dev/null @@ -1,407 +0,0 @@ -/* =================================================== - * bootstrap-transition.js v2.3.2 - * http://twitter.github.com/bootstrap/javascript.html#transitions - * =================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ========================================================== */ -import $ from 'jquery'; -global.jQuery = $; - -!function ($) { - "use strict"; - /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) - * ======================================================= */ - $(function () { - $.support.transition = (function () { - var transitionEnd = (function () { - var el = document.createElement('bootstrap') - , transEndEventNames = { - 'WebkitTransition' : 'webkitTransitionEnd' - , 'MozTransition' : 'transitionend' - , 'OTransition' : 'oTransitionEnd otransitionend' - , 'transition' : 'transitionend' - } - , name - for (name in transEndEventNames){ - if (el.style[name] !== undefined) { - return transEndEventNames[name] - } - } - }()) - return transitionEnd && { - end: transitionEnd - } - })() - }) -}(jQuery); - -/* =========================================================== - * bootstrap-tooltip.js v2.3.2 - * http://twitter.github.com/bootstrap/javascript.html#tooltips - * Inspired by the original jQuery.tipsy by Jason Frame - * =========================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ========================================================== */ -!function ($) { - - "use strict"; - - /* TOOLTIP PUBLIC CLASS DEFINITION - * =============================== */ - - var Tooltip = function (element, options) { - this.init('tooltip', element, options) - } - - Tooltip.prototype = { - - constructor: Tooltip - - , init: function (type, element, options) { - var eventIn - , eventOut - , triggers - , trigger - , i - - this.type = type - this.$element = $(element) - this.options = this.getOptions(options) - this.enabled = true - - triggers = this.options.trigger.split(' ') - - for (i = triggers.length; i--;) { - trigger = triggers[i] - if (trigger == 'click') { - this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) - } else if (trigger != 'manual') { - eventIn = trigger == 'hover' ? 'mouseenter' : 'focus' - eventOut = trigger == 'hover' ? 'mouseleave' : 'blur' - this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) - this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) - } - } - - this.options.selector ? - (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : - this.fixTitle() - } - - , getOptions: function (options) { - options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options) - - if (options.delay && typeof options.delay == 'number') { - options.delay = { - show: options.delay - , hide: options.delay - } - } - - return options - } - - , enter: function (e) { - var defaults = $.fn[this.type].defaults - , options = {} - , self - - this._options && $.each(this._options, function (key, value) { - if (defaults[key] != value) options[key] = value - }, this) - - self = $(e.currentTarget)[this.type](options).data(this.type) - - if (!self.options.delay || !self.options.delay.show) return self.show() - - clearTimeout(this.timeout) - self.hoverState = 'in' - this.timeout = setTimeout(function() { - if (self.hoverState == 'in') self.show() - }, self.options.delay.show) - } - - , leave: function (e) { - var self = $(e.currentTarget)[this.type](this._options).data(this.type) - - if (this.timeout) clearTimeout(this.timeout) - if (!self.options.delay || !self.options.delay.hide) return self.hide() - - self.hoverState = 'out' - this.timeout = setTimeout(function() { - if (self.hoverState == 'out') self.hide() - }, self.options.delay.hide) - } - - , show: function () { - var $tip - , pos - , actualWidth - , actualHeight - , placement - , tp - , e = $.Event('show') - - if (this.hasContent() && this.enabled) { - this.$element.trigger(e) - if (e.isDefaultPrevented()) return - $tip = this.tip() - this.setContent() - - if (this.options.animation) { - $tip.addClass('fade') - } - - placement = typeof this.options.placement == 'function' ? - this.options.placement.call(this, $tip[0], this.$element[0]) : - this.options.placement - - $tip - .detach() - .css({ top: 0, left: 0, display: 'block' }) - - this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) - - pos = this.getPosition() - - actualWidth = $tip[0].offsetWidth - actualHeight = $tip[0].offsetHeight - - switch (placement) { - case 'bottom': - tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2} - break - case 'top': - tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2} - break - case 'left': - tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth} - break - case 'right': - tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width} - break - } - - this.applyPlacement(tp, placement) - this.$element.trigger('shown') - } - } - - , applyPlacement: function(offset, placement){ - var $tip = this.tip() - , width = $tip[0].offsetWidth - , height = $tip[0].offsetHeight - , actualWidth - , actualHeight - , delta - , replace - - $tip - .offset(offset) - .addClass(placement) - .addClass('in') - - actualWidth = $tip[0].offsetWidth - actualHeight = $tip[0].offsetHeight - - if (placement == 'top' && actualHeight != height) { - offset.top = offset.top + height - actualHeight - replace = true - } - - if (placement == 'bottom' || placement == 'top') { - delta = 0 - - if (offset.left < 0){ - delta = offset.left * -2 - offset.left = 0 - $tip.offset(offset) - actualWidth = $tip[0].offsetWidth - actualHeight = $tip[0].offsetHeight - } - - this.replaceArrow(delta - width + actualWidth, actualWidth, 'left') - } else { - this.replaceArrow(actualHeight - height, actualHeight, 'top') - } - - if (replace) $tip.offset(offset) - } - - , replaceArrow: function(delta, dimension, position){ - this - .arrow() - .css(position, delta ? (50 * (1 - delta / dimension) + "%") : '') - } - - , setContent: function () { - var $tip = this.tip() - , title = this.getTitle() - - $tip.find('.bs-tooltip-inner')[this.options.html ? 'html' : 'text'](title) - $tip.removeClass('fade in top bottom left right') - } - - , hide: function () { - var that = this - , $tip = this.tip() - , e = $.Event('hide') - - this.$element.trigger(e) - if (e.isDefaultPrevented()) return - - $tip.removeClass('in') - - function removeWithAnimation() { - var timeout = setTimeout(function () { - $tip.off($.support.transition.end).detach() - }, 500) - - $tip.one($.support.transition.end, function () { - clearTimeout(timeout) - $tip.detach() - }) - } - - $.support.transition && this.$tip.hasClass('fade') ? - removeWithAnimation() : - $tip.detach() - - this.$element.trigger('hidden') - - return this - } - - , fixTitle: function () { - var $e = this.$element - if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { - $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') - } - } - - , hasContent: function () { - return this.getTitle() - } - - , getPosition: function () { - var el = this.$element[0] - return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : { - width: el.offsetWidth - , height: el.offsetHeight - }, this.$element.offset()) - } - - , getTitle: function () { - var title - , $e = this.$element - , o = this.options - - title = $e.attr('data-original-title') - || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) - - return title - } - - , tip: function () { - return this.$tip = this.$tip || $(this.options.template) - } - - , arrow: function(){ - return this.$arrow = this.$arrow || this.tip().find(".bs-tooltip-arrow") - } - - , validate: function () { - if (!this.$element[0].parentNode) { - this.hide() - this.$element = null - this.options = null - } - } - - , enable: function () { - this.enabled = true - } - - , disable: function () { - this.enabled = false - } - - , toggleEnabled: function () { - this.enabled = !this.enabled - } - - , toggle: function (e) { - var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this - self.tip().hasClass('in') ? self.hide() : self.show() - } - - , destroy: function () { - this.hide().$element.off('.' + this.type).removeData(this.type) - } - - } - - - /* TOOLTIP PLUGIN DEFINITION - * ========================= */ - - var old = $.fn.tooltip - - $.fn.tooltip = function ( option ) { - return this.each(function () { - var $this = $(this) - , data = $this.data('tooltip') - , options = typeof option == 'object' && option - if (!data) $this.data('tooltip', (data = new Tooltip(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - $.fn.tooltip.Constructor = Tooltip - - $.fn.tooltip.defaults = { - animation: true - , placement: 'top' - , selector: false - , template: '
' - , trigger: 'hover focus' - , title: '' - , delay: 0 - , html: false - , container: false - } - - - /* TOOLTIP NO CONFLICT - * =================== */ - - $.fn.tooltip.noConflict = function () { - $.fn.tooltip = old - return this - } - -}(jQuery); diff --git a/app/images/apps_pages/tracker.png b/app/images/apps_pages/tracker.png deleted file mode 100644 index e6dfcc116..000000000 Binary files a/app/images/apps_pages/tracker.png and /dev/null differ diff --git a/app/panel/components/Blocking/GlobalTracker.jsx b/app/panel/components/Blocking/GlobalTracker.jsx index df2221d95..ad7de407c 100644 --- a/app/panel/components/Blocking/GlobalTracker.jsx +++ b/app/panel/components/Blocking/GlobalTracker.jsx @@ -43,10 +43,10 @@ class GlobalTracker extends React.Component { /** * Implement handler for clicking on the tracker title * which shows/hides tracker description. On show it retrieves - * description from https://apps.ghostery.com and sets it in state. + * description from whotracks.me and sets it in state. */ toggleDescription() { - const { tracker, language } = this.props; + const { tracker } = this.props; const { description } = this.state; this.setState(prevState => ({ showMoreInfo: !prevState.showMoreInfo })); @@ -56,12 +56,11 @@ class GlobalTracker extends React.Component { this.setState({ description: t('tracker_description_getting') }); - sendMessageInPromise('getTrackerDescription', { - url: `${globals.APPS_BASE_URL}/${language}/apps/${ - encodeURIComponent(tracker.name.replace(/\s+/g, '_').toLowerCase())}?format=json`, + sendMessageInPromise('getTrackerInfo', { + url: `${globals.WTM_BASE_URL}/data/trackers/ghostery/${tracker.id}.json`, }).then((data) => { - if (data) { - const truncate = (data.length > 200) ? `${data.substr(0, 199)}...` : data; + if (data && data.description) { + const truncate = (data.description.length > 200) ? `${data.description.substr(0, 199)}...` : data.description; this.setState({ description: truncate }); this.setState({ showTrackerLearnMore: true }); } else { @@ -99,8 +98,12 @@ class GlobalTracker extends React.Component { * @return {ReactComponent} ReactComponent instance */ render() { - const { tracker, language } = this.props; - const { showMoreInfo, description, showTrackerLearnMore } = this.state; + const { tracker } = this.props; + const { + showMoreInfo, + description, + showTrackerLearnMore, + } = this.state; return (
@@ -119,7 +122,7 @@ class GlobalTracker extends React.Component { { showTrackerLearnMore && (
- + { t('tracker_description_learn_more') }
diff --git a/app/panel/components/Blocking/Tracker.jsx b/app/panel/components/Blocking/Tracker.jsx index 89b2a0260..08257bd69 100644 --- a/app/panel/components/Blocking/Tracker.jsx +++ b/app/panel/components/Blocking/Tracker.jsx @@ -139,25 +139,24 @@ class Tracker extends React.Component { /** * Implement handler for clicking on the tracker title * which shows/hides tracker description. On show it retrieves - * description from https://apps.ghostery.com and sets it in state. + * description from whotracks.me and sets it in state. */ toggleDescription() { - const { tracker, language } = this.props; + const { tracker } = this.props; + const { description } = this.state; this.setState(prevState => ({ showMoreInfo: !prevState.showMoreInfo })); - const { description } = this.state; if (description) { return; } this.setState({ description: t('tracker_description_getting') }); - sendMessageInPromise('getTrackerDescription', { - url: `${globals.APPS_BASE_URL}/${language}/apps/${ - encodeURIComponent(tracker.name.replace(/\s+/g, '_').toLowerCase())}?format=json`, + sendMessageInPromise('getTrackerInfo', { + url: `${globals.WTM_BASE_URL}/data/trackers/ghostery/${tracker.id}.json`, }).then((data) => { - if (data) { - const truncate = (data.length > 200) ? `${data.substr(0, 199)}...` : data; + if (data && data.description) { + const truncate = (data.description.length > 200) ? `${data.description.substr(0, 199)}...` : data.description; this.setState({ description: truncate }); this.setState({ showTrackerLearnMore: true }); } else { @@ -400,7 +399,7 @@ class Tracker extends React.Component {
{description} diff --git a/app/scss/ghostery_dot_com.scss b/app/scss/ghostery_dot_com.scss deleted file mode 100644 index 6ac91aaa0..000000000 --- a/app/scss/ghostery_dot_com.scss +++ /dev/null @@ -1,165 +0,0 @@ -/** - * Ghostery.com CSS - * - * Injected CSS for Ghostery website download page - * located at https://www.ghostery.com/products/ - * and Apps pages located at https://apps.ghostery.com/ and - * https://gcache.ghostery.com/ - * - * Compiled to /dist/css/ghostery_dot_com.css - * - * Ghostery Browser Extension - * https://www.ghostery.com/ - * - * Copyright 2019 Ghostery, Inc. 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 - */ - -h1.want-to-block { - width: 200px; - display: inline-block; - vertical-align: middle; -} -#global-blocking-control { - display: inline-block; - vertical-align: middle; - width: 45px; - height: 30px; - background: url('chrome-extension://__MSG_@@extension_id__/app/images/apps_pages/tracker.png') no-repeat; - background-position: -20px -20px; - &.blocked:hover { - background-position: -20px -160px; - } - &.unblocked:hover { - background-position: -20px -90px; - } -} -#app-global-blocking { - float: left; - width: 44px; - cursor: pointer; - background: url('chrome-extension://__MSG_@@extension_id__/app/images/apps_pages/tracker.png') no-repeat; - &.blocked { - height: 24px; - background-position: 3px -635px; - } - &.blocked:hover { - background-position: 3px -699px; - } - &.unblocked { - height: 24px; - background-position: -17px -891px; - } - &.unblocked:hover { - background-position: -17px -955px; - } - &.whitelisted { - background-position-y: -763px; - } - &.whitelisted:hover { - background-position-y: -827px; - } - &.paused { - background-position-y: -507px; - } - &.paused:hover { - background-position-y: -571px; - } -} - -/** - * Bootstrap Tooltip CSS - * - * Used on Ghostery Apps pages located at - * https://apps.ghostery.com/ - */ -.bs-tooltip { - position: absolute; - z-index: 1030; - display: block; - visibility: visible; - font-family: Helvetica, Arial, sans-serif; - font-size: 12px; - line-height: 1.4; - opacity: 0; - filter: alpha(opacity=0); - &.in { - opacity: 0.8; - filter: alpha(opacity=80); - } - &.top { - margin-top: -10px; - padding: 5px 0; - .bs-tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-width: 5px 5px 0; - border-top-color: #000000; - } - } - &.right { - margin-left: 10px; - padding: 0 5px; - .bs-tooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-width: 5px 5px 5px 0; - border-right-color: #000000; - } - } - &.bottom { - margin-top: 0px; - padding: 5px 0; - .bs-tooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000000; - } - } - &.left { - margin-left: -10px; - padding: 0 5px; - .bs-tooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-width: 5px 0 5px 5px; - border-left-color: #000000; - } - } - .bs-tooltip-inner { - max-width: 200px; - padding: 5px 10px; - color: #ffffff; - text-align: center; - text-decoration: none; - background-color: #000000; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - } - .bs-tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; - } - .fade { - opacity: 0; - -webkit-transition: opacity 0.20s linear; - -moz-transition: opacity 0.20s linear; - -o-transition: opacity 0.20s linear; - transition: opacity 0.20s linear; - } - .fade.in { - opacity: .6; - } -} diff --git a/databases/bugs.json b/databases/bugs.json index b89a0406a..b47942a29 100644 --- a/databases/bugs.json +++ b/databases/bugs.json @@ -2,23 +2,28 @@ "apps": { "1": { "name": "DoubleClick", - "cat": "advertising" + "cat": "advertising", + "trackerID": "doubleclick" }, "2": { "name": "Google Analytics", - "cat": "site_analytics" + "cat": "site_analytics", + "trackerID": "google_analytics" }, "3": { "name": "Google Safeframe", - "cat": "advertising" + "cat": "advertising", + "trackerID": "google_safeframe" }, "4": { "name": "Google IMA", - "cat": "advertising" + "cat": "advertising", + "trackerID": "google_ima" }, "5": { "name": "Google Publisher Tags", - "cat": "advertising" + "cat": "advertising", + "trackerID": "google_publisher_tags" } }, "bugs": { diff --git a/databases/click2play.json b/databases/click2play.json index 20ab9b3e3..309da5e6f 100644 --- a/databases/click2play.json +++ b/databases/click2play.json @@ -8,5 +8,5 @@ "aid": 6 } ], - "click2playVersion": 0 + "version": 0 } diff --git a/databases/compatibility.json b/databases/compatibility.json index 0bcc5c085..f743da834 100644 --- a/databases/compatibility.json +++ b/databases/compatibility.json @@ -8,5 +8,5 @@ ] } ], - "compatibilityVersion": 0 + "version": 0 } diff --git a/databases/surrogates.json b/databases/surrogates.json index 58332c5d1..cc5e2ecca 100644 --- a/databases/surrogates.json +++ b/databases/surrogates.json @@ -2,13 +2,11 @@ "surrogates": { "1": "var urchinTracker=function(){},_gaq={push:function(){try {if(arguments[0][0]==='_link'){window.location.href=arguments[0][1];}}catch(er){}}},_gat={_createTracker:function(){}, _getTracker:function(){return{__noSuchMethod__:function(){},_link:function(o){if(o){location.href=o;}},_linkByPost:function(){return true;},_getLinkerUrl:function(o){return o;},_trackEvent:function(){}};}};" }, - "mappings": [ { "app_id": [13], "sid": 1 } ], - "version": 0 } diff --git a/manifest.json b/manifest.json index f1b8a7cb8..4700eb994 100644 --- a/manifest.json +++ b/manifest.json @@ -3,8 +3,8 @@ "author": "Ghostery", "name": "__MSG_name__", "short_name": "Ghostery", - "version": "8.5.4", - "version_name": "8.5.4", + "version": "8.5.5", + "version_name": "8.5.5", "default_locale": "en", "description": "__MSG_short_description__", "icons": { @@ -25,23 +25,6 @@ }, "options_page": "app/templates/hub.html", "content_scripts": [ - { - "all_frames": false, - "js": [ - "dist/ghostery_dot_com.js" - ], - "css": [ - "dist/css/ghostery_dot_com_css.css" - ], - "matches": [ - "https://www.ghostery.com/*", - "https://apps.ghostery.com/*", - "https://staging-apps.ghostery.com/*", - "https://gcache.ghostery.com/*", - "https://staging-gcache.ghostery.com/*" - ], - "run_at": "document_idle" - }, { "all_frames": false, "js": [ @@ -111,4 +94,4 @@ "web_accessible_resources": [ "app/images/*" ] -} \ No newline at end of file +} diff --git a/src/background.js b/src/background.js index 64c6fb206..e79efc612 100644 --- a/src/background.js +++ b/src/background.js @@ -68,7 +68,7 @@ const { const IS_EDGE = (BROWSER_INFO.name === 'edge'); const IS_FIREFOX = (BROWSER_INFO.name === 'firefox'); const IS_ANDROID = (BROWSER_INFO.os === 'android'); -const VERSION_CHECK_URL = `${CDN_BASE_URL}/update/version`; +const VERSION_CHECK_URL = `${CDN_BASE_URL}/update/v4/versions.json`; const ONE_DAY_MSEC = 86400000; const ONE_HOUR_MSEC = 3600000; const onBeforeRequest = events.onBeforeRequest.bind(events); @@ -116,9 +116,9 @@ function updateDBs() { utils.getJson(VERSION_CHECK_URL).then((data) => { log('Database version retrieval succeeded', data); - c2pDb.update(data.click2playVersion); - compDb.update(data.compatibilityVersion); - bugDb.update(data.bugsVersion, (result) => { + c2pDb.update(data.click2play); + compDb.update(data.compatibility); + bugDb.update(data.bugs, (result) => { log('CHECK LIBRARY VERSION CALLED', result); if (result.success) { const nowTime = Number(new Date().getTime()); @@ -347,43 +347,6 @@ function handleCheckoutPages(name) { } } -/** - * Handle messages sent from dist/ghostery_dot_com.js content script. - * @memberOf Background - * - * @param {string} name message name - * @param {Object} message message data - * @param {number} tab_id tab id - */ -function handleGhosteryDotCom(name, message, tab_id) { - if (name === 'appsPageLoaded') { - if (tab_id) { - sendMessage(tab_id, 'appsPageData', { - blocked: conf.selected_app_ids[message.id] === 1 - }); - } else { - utils.getActiveTab((tab) => { - if (tab) { - sendMessage(tab.id, 'appsPageData', { - blocked: conf.selected_app_ids[message.id] === 1 - }); - } - }); - } - } else if (name === 'panelSelectedAppsUpdate') { - // This lets the user block trackers from https://apps.ghostery.com - const { selected_app_ids } = conf; - if (message.app_selected) { - selected_app_ids[message.app_id] = 1; - } else { - delete selected_app_ids[message.app_id]; - } - - conf.selected_app_ids = selected_app_ids; - } - return false; -} - /** * Handle messages sent from app/js/notifications.js content script. * @@ -673,10 +636,6 @@ function onMessageHandler(request, sender, callback) { // Purplebox script events return handlePurplebox(name, message, tab_id, callback); } - if (origin === 'ghostery_dot_com') { - // Ghostery.com and apps pages - return handleGhosteryDotCom(name, message, tab_id); - } if (origin === 'page_performance' && name === 'recordPageInfo') { tabInfo.setTabInfo(tab_id, 'pageTiming', message.performanceAPI); panelData.postPageLoadTime(tab_id); @@ -759,10 +718,11 @@ function onMessageHandler(request, sender, callback) { } return true; } - if (name === 'getTrackerDescription') { + if (name === 'getTrackerInfo') { utils.getJson(message.url).then((result) => { - const description = (result) ? ((result.company_in_their_own_words) ? result.company_in_their_own_words : ((result.company_description) ? result.company_description : '')) : ''; - callback(description); + callback(result); + }).catch(() => { + callback(false); }); return true; } @@ -1347,11 +1307,9 @@ function initializeEventListeners() { // Fires when a request is about to send headers chrome.webRequest.onBeforeSendHeaders.addListener(Events.onBeforeSendHeaders.bind(events), { urls: [ - 'https://l.ghostery.com/*', 'https://d.ghostery.com/*', 'https://cmp-cdn.ghostery.com/*', 'https://cdn.ghostery.com/*', - 'https://apps.ghostery.com/*', 'https://gcache.ghostery.com/*' ] }, ['requestHeaders', 'blocking']); diff --git a/src/classes/BugDb.js b/src/classes/BugDb.js index 5ca1fd738..d9b1186c1 100644 --- a/src/classes/BugDb.js +++ b/src/classes/BugDb.js @@ -12,7 +12,7 @@ */ import { - difference, each, every, keys, reduce, size + difference, each, every, keys, size } from 'underscore'; import conf from './Conf'; import Updatable from './Updatable'; @@ -118,6 +118,7 @@ class BugDb extends Updatable { blocked, shouldShow: true, catId: category, + trackerID: db.apps[appId].trackerID, }); } @@ -194,34 +195,13 @@ class BugDb extends Updatable { if (!fromMemory) { const old_bugs = conf.bugs; let new_app_ids; - // if there is an older bugs object in storage, - // update newAppIds and apply block-by-default - if (old_bugs) { - if (old_bugs.hasOwnProperty('version') && bugs.version > old_bugs.version) { - new_app_ids = BugDb.updateNewAppIds(bugs.apps, old_bugs.apps); - - if (new_app_ids.length) { - BugDb.applyBlockByDefault(new_app_ids); - db.JUST_UPDATED_WITH_NEW_TRACKERS = true; - } - - // pre-trie/legacy db - } else if (old_bugs.hasOwnProperty('bugsVersion') && bugs.version !== old_bugs.bugsVersion) { - const old_apps = reduce(old_bugs.bugs, (acc, bug) => { - acc[bug.aid] = true; - return acc; - }, {}); - - new_app_ids = BugDb.updateNewAppIds(bugs.apps, old_apps); - - if (new_app_ids.length) { - BugDb.applyBlockByDefault(new_app_ids); - - // don't claim new trackers when db got downgraded by version - if (bugs.version > old_bugs.bugsVersion) { - db.JUST_UPDATED_WITH_NEW_TRACKERS = true; - } - } + // if there is an older bugs object in storage update newAppIds and apply block-by-default + if (old_bugs && old_bugs.hasOwnProperty('version') && (old_bugs.version !== bugs.version)) { + new_app_ids = BugDb.updateNewAppIds(bugs.apps, old_bugs.apps); + + if (new_app_ids.length) { + BugDb.applyBlockByDefault(new_app_ids); + db.JUST_UPDATED_WITH_NEW_TRACKERS = true; } } diff --git a/src/classes/Click2PlayDb.js b/src/classes/Click2PlayDb.js index 69172c150..4ab8791b4 100644 --- a/src/classes/Click2PlayDb.js +++ b/src/classes/Click2PlayDb.js @@ -41,7 +41,7 @@ class Click2PlayDb extends Updatable { log('processing c2p...'); try { - db = Click2PlayDb._buildDb(data.click2play, data.click2playVersion); + db = Click2PlayDb._buildDb(data.click2play, data.version); } catch (e) { log('Click2PlayDb processList() error', e); return false; diff --git a/src/classes/CompatibilityDb.js b/src/classes/CompatibilityDb.js index 94afc446e..23e382233 100644 --- a/src/classes/CompatibilityDb.js +++ b/src/classes/CompatibilityDb.js @@ -36,7 +36,7 @@ class CompatibilityDb extends Updatable { log('processing comp...'); try { - db = CompatibilityDb._buildDb(comp.compatibility, comp.compatibilityVersion); + db = CompatibilityDb._buildDb(comp.compatibility, comp.version); } catch (e) { log('CompatibilityDb processList() error', e); return false; diff --git a/src/classes/EventHandlers.js b/src/classes/EventHandlers.js index bd3c35016..e873bc561 100644 --- a/src/classes/EventHandlers.js +++ b/src/classes/EventHandlers.js @@ -643,9 +643,8 @@ class EventHandlers { chrome.tabs.update(details.tabId, { url }); }, 0); } - return { - // If true, the request is cancelled. This prevents the request from being sent. + // If true, the request is canceled. This prevents the request from being sent. cancel: true }; } diff --git a/src/classes/FoundBugs.js b/src/classes/FoundBugs.js index 73332e226..85c9c75ac 100644 --- a/src/classes/FoundBugs.js +++ b/src/classes/FoundBugs.js @@ -53,7 +53,8 @@ class FoundBugs { * blocked: boolean, * type: string, * request_id: string - * }] + * }], + * trackerID: string * }], * appsMetadata: { * appId: { @@ -210,6 +211,7 @@ class FoundBugs { cats_obj[cid].trackers.push({ id: appid, name: db.apps[appid].name, + trackerID: db.apps[appid].trackerID, blocked: bugs[id].blocked }); if (bugs[id].blocked) { @@ -227,6 +229,7 @@ class FoundBugs { trackers: [{ id: appid, name: db.apps[appid].name, + trackerID: db.apps[appid].trackerID, blocked: bugs[id].blocked }], blocked: (bugs[id].blocked ? 1 : 0), @@ -496,12 +499,13 @@ class FoundBugs { appsMetadata[aid].needsCompatibilityCheck = appsMetadata[aid].needsCompatibilityCheck && app.blocked; } else { - const { name, cat } = db.apps[aid]; + const { name, cat, trackerID } = db.apps[aid]; const apps_len = apps.push({ id: aid, name, cat, + trackerID, blocked, sources, hasCompatibilityIssue: false, diff --git a/src/classes/Globals.js b/src/classes/Globals.js index 8c7a11582..6ba7ad2a4 100644 --- a/src/classes/Globals.js +++ b/src/classes/Globals.js @@ -57,7 +57,7 @@ class Globals { this.METRICS_BASE_URL = `https://${this.DEBUG ? 'staging-d' : 'd'}.ghostery.com`; this.CMP_BASE_URL = `https://${this.DEBUG ? 'staging-cmp-cdn' : 'cmp-cdn'}.ghostery.com`; this.CDN_BASE_URL = `https://${this.DEBUG ? 'staging-cdn' : 'cdn'}.ghostery.com`; - this.APPS_BASE_URL = `https://${this.DEBUG ? 'staging-apps' : 'apps'}.ghostery.com`; + this.WTM_BASE_URL = 'https://www.whotracks.me'; this.GCACHE_BASE_URL = `https://${this.DEBUG ? 'staging-gcache' : 'gcache'}.ghostery.com`; this.AUTH_SERVER = `https://consumerapi.${this.GHOSTERY_ROOT_DOMAIN}`; this.ACCOUNT_SERVER = `https://accountapi.${this.GHOSTERY_ROOT_DOMAIN}`; diff --git a/src/classes/PanelData.js b/src/classes/PanelData.js index ca064247d..a3e1e5866 100644 --- a/src/classes/PanelData.js +++ b/src/classes/PanelData.js @@ -704,6 +704,7 @@ class PanelData { id, name, sources, + trackerID, } = tracker; const { blocked, ss_allowed, ss_blocked } = trackerState; @@ -717,6 +718,7 @@ class PanelData { shouldShow: true, // used for filtering tracker list catId: cat, sources, + trackerID, warningCompatibility: hasCompatibilityIssue, warningInsecure: hasInsecureIssue, warningSlow: hasLatencyIssue, diff --git a/src/classes/Updatable.js b/src/classes/Updatable.js index b8a5ba576..740a38528 100644 --- a/src/classes/Updatable.js +++ b/src/classes/Updatable.js @@ -74,10 +74,9 @@ class Updatable { _localFetcher() { return new Promise((resolve, reject) => { const memory = conf[this.type]; - const version_property = (this.type === 'bugs' || this.type === 'surrogates' ? 'version' : (`${this.type}Version`)); // nothing in storage, or it's so old it doesn't have a version - if (!memory || !memory.hasOwnProperty(version_property)) { + if (!memory || !memory.hasOwnProperty('version')) { // return what's on disk log(`fetching ${this.type} from disk`); @@ -94,7 +93,7 @@ class Updatable { } else if (this.just_upgraded) { // on upgrades, see if json shipped w/ the extension is more recent fetchLocalJSONResource(`databases/${this.type}.json`).then((disk) => { - if (disk[version_property] > memory[version_property]) { + if (disk.version !== memory.version) { log(`fetching updated${this.type} from disk`); resolve({ fromMemory: false, @@ -131,8 +130,7 @@ class Updatable { */ _remoteFetcher(callback) { log(`fetching ${this.type} from remote`); - const UPDATE_URL = `${CDN_BASE_URL}/update/${ - this.type === 'bugs' ? 'v3/bugs' : this.type}`; + const UPDATE_URL = `${CDN_BASE_URL}/update/v4/${this.type}.json`; getJson(UPDATE_URL).then((list) => { callback(true, list); @@ -153,7 +151,7 @@ class Updatable { log('LOCAL VERSION, SERVER VERSION', this.db.version, options.version); // is the local version already up-to-date? - if (this.db.version && options.version && (options.version <= this.db.version)) { + if (this.db.version && options.version && (options.version === this.db.version)) { if (options.callback) { options.callback({ success: true, diff --git a/src/utils/click2play.js b/src/utils/click2play.js index 4f2b10ea0..a3b63d314 100644 --- a/src/utils/click2play.js +++ b/src/utils/click2play.js @@ -181,7 +181,8 @@ export function buildC2P(details, app_id) { export function buildRedirectC2P(redirectUrls, app_id) { const host_url = processUrl(redirectUrls.url).hostname; const redirect_url = processUrl(redirectUrls.redirectUrl).hostname; - const app_name = bugDb.db.apps[app_id].name; + const { name, trackerID } = bugDb.db.apps[app_id]; + const wtmURL = `${globals.WTM_BASE_URL}/trackers/${encodeURIComponent(trackerID).toLowerCase()}`; globals.BLOCKED_REDIRECT_DATA = {}; globals.BLOCKED_REDIRECT_DATA.app_id = app_id; @@ -192,13 +193,11 @@ export function buildRedirectC2P(redirectUrls, app_id) { blocked_redirect_page_title: t('blocked_redirect_page_title'), blocked_redirect_prevent: t( 'blocked_redirect_prevent', - // It is unlikely that apps pages will ever be translated - // [host_url, redirect_url, app_name, 'https://' + globals.APPS_SUB_DOMAIN + '.ghostery.com/' + conf.language + '/apps/' + encodeURIComponent(app_name.replace(/\s+/g, '_').toLowerCase())]), - [host_url, redirect_url, app_name, `${globals.APPS_BASE_URL}/en/apps/${encodeURIComponent(app_name.replace(/\s+/g, '_').toLowerCase())}`] + [host_url, redirect_url, name, wtmURL] ), blocked_redirect_action_always_title: t('blocked_redirect_action_always_title'), blocked_redirect_action_through_once_title: t('blocked_redirect_action_through_once_title'), - blocked_redirect_url_content: t('blocked_redirect_url_content', [redirectUrls.redirectUrl, app_name]) + blocked_redirect_url_content: t('blocked_redirect_url_content', [redirectUrls.redirectUrl, name]) }; return chrome.extension.getURL('app/templates/blocked_redirect.html'); } diff --git a/test/src/BugDB.test.js b/test/src/BugDB.test.js index cee528927..458bc4b50 100644 --- a/test/src/BugDB.test.js +++ b/test/src/BugDB.test.js @@ -29,19 +29,23 @@ describe('src/classes/BugDb.js', () => { "apps": { "3": { "name": "Clicky", - "cat": "site_analytics" + "cat": "site_analytics", + "trackerID": "clicky" }, "5": { "name": "Statisfy", - "cat": "site_analytics" + "cat": "site_analytics", + "trackerID": "statisfy" }, "6": { "name": "Google Widgets", - "cat": "customer_interaction" + "cat": "customer_interaction", + "trackerID": "google_widgets", }, "8": { "name": "Twitter Badge", "cat": "social_media", + "trackerID": "twitter_badge", "tags": [ 39 ] diff --git a/test/src/Foundbugs.test.js b/test/src/Foundbugs.test.js index 71b0567b6..30c1d92d8 100644 --- a/test/src/Foundbugs.test.js +++ b/test/src/Foundbugs.test.js @@ -42,9 +42,9 @@ describe('src/classes/FoundBugs.js', () => { conf.init().then(() => { //Start init sequence for testing. Changing the fakeServer() response each time for the following fetchJson() call const bugsJson = JSON.stringify({ - "apps": {"13": {"name": "Google Analytics","cat": "site_analytics","tags": [48]}, - "464": {"name": "Facebook Social Plugins","cat": "social_media","tags": [39]}, - "614": {"name": "New Relic","cat": "site_analytics","tags": [48]}}, + "apps": {"13": {"name": "Google Analytics","cat": "site_analytics","trackerID": "google_analytics","tags": [48]}, + "464": {"name": "Facebook Social Plugins","cat": "social_media","trackerID": "facebook_social_plugins","tags": [39]}, + "614": {"name": "New Relic","cat": "site_analytics","trackerID": "new_relic","tags": [48]}}, "bugs": {"2": {"aid": 13},"935": {"aid": 13},"1982": {"aid": 13},"719": {"aid": 464},"1009": {"aid": 614}}, "firstPartyExceptions": {'something': true}, "patterns": { regex: { 'something': true} }, diff --git a/tools/amo/build.sh b/tools/amo/build.sh index b44ef857c..074375d05 100755 --- a/tools/amo/build.sh +++ b/tools/amo/build.sh @@ -110,10 +110,10 @@ cat ${TMP_FILE} > $VERSION_FILE # copy into manifest.json rm -f ${TMP_FILE} # Download databases -curl "https://cdn.ghostery.com/update/v3/bugs" -o $DB_DIR/bugs.json --compressed --fail -curl "https://cdn.ghostery.com/update/click2play" -o $DB_DIR/click2play.json --compressed --fail -curl "https://cdn.ghostery.com/update/compatibility" -o $DB_DIR/compatibility.json --compressed --fail -curl "https://cdn.ghostery.com/update/surrogates" -o $DB_DIR/surrogates.json --compressed --fail +curl "https://cdn.ghostery.com/update/v4/bugs" -o $DB_DIR/bugs.json --compressed --fail +curl "https://cdn.ghostery.com/update/v4/click2play" -o $DB_DIR/click2play.json --compressed --fail +curl "https://cdn.ghostery.com/update/v4/compatibility" -o $DB_DIR/compatibility.json --compressed --fail +curl "https://cdn.ghostery.com/update/v4/surrogates" -o $DB_DIR/surrogates.json --compressed --fail # Zip final build files echo "Zipping to $(pwd)/$BUILD_DIR/" diff --git a/webpack.config.js b/webpack.config.js index b8c0f24a7..6dc791712 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -49,7 +49,6 @@ module.exports = { checkout_pages: [`${CONTENT_SCRIPTS_DIR}/checkout_pages.js`], click_to_play: [`${CONTENT_SCRIPTS_DIR}/click_to_play.js`], content_script_bundle: [`${CONTENT_SCRIPTS_DIR}/content_script_bundle.js`], - ghostery_dot_com: [`${CONTENT_SCRIPTS_DIR}/ghostery_dot_com.js`], hub_react: [`${HUB_DIR}/index.jsx`], licenses_react: [`${LICENSES_DIR}/Licenses.jsx`, `${LICENSES_DIR}/License.jsx`], notifications: [`${CONTENT_SCRIPTS_DIR}/notifications.js`], @@ -61,7 +60,6 @@ module.exports = { // Sass foundation: [`${SASS_DIR}/vendor/foundation.scss`], foundation_hub: [`${SASS_DIR}/vendor/foundation_hub.scss`], - ghostery_dot_com_css: [`${SASS_DIR}/ghostery_dot_com.scss`], hub: [`${SASS_DIR}/hub.scss`], licenses: [`${SASS_DIR}/licenses.scss`], panel: [`${SASS_DIR}/panel.scss`], @@ -88,7 +86,6 @@ module.exports = { onBuildExit: [ `${RM} ./dist/foundation.js`, `${RM} ./dist/foundation_hub.js`, - `${RM} ./dist/ghostery_dot_com_css.js`, `${RM} ./dist/hub.js`, `${RM} ./dist/licenses.js`, `${RM} ./dist/panel.js`,