Skip to content

Commit

Permalink
33Across User ID Module : support for the recently introduced "multip…
Browse files Browse the repository at this point in the history
…le storage types" feature (#11563)

* Refactoring - break functions that are handling multiple storage types.

* user id: introduce the concept of enabled storage types

* Apply domain override to 33across ID

* First party ID - Support for multiple storage types

* 33Across User ID: Recommend both storage types

* refactor the way enabled storage types are populated
  • Loading branch information
carlosfelix authored Jun 4, 2024
1 parent 402b524 commit 6478666
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 53 deletions.
64 changes: 43 additions & 21 deletions modules/33acrossIdSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { submodule } from '../src/hook.js';
import { uspDataHandler, coppaDataHandler, gppDataHandler } from '../src/adapterManager.js';
import { getStorageManager, STORAGE_TYPE_COOKIES, STORAGE_TYPE_LOCALSTORAGE } from '../src/storageManager.js';
import { MODULE_TYPE_UID } from '../src/activities/modules.js';
import { domainOverrideToRootDomain } from '../libraries/domainOverrideToRootDomain/index.js';

/**
* @typedef {import('../modules/userId/index.js').Submodule} Submodule
Expand All @@ -28,6 +29,10 @@ const STORAGE_FPID_KEY = '33acrossIdFp';

export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME });

export const domainUtils = {
domainOverride: domainOverrideToRootDomain(storage, MODULE_NAME)
};

function calculateResponseObj(response) {
if (!response.succeeded) {
if (response.error == 'Cookied User') {
Expand All @@ -50,7 +55,7 @@ function calculateResponseObj(response) {
};
}

function calculateQueryStringParams(pid, gdprConsentData, storageConfig) {
function calculateQueryStringParams(pid, gdprConsentData, enabledStorageTypes) {
const uspString = uspDataHandler.getConsentData();
const coppaValue = coppaDataHandler.getCoppa();
const gppConsent = gppDataHandler.getConsentData();
Expand Down Expand Up @@ -78,7 +83,7 @@ function calculateQueryStringParams(pid, gdprConsentData, storageConfig) {
params.gdpr_consent = gdprConsentData.consentString;
}

const fp = getStoredValue(STORAGE_FPID_KEY, storageConfig);
const fp = getStoredValue(STORAGE_FPID_KEY, enabledStorageTypes);
if (fp) {
params.fp = encodeURIComponent(fp);
}
Expand All @@ -90,32 +95,42 @@ function deleteFromStorage(key) {
if (storage.cookiesAreEnabled()) {
const expiredDate = new Date(0).toUTCString();

storage.setCookie(key, '', expiredDate, 'Lax');
storage.setCookie(key, '', expiredDate, 'Lax', domainUtils.domainOverride());
}

storage.removeDataFromLocalStorage(key);
}

function storeValue(key, value, storageConfig = {}) {
if (storageConfig.type === STORAGE_TYPE_COOKIES && storage.cookiesAreEnabled()) {
const expirationInMs = 60 * 60 * 24 * 1000 * storageConfig.expires;
const expirationTime = new Date(Date.now() + expirationInMs);
function storeValue(key, value, { enabledStorageTypes, expires }) {
enabledStorageTypes.forEach(storageType => {
if (storageType === STORAGE_TYPE_COOKIES) {
const expirationInMs = 60 * 60 * 24 * 1000 * expires;
const expirationTime = new Date(Date.now() + expirationInMs);

storage.setCookie(key, value, expirationTime.toUTCString(), 'Lax');
} else if (storageConfig.type === STORAGE_TYPE_LOCALSTORAGE) {
storage.setDataInLocalStorage(key, value);
}
storage.setCookie(key, value, expirationTime.toUTCString(), 'Lax', domainUtils.domainOverride());
} else if (storageType === STORAGE_TYPE_LOCALSTORAGE) {
storage.setDataInLocalStorage(key, value);
}
});
}

function getStoredValue(key, storageConfig = {}) {
if (storageConfig.type === STORAGE_TYPE_COOKIES && storage.cookiesAreEnabled()) {
return storage.getCookie(key);
} else if (storageConfig.type === STORAGE_TYPE_LOCALSTORAGE) {
return storage.getDataFromLocalStorage(key);
}
function getStoredValue(key, enabledStorageTypes) {
let storedValue;

enabledStorageTypes.find(storageType => {
if (storageType === STORAGE_TYPE_COOKIES) {
storedValue = storage.getCookie(key);
} else if (storageType === STORAGE_TYPE_LOCALSTORAGE) {
storedValue = storage.getDataFromLocalStorage(key);
}

return !!storedValue;
});

return storedValue;
}

function handleFpId(fpId, storageConfig = {}) {
function handleFpId(fpId, storageConfig) {
fpId
? storeValue(STORAGE_FPID_KEY, fpId, storageConfig)
: deleteFromStorage(STORAGE_FPID_KEY);
Expand Down Expand Up @@ -151,7 +166,7 @@ export const thirthyThreeAcrossIdSubmodule = {
* @param {SubmoduleConfig} [config]
* @returns {IdResponse|undefined}
*/
getId({ params = { }, storage: storageConfig }, gdprConsentData) {
getId({ params = { }, enabledStorageTypes = [], storage: storageConfig }, gdprConsentData) {
if (typeof params.pid !== 'string') {
logError(`${MODULE_NAME}: Submodule requires a partner ID to be defined`);

Expand Down Expand Up @@ -183,7 +198,10 @@ export const thirthyThreeAcrossIdSubmodule = {
}

if (storeFpid) {
handleFpId(responseObj.fp, storageConfig);
handleFpId(responseObj.fp, {
enabledStorageTypes,
expires: storageConfig.expires
});
}

cb(responseObj.envelope);
Expand All @@ -193,10 +211,14 @@ export const thirthyThreeAcrossIdSubmodule = {

cb();
}
}, calculateQueryStringParams(pid, gdprConsentData, storageConfig), { method: 'GET', withCredentials: true });
}, calculateQueryStringParams(pid, gdprConsentData, enabledStorageTypes), {
method: 'GET',
withCredentials: true
});
}
};
},
domainOverride: domainUtils.domainOverride,
eids: {
'33acrossId': {
source: '33across.com',
Expand Down
4 changes: 2 additions & 2 deletions modules/33acrossIdSystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pbjs.setConfig({
name: "33acrossId",
storage: {
name: "33acrossId",
type: "html5",
type: "cookie&html5",
expires: 30,
refreshInSeconds: 8*3600
},
Expand All @@ -40,7 +40,7 @@ The following settings are available for the `storage` property in the `userSync
| Param name | Scope | Type | Description | Example |
| --- | --- | --- | --- | --- |
| name | Required | String| Name of the cookie or HTML5 local storage where the user ID will be stored | `"33acrossId"` |
| type | Required | String | `"html5"` (preferred) or `"cookie"` | `"html5"` |
| type | Required | String | `"cookie&html5"` (preferred) or `"cookie"` or `"html5"` | `"cookie&html5"` |
| expires | Strongly Recommended | Number | How long (in days) the user ID information will be stored. 33Across recommends `30`. | `30` |
| refreshInSeconds | Strongly Recommended | Number | The interval (in seconds) for refreshing the user ID. 33Across recommends no more than 8 hours between refreshes. | `8*3600` |

Expand Down
Loading

0 comments on commit 6478666

Please sign in to comment.