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

PBID-11: Integrate new compound cookie #9

Merged
merged 12 commits into from
May 12, 2020
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
5 changes: 0 additions & 5 deletions integrationExamples/gpt/audigentSegments_example.html
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,6 @@
params: {
// change to Parrable Partner Client ID(s) you received from the Parrable Partners you are using
partner: '30182847-e426-4ff9-b2b5-9ca1324ea09b'
},
storage: {
type: "cookie",
name: "_parrable_eid", // create a cookie with this name
expires: 365 // cookie can last for a year
}
}, {
name: "pubCommonId",
Expand Down
5 changes: 0 additions & 5 deletions integrationExamples/gpt/userId_example.html
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,6 @@
params: {
// change to Parrable Partner Client ID(s) you received from the Parrable Partners you are using
partner: '30182847-e426-4ff9-b2b5-9ca1324ea09b'
},
storage: {
type: "cookie",
name: "_parrable_eid", // create a cookie with this name
expires: 365 // cookie can last for a year
}
}, {
name: "pubCommonId",
Expand Down
125 changes: 114 additions & 11 deletions modules/parrableIdSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,50 @@ import { ajax } from '../src/ajax.js';
import { submodule } from '../src/hook.js';
import { getRefererInfo } from '../src/refererDetection.js';
import { uspDataHandler } from '../src/adapterManager.js';
import { getStorageManager } from '../src/storageManager.js';

const PARRABLE_URL = 'https://h.parrable.com/prebid';
const PARRABLE_COOKIE_NAME = '_parrable_id';
const LEGACY_ID_COOKIE_NAME = '_parrable_eid';
const LEGACY_OPTOUT_COOKIE_NAME = '_parrable_optout';
const ONE_YEAR_MS = 364 * 24 * 60 * 60 * 1000;

const storage = getStorageManager();
const expiredCookieDate = new Date(0).toString();

function getExpirationDate() {
const oneYearFromNow = new Date(utils.timestamp() + ONE_YEAR_MS);
return oneYearFromNow.toGMTString();
}

function deserializeParrableId(parrableIdStr) {
const parrableId = {};
const values = parrableIdStr.split(',');

values.forEach(function(value) {
const pair = value.split(':');
// unpack a value of 1 as true
parrableId[pair[0]] = +pair[1] === 1 ? true : pair[1];
});

return parrableId;
}

function serializeParrableId(parrableId) {
let components = [];

if (parrableId.eid) {
components.push('eid:' + parrableId.eid);
}
if (parrableId.ibaOptout) {
components.push('ibaOptout:1');
}
if (parrableId.ccpaOptout) {
components.push('ccpaOptout:1');
}

return components.join(',');
}

function isValidConfig(configParams) {
if (!configParams) {
Expand All @@ -22,17 +64,62 @@ function isValidConfig(configParams) {
utils.logError('User ID - parrableId submodule requires partner list');
return false;
}
if (configParams.storage) {
utils.logWarn('User ID - parrableId submodule does not require a storage config');
}
return true;
}

function fetchId(configParams, currentStoredId) {
function readCookie() {
const parrableIdStr = storage.getCookie(PARRABLE_COOKIE_NAME);
if (parrableIdStr) {
return deserializeParrableId(decodeURIComponent(parrableIdStr));
}
return undefined;
}

function writeCookie(parrableId) {
const parrableIdStr = encodeURIComponent(serializeParrableId(parrableId));
storage.setCookie(PARRABLE_COOKIE_NAME, parrableIdStr, getExpirationDate(), 'lax');
}

function readLegacyCookies() {
let legacyParrableId = {};
let legacyEid = storage.getCookie(LEGACY_ID_COOKIE_NAME);
if (legacyEid) {
legacyParrableId.eid = legacyEid;
}
let legacyOptout = storage.getCookie(LEGACY_OPTOUT_COOKIE_NAME);
if (legacyOptout === 'true') {
legacyParrableId.ibaOptout = true;
}
return legacyParrableId;
}

function migrateLegacyCookies(parrableId) {
writeCookie(parrableId);
if (parrableId.eid) {
storage.setCookie(LEGACY_ID_COOKIE_NAME, '', expiredCookieDate);
}
if (parrableId.ibaOptout) {
storage.setCookie(LEGACY_OPTOUT_COOKIE_NAME, '', expiredCookieDate);
}
}

function fetchId(configParams) {
if (!isValidConfig(configParams)) return;

let parrableId = readCookie();
if (!parrableId) {
parrableId = readLegacyCookies();
migrateLegacyCookies(parrableId);
}

const refererInfo = getRefererInfo();
const uspString = uspDataHandler.getConsentData();

const data = {
eid: currentStoredId || null,
eid: (parrableId && parrableId.eid) || null,
trackers: configParams.partner.split(','),
url: refererInfo.referer
};
Expand All @@ -53,21 +140,34 @@ function fetchId(configParams, currentStoredId) {

const callback = function (cb) {
const onSuccess = (response) => {
let eid;
let parrableId = {};
if (response) {
try {
let responseObj = JSON.parse(response);
eid = responseObj ? responseObj.eid : undefined;
if (responseObj) {
if (responseObj.ccpaOptout !== true) {
parrableId.eid = responseObj.eid;
} else {
parrableId.ccpaOptout = true;
}
if (responseObj.ibaOptout === true) {
parrableId.ibaOptout = true;
}
writeCookie(responseObj);
}
} catch (error) {
utils.logError(error);
}
}
cb(eid);
cb(parrableId);
};
ajax(PARRABLE_URL, onSuccess, searchParams, options);
};

return { callback };
return {
callback,
id: parrableId
};
};

/** @type {Submodule} */
Expand All @@ -80,22 +180,25 @@ export const parrableIdSubmodule = {
/**
* decode the stored id value for passing to bid requests
* @function
* @param {Object|string} value
* @param {ParrableId} parrableId
* @return {(Object|undefined}
*/
decode(value) {
return (value && typeof value === 'string') ? { 'parrableid': value } : undefined;
decode(parrableId) {
if (parrableId && utils.isPlainObject(parrableId)) {
return { 'parrableid': parrableId.eid };
}
return undefined;
},

/**
* performs action to obtain id and return a value in the callback's response argument
* @function
* @param {SubmoduleParams} [configParams]
* @param {ConsentData} [consentData]
* @returns {function(callback:function)}
* @returns {function(callback:function), id:ParrableId}
*/
getId(configParams, gdprConsentData, currentStoredId) {
return fetchId(configParams, currentStoredId);
return fetchId(configParams);
}
};

Expand Down
4 changes: 0 additions & 4 deletions modules/userId/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -426,10 +426,6 @@ function initSubmodules(submodules, consentData) {
refreshNeeded = storedDate && (Date.now() - storedDate.getTime() > submodule.config.storage.refreshInSeconds * 1000);
}

if (CONSTANTS.SUBMODULES_THAT_ALWAYS_REFRESH_ID[submodule.config.name] === true) {
refreshNeeded = true;
}

if (!storedId || refreshNeeded) {
// No previously saved id. Request one from submodule.
response = submodule.submodule.getId(submodule.config.params, consentData, storedId);
Expand Down
5 changes: 0 additions & 5 deletions modules/userId/userId.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,6 @@ pbjs.setConfig({
params: {
// Replace partner with comma-separated (if more than one) Parrable Partner Client ID(s) for Parrable-aware bid adapters in use
partner: "30182847-e426-4ff9-b2b5-9ca1324ea09b"
},
storage: {
type: 'cookie',
name: '_parrable_eid',
expires: 365
}
}, {
name: 'identityLink',
Expand Down
3 changes: 0 additions & 3 deletions src/constants.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,5 @@
"BID_TARGETING_SET": "targetingSet",
"RENDERED": "rendered",
"BID_REJECTED": "bidRejected"
},
"SUBMODULES_THAT_ALWAYS_REFRESH_ID": {
"parrableId": true
}
}
Loading