From 3223f242b02052762161d865d4f2ce9f3d3377c7 Mon Sep 17 00:00:00 2001 From: NicoZelaya Date: Fri, 25 Feb 2022 12:50:16 -0300 Subject: [PATCH 1/5] Modif yMySegments keys for localstorage --- src/storage/KeysLocalStorage.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/storage/KeysLocalStorage.js b/src/storage/KeysLocalStorage.js index 1c9a044f6..f6c0e0829 100644 --- a/src/storage/KeysLocalStorage.js +++ b/src/storage/KeysLocalStorage.js @@ -10,11 +10,11 @@ class KeyBuilderForLocalStorage extends KeyBuilder { } buildSegmentNameKey(segmentName) { - return `${matching(this.settings.core.key)}.${this.settings.storage.prefix}.segment.${segmentName}`; + return `${this.settings.storage.prefix}.${matching(this.settings.core.key)}.segment.${segmentName}`; } extractSegmentName(builtSegmentKeyName) { - const prefix = `${matching(this.settings.core.key)}.${this.settings.storage.prefix}.segment.`; + const prefix = `${this.settings.storage.prefix}.${matching(this.settings.core.key)}.segment.`; if (startsWith(builtSegmentKeyName, prefix)) return builtSegmentKeyName.substr(prefix.length); @@ -35,6 +35,18 @@ class KeyBuilderForLocalStorage extends KeyBuilder { buildSplitsFilterQueryKey() { return `${this.settings.storage.prefix}.splits.filterQuery`; } + + // @BREAKING: The key used to start with the matching keyh instead of the prefix, this was changed on version 10.17.3 + buildOldSegmentNameKey(segmentName) { + return `${matching(this.settings.core.key)}.${this.settings.storage.prefix}.segment.${segmentName}`; + } + // @BREAKING: The key used to start with the matching keyh instead of the prefix, this was changed on version 10.17.3 + extractOldSegmentKey(maybeOldKey) { + const prefix = `${matching(this.settings.core.key)}.${this.settings.storage.prefix}.segment.`; + + if (startsWith(maybeOldKey, prefix)) + return maybeOldKey.substr(prefix.length); + } } export default KeyBuilderForLocalStorage; From 5a1206040951da7326abe4fd5be9f00d4cd56601 Mon Sep 17 00:00:00 2001 From: NicoZelaya Date: Fri, 25 Feb 2022 12:50:28 -0300 Subject: [PATCH 2/5] Update MySegments cache for LS --- .../SegmentCache/InLocalStorage/index.js | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/storage/SegmentCache/InLocalStorage/index.js b/src/storage/SegmentCache/InLocalStorage/index.js index 526588dbd..30f0768f2 100644 --- a/src/storage/SegmentCache/InLocalStorage/index.js +++ b/src/storage/SegmentCache/InLocalStorage/index.js @@ -46,9 +46,25 @@ class SegmentCacheInLocalStorage { // Scan current values from localStorage const storedSegmentNames = Object.keys(localStorage).reduce((accum, key) => { - const segmentName = this.keys.extractSegmentName(key); - - if (segmentName) accum.push(segmentName); + let segmentName = this.keys.extractSegmentName(key); + + if (segmentName) { + accum.push(segmentName); + } else { + // @BREAKING: This is only to clean up "old" keys. Remove this whole else code block. + segmentName = this.keys.extractOldSegmentKey(key); + + if (segmentName) { // this was an old segment key, let's clean up. + const newSegmentKey = this.keys.buildSegmentNameKey(segmentName); + // If the new format key is not there, create it. + if (!localStorage.getItem(newSegmentKey) && segmentNames.indexOf(segmentName) > -1) { + localStorage.setItem(newSegmentKey, DEFINED); + // we are migrating a segment, let's track it. + accum.push(segmentName); + } + localStorage.removeItem(key); // we migrated the current key, let's delete it. + } + } return accum; }, []); From 6bef1e37f9f9b85276007c3c8e16ffdbf55b1dd8 Mon Sep 17 00:00:00 2001 From: NicoZelaya Date: Fri, 25 Feb 2022 12:50:43 -0300 Subject: [PATCH 3/5] Unit testing the backwards compatibility for MyS LS keys --- .../InLocalStorage/browser.spec.js | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/storage/__tests__/SegmentCache/InLocalStorage/browser.spec.js b/src/storage/__tests__/SegmentCache/InLocalStorage/browser.spec.js index 9bb772504..b4d3074ec 100644 --- a/src/storage/__tests__/SegmentCache/InLocalStorage/browser.spec.js +++ b/src/storage/__tests__/SegmentCache/InLocalStorage/browser.spec.js @@ -19,5 +19,41 @@ tape('SEGMENT CACHE / in LocalStorage', assert => { assert.ok( cache.isInSegment('mocked-segment') === false ); + cache.flush(); + assert.end(); +}); + +// @BREAKING: REMOVE when removing this backwards compatibility. +tape('SEGMENT CACHE / in LocalStorage migration for mysegments keys', assert => { + + const keys = new KeyBuilder(SettingsFactory({ + core: { key: 'test_nico' }, + storage:{ prefix: 'LS_BC_test'} + })); + const cache = new SegmentCacheInLocalStorage(keys); + const oldKey1 = 'test_nico.LS_BC_test.SPLITIO.segment.segment1'; + const oldKey2 = 'test_nico.LS_BC_test.SPLITIO.segment.segment2'; + const newKey1 = keys.buildSegmentNameKey('segment1'); + const newKey2 = keys.buildSegmentNameKey('segment2'); + + cache.flush(); // cleanup before starting. + + // Not adding a full suite for LS keys now, testing here + assert.equal(oldKey1, keys.buildOldSegmentNameKey('segment1')); + assert.equal('segment1', keys.extractOldSegmentKey(oldKey1)); + + // add two segments, one we don't want to send on reset, should only be cleared, other one will be migrated. + localStorage.setItem(oldKey1, 1); + localStorage.setItem(oldKey2, 1); + assert.equal(localStorage.getItem(newKey1), null, 'control assertion'); + + cache.resetSegments(['segment1']); + + assert.equal(localStorage.getItem(newKey1), 1, 'The segment key for segment1, as is part of the new list, should be migrated.'); + assert.equal(localStorage.getItem(newKey2), null, 'The segment key for segment2 should not be migrated.'); + assert.equal(localStorage.getItem(oldKey1), null, 'Old keys are removed.'); + assert.equal(localStorage.getItem(oldKey2), null, 'Old keys are removed.'); + + cache.flush(); assert.end(); }); \ No newline at end of file From d598f78d980f556b03e97973532072fe75f16d37 Mon Sep 17 00:00:00 2001 From: NicoZelaya Date: Fri, 25 Feb 2022 12:51:50 -0300 Subject: [PATCH 4/5] version and changes --- CHANGES.txt | 3 +++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 17f636b47..3dbf51534 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,6 @@ +10.17.3 (XXX XX, 2022) +- Updated format for MySegments keys in LocalStorage, keeping backwards compatibility. + 10.17.2 (January 31, 2022) - Updated some dependencies for vulnerability fixes. - Bugfixing - Fixed internal handling of Fetch API promise rejection, to avoid unhandled exceptions on some Web browsers (issue https://github.com/splitio/javascript-client/issues/621) diff --git a/package-lock.json b/package-lock.json index b06dda9be..8c0a05058 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.17.2", + "version": "10.17.3-rc1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 9192a6dc9..74ea86f98 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.17.2", + "version": "10.17.3-rc1", "description": "Split SDK", "files": [ "README.md", From 4d8f6bb9329b237e339818a2070b1f2b18cdb27d Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 25 Feb 2022 14:26:25 -0300 Subject: [PATCH 5/5] added try-catch to localstorage calls and some code formatting --- CHANGES.txt | 2 +- package-lock.json | 2 +- package.json | 2 +- src/storage/KeysLocalStorage.js | 4 ++-- .../SegmentCache/InLocalStorage/index.js | 18 +++++++++++------- .../InLocalStorage/browser.spec.js | 6 +++--- src/utils/settings/index.js | 2 +- 7 files changed, 20 insertions(+), 16 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 3dbf51534..5657c17ec 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,5 @@ 10.17.3 (XXX XX, 2022) -- Updated format for MySegments keys in LocalStorage, keeping backwards compatibility. + - Updated format for MySegments keys in LocalStorage, keeping backwards compatibility. 10.17.2 (January 31, 2022) - Updated some dependencies for vulnerability fixes. diff --git a/package-lock.json b/package-lock.json index 8c0a05058..487c28124 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.17.3-rc1", + "version": "10.17.3-rc.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 74ea86f98..3c7272270 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.17.3-rc1", + "version": "10.17.3-rc.4", "description": "Split SDK", "files": [ "README.md", diff --git a/src/storage/KeysLocalStorage.js b/src/storage/KeysLocalStorage.js index f6c0e0829..1e59cec66 100644 --- a/src/storage/KeysLocalStorage.js +++ b/src/storage/KeysLocalStorage.js @@ -36,11 +36,11 @@ class KeyBuilderForLocalStorage extends KeyBuilder { return `${this.settings.storage.prefix}.splits.filterQuery`; } - // @BREAKING: The key used to start with the matching keyh instead of the prefix, this was changed on version 10.17.3 + // @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3 buildOldSegmentNameKey(segmentName) { return `${matching(this.settings.core.key)}.${this.settings.storage.prefix}.segment.${segmentName}`; } - // @BREAKING: The key used to start with the matching keyh instead of the prefix, this was changed on version 10.17.3 + // @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3 extractOldSegmentKey(maybeOldKey) { const prefix = `${matching(this.settings.core.key)}.${this.settings.storage.prefix}.segment.`; diff --git a/src/storage/SegmentCache/InLocalStorage/index.js b/src/storage/SegmentCache/InLocalStorage/index.js index 30f0768f2..82b2e60b9 100644 --- a/src/storage/SegmentCache/InLocalStorage/index.js +++ b/src/storage/SegmentCache/InLocalStorage/index.js @@ -56,13 +56,17 @@ class SegmentCacheInLocalStorage { if (segmentName) { // this was an old segment key, let's clean up. const newSegmentKey = this.keys.buildSegmentNameKey(segmentName); - // If the new format key is not there, create it. - if (!localStorage.getItem(newSegmentKey) && segmentNames.indexOf(segmentName) > -1) { - localStorage.setItem(newSegmentKey, DEFINED); - // we are migrating a segment, let's track it. - accum.push(segmentName); + try { + // If the new format key is not there, create it. + if (!localStorage.getItem(newSegmentKey) && segmentNames.indexOf(segmentName) > -1) { + localStorage.setItem(newSegmentKey, DEFINED); + // we are migrating a segment, let's track it. + accum.push(segmentName); + } + localStorage.removeItem(key); // we migrated the current key, let's delete it. + } catch (e) { + log.error(e); } - localStorage.removeItem(key); // we migrated the current key, let's delete it. } } @@ -81,7 +85,7 @@ class SegmentCacheInLocalStorage { segmentNames.forEach(segmentName => this.addToSegment(segmentName)); } else { // Slowest path => we need to find at least 1 difference because - for(index = 0; index < segmentNames.length && storedSegmentNames.indexOf(segmentNames[index]) !== -1; index++) { + for (index = 0; index < segmentNames.length && storedSegmentNames.indexOf(segmentNames[index]) !== -1; index++) { // TODO: why empty statement? } diff --git a/src/storage/__tests__/SegmentCache/InLocalStorage/browser.spec.js b/src/storage/__tests__/SegmentCache/InLocalStorage/browser.spec.js index b4d3074ec..63c61d8bc 100644 --- a/src/storage/__tests__/SegmentCache/InLocalStorage/browser.spec.js +++ b/src/storage/__tests__/SegmentCache/InLocalStorage/browser.spec.js @@ -26,7 +26,7 @@ tape('SEGMENT CACHE / in LocalStorage', assert => { // @BREAKING: REMOVE when removing this backwards compatibility. tape('SEGMENT CACHE / in LocalStorage migration for mysegments keys', assert => { - const keys = new KeyBuilder(SettingsFactory({ + const keys = new KeyBuilder(SettingsFactory({ core: { key: 'test_nico' }, storage:{ prefix: 'LS_BC_test'} })); @@ -41,7 +41,7 @@ tape('SEGMENT CACHE / in LocalStorage migration for mysegments keys', assert => // Not adding a full suite for LS keys now, testing here assert.equal(oldKey1, keys.buildOldSegmentNameKey('segment1')); assert.equal('segment1', keys.extractOldSegmentKey(oldKey1)); - + // add two segments, one we don't want to send on reset, should only be cleared, other one will be migrated. localStorage.setItem(oldKey1, 1); localStorage.setItem(oldKey2, 1); @@ -49,7 +49,7 @@ tape('SEGMENT CACHE / in LocalStorage migration for mysegments keys', assert => cache.resetSegments(['segment1']); - assert.equal(localStorage.getItem(newKey1), 1, 'The segment key for segment1, as is part of the new list, should be migrated.'); + assert.equal(localStorage.getItem(newKey1), '1', 'The segment key for segment1, as is part of the new list, should be migrated.'); assert.equal(localStorage.getItem(newKey2), null, 'The segment key for segment2 should not be migrated.'); assert.equal(localStorage.getItem(oldKey1), null, 'Old keys are removed.'); assert.equal(localStorage.getItem(oldKey2), null, 'Old keys are removed.'); diff --git a/src/utils/settings/index.js b/src/utils/settings/index.js index ea1507169..b43239cc2 100644 --- a/src/utils/settings/index.js +++ b/src/utils/settings/index.js @@ -27,7 +27,7 @@ import { API } from '../../utils/logger'; import { STANDALONE_MODE, STORAGE_MEMORY, CONSUMER_MODE, OPTIMIZED } from '../../utils/constants'; import validImpressionsMode from './impressionsMode'; -const version = '10.17.2'; +const version = '10.17.3-rc.4'; const eventsEndpointMatcher = /^\/(testImpressions|metrics|events)/; const authEndpointMatcher = /^\/v2\/auth/; const streamingEndpointMatcher = /^\/(sse|event-stream)/;