Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ID5 UserId module : use userId storage mechanism to store request number #11965

Merged
merged 1 commit into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 14 additions & 93 deletions modules/id5IdSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ import {
isPlainObject,
logError,
logInfo,
logWarn,
safeJSONParse
logWarn
} from '../src/utils.js';
import {fetch} from '../src/ajax.js';
import {submodule} from '../src/hook.js';
import {getRefererInfo} from '../src/refererDetection.js';
import {getStorageManager} from '../src/storageManager.js';
import {uspDataHandler, gppDataHandler} from '../src/adapterManager.js';
import {gppDataHandler, uspDataHandler} from '../src/adapterManager.js';
import {MODULE_TYPE_UID} from '../src/activities/modules.js';
import {GreedyPromise} from '../src/utils/promise.js';
import {loadExternalScript} from '../src/adloader.js';
Expand All @@ -34,19 +33,12 @@ import {loadExternalScript} from '../src/adloader.js';

const MODULE_NAME = 'id5Id';
const GVLID = 131;
const NB_EXP_DAYS = 30;
export const ID5_STORAGE_NAME = 'id5id';
export const ID5_PRIVACY_STORAGE_NAME = `${ID5_STORAGE_NAME}_privacy`;
const LOCAL_STORAGE = 'html5';
const LOG_PREFIX = 'User ID - ID5 submodule: ';
const ID5_API_CONFIG_URL = 'https://id5-sync.com/api/config/prebid';
const ID5_DOMAIN = 'id5-sync.com';
const TRUE_LINK_SOURCE = 'true-link-id5-sync.com';

// order the legacy cookie names in reverse priority order so the last
// cookie in the array is the most preferred to use
const LEGACY_COOKIE_NAMES = ['pbjs-id5id', 'id5id.1st', 'id5id'];

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

/**
Expand Down Expand Up @@ -231,18 +223,18 @@ export const id5IdSubmodule = {
* @param {SubmoduleConfig} config
* @param {ConsentData|undefined} consentData
* @param {Object} cacheIdObj - existing id, if any
* @return {(IdResponse|function(callback:function))} A response object that contains id and/or callback.
* @return {IdResponse} A response object that contains id.
*/
extendId(config, consentData, cacheIdObj) {
if (!hasWriteConsentToLocalStorage(consentData)) {
logInfo(LOG_PREFIX + 'No consent given for ID5 local storage writing, skipping nb increment.');
return cacheIdObj;
}

const partnerId = validateConfig(config) ? config.params.partner : 0;
incrementNb(partnerId);

logInfo(LOG_PREFIX + 'using cached ID', cacheIdObj);
if (cacheIdObj) {
cacheIdObj.nbPage = incrementNb(cacheIdObj)
}
return cacheIdObj;
},
eids: {
Expand Down Expand Up @@ -401,8 +393,8 @@ export class IdFetchFlow {
const params = this.submoduleConfig.params;
const hasGdpr = (this.gdprConsentData && typeof this.gdprConsentData.gdprApplies === 'boolean' && this.gdprConsentData.gdprApplies) ? 1 : 0;
const referer = getRefererInfo();
const signature = (this.cacheIdObj && this.cacheIdObj.signature) ? this.cacheIdObj.signature : getLegacyCookieSignature();
const nbPage = incrementAndResetNb(params.partner);
const signature = this.cacheIdObj ? this.cacheIdObj.signature : undefined;
const nbPage = incrementNb(this.cacheIdObj);
const trueLinkInfo = window.id5Bootstrap ? window.id5Bootstrap.getTrueLinkInfo() : {booted: false};

const data = {
Expand Down Expand Up @@ -456,7 +448,6 @@ export class IdFetchFlow {
#processFetchCallResponse(fetchCallResponse) {
try {
if (fetchCallResponse.privacy) {
storeInLocalStorage(ID5_PRIVACY_STORAGE_NAME, JSON.stringify(fetchCallResponse.privacy), NB_EXP_DAYS);
if (window.id5Bootstrap && window.id5Bootstrap.setPrivacy) {
window.id5Bootstrap.setPrivacy(fetchCallResponse.privacy);
}
Expand Down Expand Up @@ -507,89 +498,19 @@ function validateConfig(config) {
logError(LOG_PREFIX + 'storage required to be set');
return false;
}

// in a future release, we may return false if storage type or name are not set as required
if (config.storage.type !== LOCAL_STORAGE) {
logWarn(LOG_PREFIX + `storage type recommended to be '${LOCAL_STORAGE}'. In a future release this may become a strict requirement`);
}
// in a future release, we may return false if storage type or name are not set as required
if (config.storage.name !== ID5_STORAGE_NAME) {
logWarn(LOG_PREFIX + `storage name recommended to be '${ID5_STORAGE_NAME}'. In a future release this may become a strict requirement`);
logWarn(LOG_PREFIX + `storage name recommended to be '${ID5_STORAGE_NAME}'.`);
}

return true;
}

export function expDaysStr(expDays) {
return (new Date(Date.now() + (1000 * 60 * 60 * 24 * expDays))).toUTCString();
}

export function nbCacheName(partnerId) {
return `${ID5_STORAGE_NAME}_${partnerId}_nb`;
}

export function storeNbInCache(partnerId, nb) {
storeInLocalStorage(nbCacheName(partnerId), nb, NB_EXP_DAYS);
}

export function getNbFromCache(partnerId) {
let cacheNb = getFromLocalStorage(nbCacheName(partnerId));
return (cacheNb) ? parseInt(cacheNb) : 0;
}

function incrementNb(partnerId) {
const nb = (getNbFromCache(partnerId) + 1);
storeNbInCache(partnerId, nb);
return nb;
}

function incrementAndResetNb(partnerId) {
const result = incrementNb(partnerId);
storeNbInCache(partnerId, 0);
return result;
}

function getLegacyCookieSignature() {
let legacyStoredValue;
LEGACY_COOKIE_NAMES.forEach(function (cookie) {
if (storage.getCookie(cookie)) {
legacyStoredValue = safeJSONParse(storage.getCookie(cookie)) || legacyStoredValue;
}
});
return (legacyStoredValue && legacyStoredValue.signature) || '';
}

/**
* This will make sure we check for expiration before accessing local storage
* @param {string} key
*/
export function getFromLocalStorage(key) {
const storedValueExp = storage.getDataFromLocalStorage(`${key}_exp`);
// empty string means no expiration set
if (storedValueExp === '') {
return storage.getDataFromLocalStorage(key);
} else if (storedValueExp) {
if ((new Date(storedValueExp)).getTime() - Date.now() > 0) {
return storage.getDataFromLocalStorage(key);
}
function incrementNb(cachedObj) {
if (cachedObj && cachedObj.nbPage !== undefined) {
return cachedObj.nbPage + 1;
} else {
return 1;
}
// if we got here, then we have an expired item or we didn't set an
// expiration initially somehow, so we need to remove the item from the
// local storage
storage.removeDataFromLocalStorage(key);
return null;
}

/**
* Ensure that we always set an expiration in local storage since
* by default it's not required
* @param {string} key
* @param {any} value
* @param {number} expDays
*/
export function storeInLocalStorage(key, value, expDays) {
storage.setDataInLocalStorage(`${key}_exp`, expDaysStr(expDays));
storage.setDataInLocalStorage(`${key}`, value);
}

/**
Expand Down
Loading