From 86b4f20ca49210ae392379c70db67d432df5d6f9 Mon Sep 17 00:00:00 2001 From: Leury Rodriguez Date: Mon, 26 Oct 2020 12:54:18 -0400 Subject: [PATCH] (8.5.4) GH-2153: Future-proof metrics uninstall URL (#615) * Use only crucial params for uninstall type * Move some query string construction to helper * Group METRICS_URL_SET with other consts * Syntax fix Co-authored-by: Ilya Zarembsky Co-authored-by: Christopher Tino <4699516+christophertino@users.noreply.github.com> --- src/classes/Metrics.js | 138 +++++++++++++++++++++++------------------ 1 file changed, 77 insertions(+), 61 deletions(-) diff --git a/src/classes/Metrics.js b/src/classes/Metrics.js index e9c9cd31b..74929a9c8 100644 --- a/src/classes/Metrics.js +++ b/src/classes/Metrics.js @@ -27,6 +27,16 @@ const CRITICAL_METRICS = ['install', 'install_complete', 'upgrade', 'active', 'e const CAMPAIGN_METRICS = ['install', 'active', 'uninstall']; const { METRICS_BASE_URL, EXTENSION_VERSION, BROWSER_INFO } = globals; const MAX_DELAYED_PINGS = 100; +// Set of conf keys used in constructing telemetry url +const METRICS_URL_SET = new Set([ + 'enable_human_web', + 'enable_offers', + 'account', + 'enable_metrics', + 'show_alert', + 'alert_expanded', + 'show_cmp' +]); /** * Class for handling telemetry pings. @@ -190,27 +200,26 @@ class Metrics { * @param {string} conf key being changed */ setUninstallUrl(key) { - if (typeof chrome.runtime.setUninstallURL === 'function') { - // Set of conf keys used in constructing telemetry url - const METRICS_URL_SET = new Set([ - 'enable_human_web', - 'enable_offers', - 'account', - 'enable_metrics', - 'show_alert', - 'alert_expanded', - 'show_cmp' - ]); - - if (!key || METRICS_URL_SET.has(key)) { - const metrics_url = this._buildMetricsUrl('uninstall'); - if (metrics_url.length) { - chrome.runtime.setUninstallURL(metrics_url); - } + if (typeof chrome.runtime.setUninstallURL === 'function' && (!key || METRICS_URL_SET.has(key))) { + const metrics_url = this._buildMetricsUrl('uninstall'); + if (metrics_url.length) { + chrome.runtime.setUninstallURL(metrics_url); } } } + /** + * Helper for building query string key value pairs + * + * @private + * + * @since 8.5.4 + * @param {string} query param to be included in string + * @param {string} value number value to be passed on through qeury string + * @return {string} complete query component + */ + _buildQueryPair = (query, value) => `&${query}=${encodeURIComponent(value)}`; + /** * Build telemetry URL * @@ -223,87 +232,94 @@ class Metrics { _buildMetricsUrl(type, frequency) { const frequencyString = (type !== 'uninstall') ? `/${frequency}` : ''; - let metrics_url = `${METRICS_BASE_URL}/${type}${frequencyString}?gr=-1` + - // Old parameters, old names - // Human web - `&hw=${encodeURIComponent(conf.enable_human_web ? '1' : '0')}` + + let metrics_url = `${METRICS_BASE_URL}/${type}${frequencyString}?gr=-1`; + metrics_url += + // Crucial parameters + // Always added for uninstall URL // Extension version - `&v=${encodeURIComponent(EXTENSION_VERSION)}` + + this._buildQueryPair('v', EXTENSION_VERSION) + // User agent - browser - `&ua=${encodeURIComponent(BROWSER_INFO.token)}` + + this._buildQueryPair('ua', BROWSER_INFO.token) + // Operating system - `&os=${encodeURIComponent(BROWSER_INFO.os)}` + + this._buildQueryPair('os', BROWSER_INFO.os) + // Browser language - `&l=${encodeURIComponent(conf.language)}` + + this._buildQueryPair('l', conf.language) + // Browser version - `&bv=${encodeURIComponent(BROWSER_INFO.version)}` + + this._buildQueryPair('bv', BROWSER_INFO.version) + + // Offers (former offers) + this._buildQueryPair('of', conf.enable_offers ? '1' : '0') + + // Date of install (former install_date) + this._buildQueryPair('id', conf.install_date) + + // Showing campaign messages (former show_cmp) + this._buildQueryPair('sc', conf.show_cmp ? '1' : '0') + + // Subscription Type + this._buildQueryPair('st', Metrics._getSubscriptionType().toString()) + + + // New parameters for Ghostery 8.5.2 + // Subscription Interval + this._buildQueryPair('si', Metrics._getSubscriptionInterval().toString()) + + // Product ID Parameter + this._buildQueryPair('pi', 'gbe'); + if (type !== 'uninstall') { + metrics_url += + // Old parameters, old names + // Human web + this._buildQueryPair('hw', conf.enable_human_web ? '1' : '0') + // Old parameters, new names - // Offers (former offers) - `&of=${encodeURIComponent(conf.enable_offers ? '1' : '0')}` + // Random number, assigned at install (former install_rand) - `&ir=${encodeURIComponent(conf.install_random_number)}` + + this._buildQueryPair('ir', conf.install_random_number) + // Login state (former signed_in) - `&sn=${encodeURIComponent(conf.account ? '1' : '0')}` + - // Date of install (former install_date) - `&id=${encodeURIComponent(conf.install_date)}` + + this._buildQueryPair('sn', conf.account ? '1' : '0') + // Noncritical ping (former noncritical) - `&nc=${encodeURIComponent(conf.enable_metrics ? '1' : '0')}` + + this._buildQueryPair('nc', conf.enable_metrics ? '1' : '0') + // Purplebox state (former purplebox) - `&pb=${encodeURIComponent(conf.show_alert ? (conf.alert_expanded ? '1' : '2') : '0')}` + - // Showing campaign messages (former show_cmp) - `&sc=${encodeURIComponent(conf.show_cmp ? '1' : '0')}` + + this._buildQueryPair('pb', conf.show_alert ? (conf.alert_expanded ? '1' : '2') : '0') + // New parameters, new names // Extension_view - which view of the extension is the user in - `&ev=${encodeURIComponent(conf.is_expert ? (conf.is_expanded ? '3' : '2') : '1')}` + + this._buildQueryPair('ev', conf.is_expert ? (conf.is_expanded ? '3' : '2') : '1') + // Adblocking state - `&ab=${encodeURIComponent(conf.enable_ad_block ? '1' : '0')}` + + this._buildQueryPair('ab', conf.enable_ad_block ? '1' : '0') + // Smartblocking state - `&sm=${encodeURIComponent(conf.enable_smart_block ? '1' : '0')}` + + this._buildQueryPair('sm', conf.enable_smart_block ? '1' : '0') + // Antitracking state - `&at=${encodeURIComponent(conf.enable_anti_tracking ? '1' : '0')}` + + this._buildQueryPair('at', conf.enable_anti_tracking ? '1' : '0') + // The deepest setup page reached by user during setup - `&ss=${encodeURIComponent((conf.metrics.install_complete_all || type === 'install_complete') ? conf.setup_step.toString() : '-1')}` + + this._buildQueryPair('ss', (conf.metrics.install_complete_all || type === 'install_complete') ? conf.setup_step.toString() : '-1') + // The number of times the user has gone through setup - `&sl=${encodeURIComponent(conf.setup_number.toString())}` + + this._buildQueryPair('sl', conf.setup_number.toString()) + // Type of blocking selected during setup - `&sb=${encodeURIComponent(conf.setup_block.toString())}` + + this._buildQueryPair('sb', conf.setup_block.toString()) + // Recency, days since last active daily ping - `&rc=${encodeURIComponent(Metrics._getRecencyActive(type, frequency).toString())}` + + this._buildQueryPair('rc', Metrics._getRecencyActive(type, frequency).toString()) + // New parameters to Ghostery 8.3 - // Subscription Type - `&st=${encodeURIComponent(Metrics._getSubscriptionType().toString())}` + // Whether the computer ever had a Paid Subscription - `&ps=${encodeURIComponent(conf.paid_subscription ? '1' : '0')}` + + this._buildQueryPair('ps', conf.paid_subscription ? '1' : '0') + // Active Velocity - `&va=${encodeURIComponent(Metrics._getVelocityActive(type).toString())}` + + this._buildQueryPair('va', Metrics._getVelocityActive(type).toString()) + // Engaged Recency - `&re=${encodeURIComponent(Metrics._getRecencyEngaged(type, frequency).toString())}` + + this._buildQueryPair('re', Metrics._getRecencyEngaged(type, frequency).toString()) + // Engaged Velocity - `&ve=${encodeURIComponent(Metrics._getVelocityEngaged(type).toString())}` + + this._buildQueryPair('ve', Metrics._getVelocityEngaged(type).toString()) + // Theme - `&th=${encodeURIComponent(Metrics._getThemeValue().toString())}` + - - // New parameters for Ghostery 8.5.2 - // Subscription Interval - `&si=${encodeURIComponent(Metrics._getSubscriptionInterval().toString())}` + - // Product ID Parameter - `&pi=${encodeURIComponent('gbe')}` + + this._buildQueryPair('th', Metrics._getThemeValue().toString()) + // New parameter for Ghostery 8.5.3 // AB tests enabled? - `&ts=${encodeURIComponent(conf.enable_abtests ? '1' : '0')}`; + this._buildQueryPair('ts', conf.enable_abtests ? '1' : '0'); + } - if (CAMPAIGN_METRICS.includes(type)) { + if (CAMPAIGN_METRICS.includes(type) || type === 'uninstall') { // only send campaign attribution when necessary metrics_url += // Marketing source (Former utm_source) - `&us=${encodeURIComponent(this.utm_source)}` + + this._buildQueryPair('us', this.utm_source) + // Marketing campaign (Former utm_campaign) - `&uc=${encodeURIComponent(this.utm_campaign)}`; + this._buildQueryPair('uc', this.utm_campaign); } + return metrics_url; }