Skip to content
10 changes: 6 additions & 4 deletions src/mp-instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import KitBlocker from './kitBlocking';
import ConfigAPIClient, { IKitConfigs } from './configAPIClient';
import IdentityAPIClient from './identityApiClient';
import { isFunction, parseConfig, valueof } from './utils';
import { LocalStorageVault } from './vault';
import { DisabledVault, LocalStorageVault } from './vault';
import { removeExpiredIdentityCacheDates } from './identity-utils';
import IntegrationCapture from './integrationCapture';
import { IPreInit, processReadyQueue } from './pre-init-utils';
Expand Down Expand Up @@ -1534,9 +1534,11 @@ function createKitBlocker(config, mpInstance) {
}

function createIdentityCache(mpInstance) {
return new LocalStorageVault(`${mpInstance._Store.storageName}-id-cache`, {
logger: mpInstance.Logger,
});
const cacheKey = `${mpInstance._Store.storageName}-id-cache`;
if (mpInstance._Store.getPrivacyFlag('IdentityCache')) {
return new DisabledVault(cacheKey, { logger: mpInstance.Logger });
}
return new LocalStorageVault(cacheKey, { logger: mpInstance.Logger });
}

function runPreConfigFetchInitialization(mpInstance, apiKey, config) {
Expand Down
16 changes: 16 additions & 0 deletions src/vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,20 @@ export class SessionStorageVault<StorableItem> extends BaseVault<StorableItem> {
constructor(storageKey: string, options?: IVaultOptions) {
super(storageKey, window.sessionStorage, options);
}
}

// DisabledVault is used when persistence is disabled by privacy flags.
export class DisabledVault<StorableItem> extends BaseVault<StorableItem> {
constructor(storageKey: string, options?: IVaultOptions) {
super(storageKey, window.localStorage, options);
this.contents = null;
}

public store(_item: StorableItem): void {
this.contents = null;
}

public retrieve(): StorableItem | null {
return this.contents;
}
}
30 changes: 30 additions & 0 deletions test/src/tests-identity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,36 @@ describe('identity', function() {
});
});

describe('privacy flags', function() {
beforeEach(function() {
mParticle._resetForTests(MPConfig);
mParticle.config.flags.cacheIdentity = 'True';
localStorage.clear();
});

describe('#createIdentityCache', function() {
it('should save id cache to local storage when noFunctional is false by default', async () => {
mParticle.init(apiKey, window.mParticle.config);
await waitForCondition(hasIdentifyReturned);
expect(localStorage.getItem('mprtcl-v4_abcdef-id-cache')).to.be.ok;
});

it('should NOT save id cache to local storage when noFunctional is true', async () => {
mParticle.config.launcherOptions = { noFunctional: true };
mParticle.init(apiKey, window.mParticle.config);
await waitForCondition(hasIdentifyReturned);
expect(localStorage.getItem('mprtcl-v4_abcdef-id-cache')).not.to.be.ok;
});

it('should save id cache to local storage when noFunctional is false', async () => {
mParticle.config.launcherOptions = { noFunctional: false };
mParticle.init(apiKey, window.mParticle.config);
await waitForCondition(hasIdentifyReturned);
expect(localStorage.getItem('mprtcl-v4_abcdef-id-cache')).to.be.ok;
});
});
});

// https://go.mparticle.com/work/SQDSDKS-6849
// This test passes with no issue when it is run on its own, but fails when tests-forwarders.js are also ran.
it('should respect consent rules on consent-change', async () => {
Expand Down
74 changes: 73 additions & 1 deletion test/src/vault.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Batch } from '@mparticle/event-models';
import { expect } from 'chai';
import { Dictionary } from '../../src/utils';
import { SessionStorageVault, LocalStorageVault } from '../../src/vault';
import { SessionStorageVault, LocalStorageVault, DisabledVault } from '../../src/vault';

const testObject: Dictionary<Dictionary<string>> = {
foo: { foo: 'bar', buzz: 'bazz' },
Expand Down Expand Up @@ -419,4 +419,76 @@ describe('Vault', () => {
);
});
});

describe('DisabledVault', () => {
afterEach(() => {
window.localStorage.clear();
});

describe('#store', () => {
it('should NOT write to localStorage', () => {
const storageKey = 'test-disabled-store-empty';
const vault = new DisabledVault<string>(storageKey);

vault.store('testString');

expect(vault.contents).to.equal(null);
expect(window.localStorage.getItem(storageKey)).to.equal(null);
});

it('should NOT overwrite existing localStorage value and keep contents null', () => {
const storageKey = 'test-disabled-store-existing';
window.localStorage.setItem(storageKey, 'existingItem');

const vault = new DisabledVault<string>(storageKey);

vault.store('newValue');

expect(vault.contents).to.equal(null);
expect(window.localStorage.getItem(storageKey)).to.equal('existingItem');
});
});

describe('#retrieve', () => {
it('should return null when nothing is stored', () => {
const storageKey = 'test-disabled-retrieve-empty';
const vault = new DisabledVault<string>(storageKey);
const retrievedItem = vault.retrieve();
expect(retrievedItem).to.equal(null);
});

it('should return null even if localStorage has a value', () => {
const storageKey = 'test-disabled-retrieve-existing';
window.localStorage.setItem(storageKey, 'existingItem');

const vault = new DisabledVault<string>(storageKey);
const retrievedItem = vault.retrieve();
expect(retrievedItem).to.equal(null);
expect(window.localStorage.getItem(storageKey)).to.equal('existingItem');
});
});

describe('#purge', () => {
it('should keep contents null when purging', () => {
const storageKey = 'test-disabled-purge-existing';
window.localStorage.setItem(storageKey, 'existing');

const vault = new DisabledVault<string>(storageKey);

vault.purge();

expect(vault.contents).to.equal(null);
expect(window.localStorage.getItem(storageKey)).to.equal(null);
});

it('should keep contents null when purging an empty key', () => {
const storageKey = 'test-disabled-purge-empty';
const vault = new DisabledVault<string>(storageKey);

vault.purge();
expect(vault.contents).to.equal(null);
expect(window.localStorage.getItem(storageKey)).to.equal(null);
});
});
});
});
Loading