From 9f94266271a320c109cc87a183812a68fb94f3be Mon Sep 17 00:00:00 2001 From: John Tran <jptran318@gmail.com> Date: Mon, 24 May 2021 15:20:44 -0700 Subject: [PATCH 1/5] Add API to clear storage --- src/amplitude-client.js | 10 ++++++++++ src/base-cookie.js | 9 +++++++++ src/metadata-storage.js | 28 ++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/src/amplitude-client.js b/src/amplitude-client.js index 557406e6..aa8a873f 100644 --- a/src/amplitude-client.js +++ b/src/amplitude-client.js @@ -521,6 +521,16 @@ AmplitudeClient.prototype._sendEventsIfReady = function _sendEventsIfReady() { return false; // an upload was scheduled, no events were uploaded }; +/** + * Clears any saved metadata storage + * @constructor AmplitudeClient + * @public + * @return {boolean} True if metadata was cleared, false if none existed + */ +AmplitudeClient.prototype.clearStorage = function clearStorage() { + return this._metadataStorage.clear(); +}; + /** * Helper function to fetch values from storage * Storage argument allows for localStoraoge and sessionStoraoge diff --git a/src/base-cookie.js b/src/base-cookie.js index ef6457ee..45917473 100644 --- a/src/base-cookie.js +++ b/src/base-cookie.js @@ -92,6 +92,14 @@ const sortByEventTime = (cookies) => { }); }; +/** + * Clears cookie by setting expiration to a past date + * @param {*} name + */ +const clear = (name) => { + document.cookie = `${name}= ; expires = Thu, 01 Jan 1970 00:00:00 GMT'`; +}; + // test that cookies are enabled - navigator.cookiesEnabled yields false positives in IE, need to test directly const areCookiesEnabled = (opts = {}) => { const cookieName = Constants.COOKIE_TEST_PREFIX + base64Id(); @@ -113,6 +121,7 @@ const areCookiesEnabled = (opts = {}) => { export default { set, get, + clear, getAll, getLastEventTime, sortByEventTime, diff --git a/src/metadata-storage.js b/src/metadata-storage.js index f83b15f8..2a19249f 100644 --- a/src/metadata-storage.js +++ b/src/metadata-storage.js @@ -163,6 +163,34 @@ class MetadataStorage { sequenceNumber: parseInt(values[Constants.SEQUENCE_NUMBER_INDEX], 32), }; } + + /** + * Clears any saved metadata storage + * @constructor AmplitudeClient + * @public + * @return {boolean} True if metadata was cleared, false if none existed + */ + clear() { + let str; + if (this.storage === Constants.STORAGE_COOKIES) { + str = baseCookie.get(this.getCookieStorageKey() + '='); + baseCookie.clear(this.getCookieStorageKey()); + } + if (!str) { + str = ampLocalStorage.getItem(this.storageKey); + ampLocalStorage.clear(); + } + if (!str) { + try { + str = window.sessionStorage && window.sessionStorage.getItem(this.storageKey); + window.sessionStorage.clear(); + } catch (e) { + utils.log.info(`window.sessionStorage unavailable. Reason: "${e}"`); + } + } + if (!str) false; + return true; + } } export default MetadataStorage; From 4e63b68f85c626c9a2aca7c84aa413d0a7dc9218 Mon Sep 17 00:00:00 2001 From: John Tran <jptran318@gmail.com> Date: Wed, 26 May 2021 01:57:15 -0700 Subject: [PATCH 2/5] Add tests --- test/amplitude-client.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/amplitude-client.js b/test/amplitude-client.js index 453b7f80..5b2516eb 100644 --- a/test/amplitude-client.js +++ b/test/amplitude-client.js @@ -3804,4 +3804,34 @@ describe('AmplitudeClient', function () { }); }); }); + + describe('clearStorage', function () { + afterEach(() => { + reset(); + }); + + it('should clear cookies', function () { + amplitude.init(apiKey, null, { storage: constants.STORAGE_COOKIES }); + assert.isNotNull(amplitude._metadataStorage.load()); + assert.equal(amplitude._metadataStorage.storage, constants.STORAGE_COOKIES); + amplitude.clearStorage(); + assert.isNull(amplitude._metadataStorage.load()); + }); + + it('should clear localStorage', function () { + amplitude.init(apiKey, null, { storage: constants.STORAGE_LOCAL }); + assert.isNotNull(amplitude._metadataStorage.load()); + assert.equal(amplitude._metadataStorage.storage, constants.STORAGE_LOCAL); + amplitude.clearStorage(); + assert.isNull(amplitude._metadataStorage.load()); + }); + + it('should clear sessionStorage', function () { + amplitude.init(apiKey, null, { storage: constants.STORAGE_SESSION }); + assert.isNotNull(amplitude._metadataStorage.load()); + assert.equal(amplitude._metadataStorage.storage, constants.STORAGE_SESSION); + amplitude.clearStorage(); + assert.isNull(amplitude._metadataStorage.load()); + }); + }); }); From 3fc50957858dc8a27dc883f8f5c33683a9ac5112 Mon Sep 17 00:00:00 2001 From: John Tran <jptran318@gmail.com> Date: Wed, 26 May 2021 02:00:48 -0700 Subject: [PATCH 3/5] Fix clear storage logic --- src/base-cookie.js | 9 --------- src/metadata-storage.js | 7 ++++++- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/base-cookie.js b/src/base-cookie.js index 45917473..ef6457ee 100644 --- a/src/base-cookie.js +++ b/src/base-cookie.js @@ -92,14 +92,6 @@ const sortByEventTime = (cookies) => { }); }; -/** - * Clears cookie by setting expiration to a past date - * @param {*} name - */ -const clear = (name) => { - document.cookie = `${name}= ; expires = Thu, 01 Jan 1970 00:00:00 GMT'`; -}; - // test that cookies are enabled - navigator.cookiesEnabled yields false positives in IE, need to test directly const areCookiesEnabled = (opts = {}) => { const cookieName = Constants.COOKIE_TEST_PREFIX + base64Id(); @@ -121,7 +113,6 @@ const areCookiesEnabled = (opts = {}) => { export default { set, get, - clear, getAll, getLastEventTime, sortByEventTime, diff --git a/src/metadata-storage.js b/src/metadata-storage.js index 2a19249f..5888738d 100644 --- a/src/metadata-storage.js +++ b/src/metadata-storage.js @@ -174,7 +174,12 @@ class MetadataStorage { let str; if (this.storage === Constants.STORAGE_COOKIES) { str = baseCookie.get(this.getCookieStorageKey() + '='); - baseCookie.clear(this.getCookieStorageKey()); + baseCookie.set(this.getCookieStorageKey(), null, { + domain: this.cookieDomain, + secure: this.secure, + sameSite: this.sameSite, + expirationDays: 0, + }); } if (!str) { str = ampLocalStorage.getItem(this.storageKey); From f6a66379dc5b349541e2a3eff154c29bef859353 Mon Sep 17 00:00:00 2001 From: John Tran <jptran318@gmail.com> Date: Wed, 26 May 2021 02:01:20 -0700 Subject: [PATCH 4/5] Fix public docs --- src/amplitude-client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/amplitude-client.js b/src/amplitude-client.js index aa8a873f..eb2efaa1 100644 --- a/src/amplitude-client.js +++ b/src/amplitude-client.js @@ -522,7 +522,7 @@ AmplitudeClient.prototype._sendEventsIfReady = function _sendEventsIfReady() { }; /** - * Clears any saved metadata storage + * Clears any stored events and metadata. Storage is then re-created on next event sending. * @constructor AmplitudeClient * @public * @return {boolean} True if metadata was cleared, false if none existed From 2ed1174ab9bedc4efa76d4a234ec03773b316c2a Mon Sep 17 00:00:00 2001 From: John Tran <jptran318@gmail.com> Date: Wed, 26 May 2021 02:04:18 -0700 Subject: [PATCH 5/5] Improve tests --- test/amplitude-client.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/amplitude-client.js b/test/amplitude-client.js index 5b2516eb..24dee99d 100644 --- a/test/amplitude-client.js +++ b/test/amplitude-client.js @@ -3814,7 +3814,7 @@ describe('AmplitudeClient', function () { amplitude.init(apiKey, null, { storage: constants.STORAGE_COOKIES }); assert.isNotNull(amplitude._metadataStorage.load()); assert.equal(amplitude._metadataStorage.storage, constants.STORAGE_COOKIES); - amplitude.clearStorage(); + assert.equal(amplitude.clearStorage(), true); assert.isNull(amplitude._metadataStorage.load()); }); @@ -3822,7 +3822,7 @@ describe('AmplitudeClient', function () { amplitude.init(apiKey, null, { storage: constants.STORAGE_LOCAL }); assert.isNotNull(amplitude._metadataStorage.load()); assert.equal(amplitude._metadataStorage.storage, constants.STORAGE_LOCAL); - amplitude.clearStorage(); + assert.equal(amplitude.clearStorage(), true); assert.isNull(amplitude._metadataStorage.load()); }); @@ -3830,7 +3830,7 @@ describe('AmplitudeClient', function () { amplitude.init(apiKey, null, { storage: constants.STORAGE_SESSION }); assert.isNotNull(amplitude._metadataStorage.load()); assert.equal(amplitude._metadataStorage.storage, constants.STORAGE_SESSION); - amplitude.clearStorage(); + assert.equal(amplitude.clearStorage(), true); assert.isNull(amplitude._metadataStorage.load()); }); });