From 653632e2458511bcf6fb746e4adac17135bb844e Mon Sep 17 00:00:00 2001 From: Frank Chiarulli Jr Date: Tue, 22 Dec 2020 13:45:24 -0500 Subject: [PATCH 01/14] add search messager class and allow calling of refreshToken --- src/background.js | 11 ++++++++ src/classes/Account.js | 2 ++ src/classes/SearchMessager.js | 51 +++++++++++++++++++++++++++++++++++ src/utils/api.js | 4 +++ 4 files changed, 68 insertions(+) create mode 100644 src/classes/SearchMessager.js diff --git a/src/background.js b/src/background.js index 64c6fb206..f59b37acb 100644 --- a/src/background.js +++ b/src/background.js @@ -40,6 +40,7 @@ import tabInfo from './classes/TabInfo'; import metrics from './classes/Metrics'; import account from './classes/Account'; import promoModals from './classes/PromoModals'; +import searchMessager from './classes/SearchMessager'; // utilities import { allowAllwaysC2P } from './utils/click2play'; import * as common from './utils/common'; @@ -1648,6 +1649,15 @@ function initializeGhosteryModules() { }); } +/** + * Initialize Search Messaging. + * @memberOf Background + */ +function initializeSearchMessaging() { + const sm = new searchMessager(); + sm.init() +} + /** * Application Initializer * Called whenever the browser starts or the extension is @@ -1659,6 +1669,7 @@ function init() { initializePopup(); initializeEventListeners(); initializeVersioning(); + initializeSearchMessaging(); return metrics.init(globals.JUST_INSTALLED).then(() => initializeGhosteryModules().then(() => { account.migrate() .then(() => { diff --git a/src/classes/Account.js b/src/classes/Account.js index c65ba35f7..47e18ce82 100644 --- a/src/classes/Account.js +++ b/src/classes/Account.js @@ -142,6 +142,8 @@ class Account { }) ) + refreshToken = () => api.refreshToken() + // @TODO a 404 here should trigger a logout getUser = () => ( this._getUserID() diff --git a/src/classes/SearchMessager.js b/src/classes/SearchMessager.js new file mode 100644 index 000000000..e9ed4b5f7 --- /dev/null +++ b/src/classes/SearchMessager.js @@ -0,0 +1,51 @@ +/** + * Search Messager + * + * 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 + */ + +import ExtMessenger from './ExtMessenger'; +import account from './Account'; +import { log } from '../utils/common'; + +/** + * Class for handling cross-extension messaging. + * @memberOf BackgroundClasses + */ +export default class SearchMessager { + constructor() { + this.extensionId = 'search@ghostery.com'; + this._messageHandler = this._messageHandler.bind(this); + } + + init() { + ExtMessenger.addListener(this._messageHandler); + } + + unload() { + ExtMessenger.removeListener(this._messageHandler); + } + + _messageHandler(message, sender, sendResponse) { + if (sender.id !== this.extensionId) { + return; + } + + // allow search extension to refresh token + if (message === "refreshToken") { + account.refreshToken() + .then(() => sendResponse({ success: true })) + .catch(error => sendResponse({ success: false, error })); + return true + } else { + log('SearchMessager error: Unhandled message', message); + } + } +} diff --git a/src/utils/api.js b/src/utils/api.js index 3ebea93d7..a0d0aac05 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -27,6 +27,10 @@ class Api { } } + refreshToken() { + return this._refreshToken().then(this.isRefreshing = false); + } + _refreshToken() { if (this.isRefreshing) { let bindedResolve; From 0985b0fac4c9d701861d2e66cc9aa316febd5c5b Mon Sep 17 00:00:00 2001 From: Frank Chiarulli Jr Date: Tue, 22 Dec 2020 16:49:19 -0500 Subject: [PATCH 02/14] only init on gb --- src/background.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/background.js b/src/background.js index f59b37acb..0de1076d0 100644 --- a/src/background.js +++ b/src/background.js @@ -67,6 +67,7 @@ const { CDN_BASE_URL, BROWSER_INFO, IS_CLIQZ } = globals; const IS_EDGE = (BROWSER_INFO.name === 'edge'); +const IS_GHOSTERY_BROWSER = (BROWSER_INFO.name === 'ghostery_desktop'); const IS_FIREFOX = (BROWSER_INFO.name === 'firefox'); const IS_ANDROID = (BROWSER_INFO.os === 'android'); const VERSION_CHECK_URL = `${CDN_BASE_URL}/update/version`; @@ -1650,10 +1651,10 @@ function initializeGhosteryModules() { } /** - * Initialize Search Messaging. + * Initialize Search Message Handler. * @memberOf Background */ -function initializeSearchMessaging() { +function initializeSearchMessageHandler() { const sm = new searchMessager(); sm.init() } @@ -1669,7 +1670,9 @@ function init() { initializePopup(); initializeEventListeners(); initializeVersioning(); - initializeSearchMessaging(); + if (IS_GHOSTERY_BROWSER) { + initializeSearchMessageHandler(); + } return metrics.init(globals.JUST_INSTALLED).then(() => initializeGhosteryModules().then(() => { account.migrate() .then(() => { From 0e512227637bd405f661879a3061461fb495193a Mon Sep 17 00:00:00 2001 From: Frank Chiarulli Jr Date: Wed, 23 Dec 2020 10:59:16 -0500 Subject: [PATCH 03/14] lint fixes --- src/background.js | 6 +++--- src/classes/SearchMessager.js | 10 +++++----- src/utils/api.js | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/background.js b/src/background.js index 0de1076d0..30fa56e8c 100644 --- a/src/background.js +++ b/src/background.js @@ -40,7 +40,7 @@ import tabInfo from './classes/TabInfo'; import metrics from './classes/Metrics'; import account from './classes/Account'; import promoModals from './classes/PromoModals'; -import searchMessager from './classes/SearchMessager'; +import SearchMessager from './classes/SearchMessager'; // utilities import { allowAllwaysC2P } from './utils/click2play'; import * as common from './utils/common'; @@ -1655,8 +1655,8 @@ function initializeGhosteryModules() { * @memberOf Background */ function initializeSearchMessageHandler() { - const sm = new searchMessager(); - sm.init() + const sm = new SearchMessager(); + sm.init(); } /** diff --git a/src/classes/SearchMessager.js b/src/classes/SearchMessager.js index e9ed4b5f7..ef68d1e6e 100644 --- a/src/classes/SearchMessager.js +++ b/src/classes/SearchMessager.js @@ -35,17 +35,17 @@ export default class SearchMessager { _messageHandler(message, sender, sendResponse) { if (sender.id !== this.extensionId) { - return; + return false; } // allow search extension to refresh token - if (message === "refreshToken") { + if (message === 'refreshToken') { account.refreshToken() .then(() => sendResponse({ success: true })) .catch(error => sendResponse({ success: false, error })); - return true - } else { - log('SearchMessager error: Unhandled message', message); + return true; } + log('SearchMessager error: Unhandled message', message); + return false; } } diff --git a/src/utils/api.js b/src/utils/api.js index a0d0aac05..1d99eaeef 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -28,7 +28,7 @@ class Api { } refreshToken() { - return this._refreshToken().then(this.isRefreshing = false); + return this._refreshToken().then(this.isRefreshing = false); // eslint-disable-line no-return-assign } _refreshToken() { From 952a9f4f9c1894108532f59238971276b68da1ad Mon Sep 17 00:00:00 2001 From: Frank Chiarulli Jr Date: Wed, 23 Dec 2020 11:28:05 -0500 Subject: [PATCH 04/14] add since --- src/classes/SearchMessager.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/classes/SearchMessager.js b/src/classes/SearchMessager.js index ef68d1e6e..6f38fe5d7 100644 --- a/src/classes/SearchMessager.js +++ b/src/classes/SearchMessager.js @@ -16,6 +16,8 @@ import account from './Account'; import { log } from '../utils/common'; /** + * @since 8.5.5 + * * Class for handling cross-extension messaging. * @memberOf BackgroundClasses */ From b225f5899b74dff9d6a7764dac590c45752802bb Mon Sep 17 00:00:00 2001 From: Frank Chiarulli Jr Date: Thu, 24 Dec 2020 10:57:28 -0500 Subject: [PATCH 05/14] ensure browser info is populated --- src/background.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/background.js b/src/background.js index 30fa56e8c..e50110c61 100644 --- a/src/background.js +++ b/src/background.js @@ -1651,12 +1651,15 @@ function initializeGhosteryModules() { } /** - * Initialize Search Message Handler. + * Initialize Search Message Handler on Ghostery Browser. * @memberOf Background */ -function initializeSearchMessageHandler() { - const sm = new SearchMessager(); - sm.init(); +async function initializeSearchMessageHandler() { + await globals.BROWSER_INFO_READY; // ensure browser info is set + if (IS_GHOSTERY_BROWSER) { + const sm = new SearchMessager(); + sm.init(); + } } /** @@ -1670,9 +1673,7 @@ function init() { initializePopup(); initializeEventListeners(); initializeVersioning(); - if (IS_GHOSTERY_BROWSER) { - initializeSearchMessageHandler(); - } + initializeSearchMessageHandler(); return metrics.init(globals.JUST_INSTALLED).then(() => initializeGhosteryModules().then(() => { account.migrate() .then(() => { From 3e28136a969159ef79c10aa2f04455dd70a31d9b Mon Sep 17 00:00:00 2001 From: Frank Chiarulli Jr Date: Mon, 4 Jan 2021 10:00:55 -0500 Subject: [PATCH 06/14] remove gb IS const --- src/background.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/background.js b/src/background.js index e50110c61..5960364c1 100644 --- a/src/background.js +++ b/src/background.js @@ -67,7 +67,6 @@ const { CDN_BASE_URL, BROWSER_INFO, IS_CLIQZ } = globals; const IS_EDGE = (BROWSER_INFO.name === 'edge'); -const IS_GHOSTERY_BROWSER = (BROWSER_INFO.name === 'ghostery_desktop'); const IS_FIREFOX = (BROWSER_INFO.name === 'firefox'); const IS_ANDROID = (BROWSER_INFO.os === 'android'); const VERSION_CHECK_URL = `${CDN_BASE_URL}/update/version`; @@ -1656,7 +1655,7 @@ function initializeGhosteryModules() { */ async function initializeSearchMessageHandler() { await globals.BROWSER_INFO_READY; // ensure browser info is set - if (IS_GHOSTERY_BROWSER) { + if (BROWSER_INFO.name === 'ghostery_desktop') { const sm = new SearchMessager(); sm.init(); } From 935998fcb20b5cb11638486d24f58309f139416d Mon Sep 17 00:00:00 2001 From: Frank Chiarulli Jr Date: Tue, 5 Jan 2021 09:45:50 -0500 Subject: [PATCH 07/14] fix isRefreshing invocation --- src/utils/api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/api.js b/src/utils/api.js index 1d99eaeef..b183cf8f9 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -28,7 +28,7 @@ class Api { } refreshToken() { - return this._refreshToken().then(this.isRefreshing = false); // eslint-disable-line no-return-assign + return this._refreshToken().then(() => { this.isRefreshing = false; }); } _refreshToken() { From 496448eedd8d10574e383d75e04c5ff791709d4d Mon Sep 17 00:00:00 2001 From: Frank Chiarulli Jr Date: Tue, 5 Jan 2021 09:59:06 -0500 Subject: [PATCH 08/14] move to main func, use finally --- src/utils/api.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/utils/api.js b/src/utils/api.js index b183cf8f9..b1e824fb3 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -28,10 +28,6 @@ class Api { } refreshToken() { - return this._refreshToken().then(() => { this.isRefreshing = false; }); - } - - _refreshToken() { if (this.isRefreshing) { let bindedResolve; const _processRefreshTokenEvent = (resolve, e) => { @@ -48,7 +44,7 @@ class Api { return fetch(`${this.config.AUTH_SERVER}/api/v2/refresh_token`, { method: 'POST', credentials: 'include', - }); + }).finally(() => { this.isRefreshing = false; }); } _sendReq(method, path, body) { @@ -111,9 +107,8 @@ class Api { }); } if (shouldRefresh) { - this._refreshToken() + this.refreshToken() .then((res) => { - this.isRefreshing = false; window.dispatchEvent(new CustomEvent(this.tokenRefreshedEventType, { detail: res, })); From 4f90be731548b0be5b843913f995b87bebaee1d1 Mon Sep 17 00:00:00 2001 From: Frank Chiarulli Jr Date: Tue, 5 Jan 2021 10:01:25 -0500 Subject: [PATCH 09/14] move window dispatch --- src/utils/api.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/utils/api.js b/src/utils/api.js index b1e824fb3..d803a16d8 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -44,7 +44,13 @@ class Api { return fetch(`${this.config.AUTH_SERVER}/api/v2/refresh_token`, { method: 'POST', credentials: 'include', - }).finally(() => { this.isRefreshing = false; }); + }).then((res) => { + this.isRefreshing = false; + window.dispatchEvent(new CustomEvent(this.tokenRefreshedEventType, { + detail: res, + })); + return res; + }); } _sendReq(method, path, body) { @@ -109,9 +115,6 @@ class Api { if (shouldRefresh) { this.refreshToken() .then((res) => { - window.dispatchEvent(new CustomEvent(this.tokenRefreshedEventType, { - detail: res, - })); const { status } = res; if (status >= 400) { res.json().then(data2 => ( From 0ca6af23a5eb6da4a85a56b41e4b7332395fdd9e Mon Sep 17 00:00:00 2001 From: Frank Chiarulli Jr Date: Tue, 5 Jan 2021 17:00:11 -0500 Subject: [PATCH 10/14] handle previously unhandled fetch rejections --- src/utils/api.js | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/utils/api.js b/src/utils/api.js index d803a16d8..89239cad2 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -29,15 +29,21 @@ class Api { refreshToken() { if (this.isRefreshing) { - let bindedResolve; - const _processRefreshTokenEvent = (resolve, e) => { - window.removeEventListener(this.tokenRefreshedEventType, bindedResolve, false); - resolve(e.detail); - }; - return new Promise((resolve) => { - bindedResolve = _processRefreshTokenEvent.bind(null, resolve); - window.addEventListener(this.tokenRefreshedEventType, bindedResolve, false); + const deferedPromise = {}; + deferedPromise.p = new Promise((resolve, reject) => { + deferedPromise.resolve = resolve; + deferedPromise.reject = reject; }); + const _processRefreshTokenEvent = (e) => { + window.removeEventListener(this.tokenRefreshedEventType, deferedPromise, false); + if (e.detail && e.detail.err) { + deferedPromise.reject(e.detail.err); + } else { + deferedPromise.resolve(e.detail); + } + }; + window.addEventListener(this.tokenRefreshedEventType, _processRefreshTokenEvent, false); + return deferedPromise.p; } this.isRefreshing = true; @@ -50,6 +56,12 @@ class Api { detail: res, })); return res; + }).catch((err) => { + this.isRefreshing = false; + window.dispatchEvent(new CustomEvent(this.tokenRefreshedEventType, { + detail: { err }, + })); + throw err; }); } From f3d3ff8a12d740ebbb065a04859239b609a4285f Mon Sep 17 00:00:00 2001 From: Frank Chiarulli Jr Date: Tue, 5 Jan 2021 17:47:30 -0500 Subject: [PATCH 11/14] refactor to use a single promise --- src/utils/api.js | 39 +++++++-------------------------------- 1 file changed, 7 insertions(+), 32 deletions(-) diff --git a/src/utils/api.js b/src/utils/api.js index 89239cad2..be050c81a 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -15,7 +15,7 @@ export const _getJSONAPIErrorsObject = e => [{ title: e.message || '', detail: e class Api { constructor() { - this.isRefreshing = false; + this._refreshPromise = null; this.tokenRefreshedEventType = 'tokenRefreshed'; } @@ -28,41 +28,16 @@ class Api { } refreshToken() { - if (this.isRefreshing) { - const deferedPromise = {}; - deferedPromise.p = new Promise((resolve, reject) => { - deferedPromise.resolve = resolve; - deferedPromise.reject = reject; - }); - const _processRefreshTokenEvent = (e) => { - window.removeEventListener(this.tokenRefreshedEventType, deferedPromise, false); - if (e.detail && e.detail.err) { - deferedPromise.reject(e.detail.err); - } else { - deferedPromise.resolve(e.detail); - } - }; - window.addEventListener(this.tokenRefreshedEventType, _processRefreshTokenEvent, false); - return deferedPromise.p; + if (this._refreshPromise) { + return this._refreshPromise; } - this.isRefreshing = true; - return fetch(`${this.config.AUTH_SERVER}/api/v2/refresh_token`, { + this._refreshPromise = fetch(`${this.config.AUTH_SERVER}/api/v2/refresh_token`, { method: 'POST', credentials: 'include', - }).then((res) => { - this.isRefreshing = false; - window.dispatchEvent(new CustomEvent(this.tokenRefreshedEventType, { - detail: res, - })); - return res; - }).catch((err) => { - this.isRefreshing = false; - window.dispatchEvent(new CustomEvent(this.tokenRefreshedEventType, { - detail: { err }, - })); - throw err; - }); + }).finally(() => { this._refreshPromise = null; }); + + return this._refreshPromise; } _sendReq(method, path, body) { From e49e6bcde4cffed777bf6ccfd0d464b02719a8b6 Mon Sep 17 00:00:00 2001 From: Frank Chiarulli Jr Date: Tue, 5 Jan 2021 18:23:39 -0500 Subject: [PATCH 12/14] remove old event type --- src/utils/api.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/api.js b/src/utils/api.js index be050c81a..056419c47 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -16,7 +16,6 @@ export const _getJSONAPIErrorsObject = e => [{ title: e.message || '', detail: e class Api { constructor() { this._refreshPromise = null; - this.tokenRefreshedEventType = 'tokenRefreshed'; } init(config, opts) { From d8219d2a66e54dba73979d3818734e7fce707336 Mon Sep 17 00:00:00 2001 From: Frank Chiarulli Jr Date: Tue, 5 Jan 2021 18:35:52 -0500 Subject: [PATCH 13/14] handle refreshToken errors --- src/utils/api.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/api.js b/src/utils/api.js index 056419c47..309ded82d 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -117,7 +117,8 @@ class Api { .then(() => resolve(data3)) .catch(err => reject(err)); }); - }); + }) + .catch(err => reject(err)); } else { this._errorHandler(data.errors) .then(() => resolve(data)) From 8e7bebdcb26dc1f02c1dd4c056be7af1c428d81e Mon Sep 17 00:00:00 2001 From: Frank Chiarulli Jr Date: Tue, 5 Jan 2021 22:22:40 -0500 Subject: [PATCH 14/14] update cc --- src/classes/SearchMessager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/classes/SearchMessager.js b/src/classes/SearchMessager.js index 6f38fe5d7..a5091e1db 100644 --- a/src/classes/SearchMessager.js +++ b/src/classes/SearchMessager.js @@ -4,7 +4,7 @@ * Ghostery Browser Extension * https://www.ghostery.com/ * - * Copyright 2019 Ghostery, Inc. All rights reserved. + * Copyright 2020 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