From 98835fa1014d51e5530b2676365011ef778ee13f Mon Sep 17 00:00:00 2001 From: Ian Flournoy Date: Tue, 5 May 2020 15:29:34 -0400 Subject: [PATCH 01/10] PBID-11: Read new Parrable compound cookie _parrable_id Migrating from legacy _parrable_eid cookie. The new cookie contains ibaOptout and ccpaOptout status fields --- modules/parrableIdSystem.js | 73 +++++++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 7 deletions(-) diff --git a/modules/parrableIdSystem.js b/modules/parrableIdSystem.js index ba5fae81952..9f018aaab03 100644 --- a/modules/parrableIdSystem.js +++ b/modules/parrableIdSystem.js @@ -10,8 +10,40 @@ 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 LEGACY_COOKIE_NAME = '_parrable_eid'; + +const storage = getStorageManager(); +const cookieExpireDate = new Date(0).toString(); + +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 str = ''; + if (parrableId.eid) { + str += 'eid:' + parrableId.eid; + } + if (parrableId.ibaOptout) { + str += ',ibaOptout:1'; + } + if (parrableId.ccpaOptout) { + str += ',ccpaOptout:1'; + } + return str; +} function isValidConfig(configParams) { if (!configParams) { @@ -25,14 +57,25 @@ function isValidConfig(configParams) { return true; } -function fetchId(configParams, currentStoredId) { +function readLegacyEid() { + legacyEid = storage.getCookie(LEGACY_COOKIE_NAME); + if (legacyEid) { + storage.setCookie(LEGACY_COOKIE_NAME, '', cookieExpireDate); + return legacyEid; + } + return undefined; +} + +function fetchId(configParams, parrableIdStr) { if (!isValidConfig(configParams)) return; + const parrableId = deserializeParrableId(parrableIdStr); + const legacyEid = readLegacyEid(); const refererInfo = getRefererInfo(); const uspString = uspDataHandler.getConsentData(); const data = { - eid: currentStoredId || null, + eid: (parrableId && parrableId.eid) || legacyEid || null, trackers: configParams.partner.split(','), url: refererInfo.referer }; @@ -53,21 +96,33 @@ function fetchId(configParams, currentStoredId) { const callback = function (cb) { const onSuccess = (response) => { - let eid; + let parrableId = {}; if (response) { try { let responseObj = JSON.parse(response); + if (responseObj) { + parrableId = { + eid: responseObj.eid, + ibaOptout: responseObj.ibaOptout, + ccpaOptout: responseObj.ccpaOptout + }; + } eid = responseObj ? responseObj.eid : undefined; } catch (error) { utils.logError(error); } } - cb(eid); + cb(serializeParrableId(parrableId)); }; ajax(PARRABLE_URL, onSuccess, searchParams, options); }; - return { callback }; + // provide the legacyStoredId so it gets used in auction on the first + // impression where the legacy cookie is migrated to the new cookie + return { + callback, + id: serializeParrableId({ eid: legacyStoredId }) + }; }; /** @type {Submodule} */ @@ -80,11 +135,15 @@ export const parrableIdSubmodule = { /** * decode the stored id value for passing to bid requests * @function - * @param {Object|string} value + * @param {string} value * @return {(Object|undefined} */ decode(value) { - return (value && typeof value === 'string') ? { 'parrableid': value } : undefined; + if (value && utils.isStr(value)) { + const idObject = deserializeParrableId(value); + return { 'parrableId': idObject }; + } + return undefined; }, /** From e88c929061e9550cf5b3dd2fa489aad020c6960b Mon Sep 17 00:00:00 2001 From: Ian Flournoy Date: Thu, 7 May 2020 13:53:35 -0400 Subject: [PATCH 02/10] PBID-11: Integrate Parrable compound cookie, consolidating old cookies --- modules/parrableIdSystem.js | 92 +++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 25 deletions(-) diff --git a/modules/parrableIdSystem.js b/modules/parrableIdSystem.js index 9f018aaab03..3806ca18ef5 100644 --- a/modules/parrableIdSystem.js +++ b/modules/parrableIdSystem.js @@ -13,10 +13,18 @@ import { uspDataHandler } from '../src/adapterManager.js'; import { getStorageManager } from '../src/storageManager.js'; const PARRABLE_URL = 'https://h.parrable.com/prebid'; -const LEGACY_COOKIE_NAME = '_parrable_eid'; +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 cookieExpireDate = new Date(0).toString(); +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 = {}; @@ -54,28 +62,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 readLegacyEid() { - legacyEid = storage.getCookie(LEGACY_COOKIE_NAME); - if (legacyEid) { - storage.setCookie(LEGACY_COOKIE_NAME, '', cookieExpireDate); - return legacyEid; +function readCookie() { + const parrableIdStr = storage.getCookie(PARRABLE_COOKIE_NAME); + if (parrableIdStr) { + return deserializeParrableId(decodeURIComponent(parrableIdStr)); } return undefined; } -function fetchId(configParams, parrableIdStr) { +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) { + legacyParrableId.ibaOptout = legacyOptout; + } + 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; - const parrableId = deserializeParrableId(parrableIdStr); - const legacyEid = readLegacyEid(); + let parrableId = readCookie(); + if (!parrableId) { + parrableId = readLegacyCookies(); + migrateLegacyCookies(parrableId); + } + const refererInfo = getRefererInfo(); const uspString = uspDataHandler.getConsentData(); const data = { - eid: (parrableId && parrableId.eid) || legacyEid || null, + eid: (parrableId && parrableId.eid) || null, trackers: configParams.partner.split(','), url: refererInfo.referer }; @@ -101,27 +143,28 @@ function fetchId(configParams, parrableIdStr) { try { let responseObj = JSON.parse(response); if (responseObj) { - parrableId = { - eid: responseObj.eid, - ibaOptout: responseObj.ibaOptout, - ccpaOptout: responseObj.ccpaOptout - }; + if (responseObj.ccpaOptout !== true) { + parrableId.eid = responseObj.eid; + } else { + parrableId.ccpaOptout = true; + } + if (responseObj.ibaOptout === true) { + parrableId.ibaOptout = true; + } + writeCookie(responseObj); } - eid = responseObj ? responseObj.eid : undefined; } catch (error) { utils.logError(error); } } - cb(serializeParrableId(parrableId)); + cb(parrableId); }; ajax(PARRABLE_URL, onSuccess, searchParams, options); }; - // provide the legacyStoredId so it gets used in auction on the first - // impression where the legacy cookie is migrated to the new cookie return { callback, - id: serializeParrableId({ eid: legacyStoredId }) + id: parrableId }; }; @@ -139,9 +182,8 @@ export const parrableIdSubmodule = { * @return {(Object|undefined} */ decode(value) { - if (value && utils.isStr(value)) { - const idObject = deserializeParrableId(value); - return { 'parrableId': idObject }; + if (value && utils.isPlainObject(value)) { + return { 'parrableid': value.eid }; } return undefined; }, @@ -154,7 +196,7 @@ export const parrableIdSubmodule = { * @returns {function(callback:function)} */ getId(configParams, gdprConsentData, currentStoredId) { - return fetchId(configParams, currentStoredId); + return fetchId(configParams); } }; From 1286adc56bf2380cef7b2234a97b0dd655a83348 Mon Sep 17 00:00:00 2001 From: Ian Flournoy Date: Thu, 7 May 2020 13:54:13 -0400 Subject: [PATCH 03/10] PBID-11: Update parrableIdSystem requestBids hook test to support compound cookie value --- test/spec/modules/parrableIdSystem_spec.js | 59 ++++++++++------------ 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/test/spec/modules/parrableIdSystem_spec.js b/test/spec/modules/parrableIdSystem_spec.js index d0bd75a9b2d..02078581165 100644 --- a/test/spec/modules/parrableIdSystem_spec.js +++ b/test/spec/modules/parrableIdSystem_spec.js @@ -11,45 +11,41 @@ import { server } from 'test/mocks/xhr'; const storage = newStorageManager(); const EXPIRED_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:01 GMT'; -const P_COOKIE_NAME = '_parrable_eid'; +const P_COOKIE_NAME = '_parrable_id'; const P_COOKIE_EID = '01.1563917337.test-eid'; const P_XHR_EID = '01.1588030911.test-new-eid' const P_CONFIG_MOCK = { name: 'parrableId', params: { partner: 'parrable_test_partner_123,parrable_test_partner_456' - }, - storage: { - name: '_parrable_eid', - type: 'cookie', - expires: 364 } }; -describe('Parrable ID System', function() { - function getConfigMock() { - return { - userSync: { - syncDelay: 0, - userIds: [P_CONFIG_MOCK] - } +function getConfigMock() { + return { + userSync: { + syncDelay: 0, + userIds: [P_CONFIG_MOCK] } } +} + +function getAdUnitMock(code = 'adUnit-code') { + return { + code, + mediaTypes: {banner: {}, native: {}}, + sizes: [ + [300, 200], + [300, 600] + ], + bids: [{ + bidder: 'sampleBidder', + params: { placementId: 'banner-only-bidder' } + }] + }; +} - function getAdUnitMock(code = 'adUnit-code') { - return { - code, - mediaTypes: {banner: {}, native: {}}, - sizes: [ - [300, 200], - [300, 600] - ], - bids: [{ - bidder: 'sampleBidder', - params: { placementId: 'banner-only-bidder' } - }] - }; - } +describe('Parrable ID System', function() { describe('parrableIdSystem.getId()', function() { let callbackSpy = sinon.spy(); @@ -108,7 +104,8 @@ describe('Parrable ID System', function() { }); }); - describe('Parrable ID in Bid Request', function() { + describe('userId requestBids hook', function() { + const parrableEid = '01.234.test-eid'; let adUnits; beforeEach(function() { @@ -116,7 +113,7 @@ describe('Parrable ID System', function() { // simulate existing browser local storage values storage.setCookie( P_COOKIE_NAME, - P_COOKIE_EID, + encodeURIComponent('eid:' + parrableEid), (new Date(Date.now() + 5000).toUTCString()) ); setSubmoduleRegistry([parrableIdSubmodule]); @@ -128,12 +125,12 @@ describe('Parrable ID System', function() { storage.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE); }); - it('provides the parrableid in the bid request', function(done) { + it('when a stored Parrable ID exists it is added to bids', function(done) { requestBidsHook(function() { adUnits.forEach(unit => { unit.bids.forEach(bid => { expect(bid).to.have.deep.nested.property('userId.parrableid'); - expect(bid.userId.parrableid).to.equal(P_COOKIE_EID); + expect(bid.userId.parrableid).to.equal(parrableEid); }); }); done(); From 2be1fb36c4a66a4615353c19d1912fde89723232 Mon Sep 17 00:00:00 2001 From: Ian Flournoy Date: Thu, 7 May 2020 14:20:52 -0400 Subject: [PATCH 04/10] PBID-11: Small refactor to parrableIdSystem spec to support compound cookie --- test/spec/modules/parrableIdSystem_spec.js | 84 +++++++++++++++------- 1 file changed, 57 insertions(+), 27 deletions(-) diff --git a/test/spec/modules/parrableIdSystem_spec.js b/test/spec/modules/parrableIdSystem_spec.js index 02078581165..0c0dd9f9d0f 100644 --- a/test/spec/modules/parrableIdSystem_spec.js +++ b/test/spec/modules/parrableIdSystem_spec.js @@ -45,37 +45,61 @@ function getAdUnitMock(code = 'adUnit-code') { }; } -describe('Parrable ID System', function() { +function serializeParrableId(parrableId) { + let str = ''; + if (parrableId.eid) { + str += 'eid:' + parrableId.eid; + } + if (parrableId.ibaOptout) { + str += ',ibaOptout:1'; + } + if (parrableId.ccpaOptout) { + str += ',ccpaOptout:1'; + } + return str; +} - describe('parrableIdSystem.getId()', function() { +function writeParrableCookie(parrableId) { + let cookieValue = encodeURIComponent(serializeParrableId(parrableId)); + storage.setCookie( + P_COOKIE_NAME, + cookieValue, + (new Date(Date.now() + 5000).toUTCString()), + 'lax' + ); +} + +function removeParrableCookie() { + storage.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE); +} + +describe('Parrable ID System', function() { + describe('parrableIdSystem.getId() callback', function() { let callbackSpy = sinon.spy(); beforeEach(function() { callbackSpy.resetHistory(); + writeParrableCookie({ eid: P_COOKIE_EID }); }); - it('returns a callback used to refresh the ID', function() { - let getIdResponse = parrableIdSubmodule.getId( - P_CONFIG_MOCK.params, - null, - P_COOKIE_EID - ); - expect(getIdResponse.callback).to.be.a('function'); - }); + afterEach(function() { + removeParrableCookie(); + }) - it('callback creates xhr to Parrable that synchronizes the ID', function() { - let getIdCallback = parrableIdSubmodule.getId( + it('creates xhr to Parrable that synchronizes the ID', function() { + let getIdResult = parrableIdSubmodule.getId( P_CONFIG_MOCK.params, null, - P_COOKIE_EID - ).callback; + null + ); - getIdCallback(callbackSpy); + getIdResult.callback(callbackSpy); let request = server.requests[0]; let queryParams = utils.parseQS(request.url.split('?')[1]); let data = JSON.parse(atob(queryParams.data)); + expect(getIdResult.callback).to.be.a('function'); expect(request.url).to.contain('h.parrable.com/prebid'); expect(queryParams).to.not.have.property('us_privacy'); expect(data).to.deep.equal({ @@ -89,40 +113,46 @@ describe('Parrable ID System', function() { JSON.stringify({ eid: P_XHR_EID }) ); - expect(callbackSpy.calledWith(P_XHR_EID)).to.be.true; + expect(callbackSpy.lastCall.lastArg).to.deep.equal({ + eid: P_XHR_EID + }); }); - it('passes the uspString to Parrable', function() { + it('xhr passes the uspString to Parrable', function() { let uspString = '1YNN'; uspDataHandler.setConsentData(uspString); parrableIdSubmodule.getId( P_CONFIG_MOCK.params, null, - P_COOKIE_EID + null ).callback(callbackSpy); + uspDataHandler.setConsentData(null); expect(server.requests[0].url).to.contain('us_privacy=' + uspString); }); }); + describe('parrableIdSystem.getId() id', function() { + it('provides the stored Parrable values if a cookie exists'); + it('migrates legacy cookies to new compound cookie format'); + }); + + describe('parrableIdSystem.decode()', function() { + it('provides the Parrable ID (EID) from a stored object'); + }); + describe('userId requestBids hook', function() { - const parrableEid = '01.234.test-eid'; let adUnits; beforeEach(function() { adUnits = [getAdUnitMock()]; - // simulate existing browser local storage values - storage.setCookie( - P_COOKIE_NAME, - encodeURIComponent('eid:' + parrableEid), - (new Date(Date.now() + 5000).toUTCString()) - ); + writeParrableCookie({ eid: P_COOKIE_EID }); setSubmoduleRegistry([parrableIdSubmodule]); init(config); config.setConfig(getConfigMock()); }); afterEach(function() { - storage.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE); + removeParrableCookie(); }); it('when a stored Parrable ID exists it is added to bids', function(done) { @@ -130,7 +160,7 @@ describe('Parrable ID System', function() { adUnits.forEach(unit => { unit.bids.forEach(bid => { expect(bid).to.have.deep.nested.property('userId.parrableid'); - expect(bid.userId.parrableid).to.equal(parrableEid); + expect(bid.userId.parrableid).to.equal(P_COOKIE_EID); }); }); done(); From a9d67ee76b9071aed88eda0c92e500c8e1130b32 Mon Sep 17 00:00:00 2001 From: Ian Flournoy Date: Thu, 7 May 2020 14:42:45 -0400 Subject: [PATCH 05/10] PBID-11: Handle legacy ibaOptout as truthy value when migrating to compound cookie --- modules/parrableIdSystem.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/parrableIdSystem.js b/modules/parrableIdSystem.js index 3806ca18ef5..c38132f8f07 100644 --- a/modules/parrableIdSystem.js +++ b/modules/parrableIdSystem.js @@ -88,8 +88,8 @@ function readLegacyCookies() { legacyParrableId.eid = legacyEid; } let legacyOptout = storage.getCookie(LEGACY_OPTOUT_COOKIE_NAME); - if (legacyOptout) { - legacyParrableId.ibaOptout = legacyOptout; + if (legacyOptout === 'true') { + legacyParrableId.ibaOptout = true; } return legacyParrableId; } From b71f7fd602da5d66ae60a8e4a8da75f7897cda7d Mon Sep 17 00:00:00 2001 From: Ian Flournoy Date: Thu, 7 May 2020 14:43:02 -0400 Subject: [PATCH 06/10] PBID-11: Add parrableIdSystem spec tests covering migration of legacy cookies --- test/spec/modules/parrableIdSystem_spec.js | 55 ++++++++++++++++++---- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/test/spec/modules/parrableIdSystem_spec.js b/test/spec/modules/parrableIdSystem_spec.js index 0c0dd9f9d0f..646f2c952f6 100644 --- a/test/spec/modules/parrableIdSystem_spec.js +++ b/test/spec/modules/parrableIdSystem_spec.js @@ -87,11 +87,7 @@ describe('Parrable ID System', function() { }) it('creates xhr to Parrable that synchronizes the ID', function() { - let getIdResult = parrableIdSubmodule.getId( - P_CONFIG_MOCK.params, - null, - null - ); + let getIdResult = parrableIdSubmodule.getId(P_CONFIG_MOCK.params); getIdResult.callback(callbackSpy); @@ -116,6 +112,10 @@ describe('Parrable ID System', function() { expect(callbackSpy.lastCall.lastArg).to.deep.equal({ eid: P_XHR_EID }); + + expect(storage.getCookie(P_COOKIE_NAME)).to.equal( + encodeURIComponent('eid:' + P_XHR_EID) + ); }); it('xhr passes the uspString to Parrable', function() { @@ -132,12 +132,51 @@ describe('Parrable ID System', function() { }); describe('parrableIdSystem.getId() id', function() { - it('provides the stored Parrable values if a cookie exists'); - it('migrates legacy cookies to new compound cookie format'); + it('provides the stored Parrable values if a cookie exists', function() { + writeParrableCookie({ eid: P_COOKIE_EID }); + let getIdResult = parrableIdSubmodule.getId(P_CONFIG_MOCK.params); + removeParrableCookie(); + + expect(getIdResult.id).to.deep.equal({ + eid: P_COOKIE_EID + }); + }); + + it('provides the stored legacy Parrable ID values if cookies exist', function() { + let oldEid = '01.111.old-eid'; + let oldEidCookieName = '_parrable_eid'; + let oldOptoutCookieName = '_parrable_optout'; + + storage.setCookie(oldEidCookieName, oldEid); + storage.setCookie(oldOptoutCookieName, 'true'); + + let getIdResult = parrableIdSubmodule.getId(P_CONFIG_MOCK.params); + expect(getIdResult.id).to.deep.equal({ + eid: oldEid, + ibaOptout: true + }); + + // The ID system is expected to migrate old cookies to the new format + expect(storage.getCookie(P_COOKIE_NAME)).to.equal( + encodeURIComponent('eid:' + oldEid + ',ibaOptout:1') + ); + expect(storage.getCookie(oldEidCookieName)).to.equal(null); + expect(storage.getCookie(oldOptoutCookieName)).to.equal(null); + }); }); describe('parrableIdSystem.decode()', function() { - it('provides the Parrable ID (EID) from a stored object'); + it('provides the Parrable ID (EID) from a stored object', function() { + let eid = '01.123.4567890'; + let parrableId = { + eid, + ccpaOptout: true + }; + + expect(parrableIdSubmodule.decode(parrableId)).to.deep.equal({ + parrableid: eid + }); + }); }); describe('userId requestBids hook', function() { From 742e3d9d9b52a561f1008caf62540cfce737acce Mon Sep 17 00:00:00 2001 From: Ian Flournoy Date: Thu, 7 May 2020 14:46:02 -0400 Subject: [PATCH 07/10] PBID-11: Remove storage documentation from test pages and userId module docs --- integrationExamples/gpt/audigentSegments_example.html | 5 ----- integrationExamples/gpt/userId_example.html | 5 ----- modules/userId/userId.md | 5 ----- 3 files changed, 15 deletions(-) diff --git a/integrationExamples/gpt/audigentSegments_example.html b/integrationExamples/gpt/audigentSegments_example.html index 9b72da76d23..7739b558327 100644 --- a/integrationExamples/gpt/audigentSegments_example.html +++ b/integrationExamples/gpt/audigentSegments_example.html @@ -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", diff --git a/integrationExamples/gpt/userId_example.html b/integrationExamples/gpt/userId_example.html index 6d2c2ce677a..3bb8ce2df66 100644 --- a/integrationExamples/gpt/userId_example.html +++ b/integrationExamples/gpt/userId_example.html @@ -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", diff --git a/modules/userId/userId.md b/modules/userId/userId.md index e6da02a6811..5ce31a4e3a9 100644 --- a/modules/userId/userId.md +++ b/modules/userId/userId.md @@ -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', From 16dd0837db32b69819fa0165734c789936266e1e Mon Sep 17 00:00:00 2001 From: Ian Flournoy Date: Thu, 7 May 2020 14:49:17 -0400 Subject: [PATCH 08/10] PBID-11: Remove SUBMODULES_THAT_ALWAYS_REFRESH_ID feature from userId system --- modules/userId/index.js | 4 -- src/constants.json | 3 -- test/spec/modules/userId_spec.js | 76 -------------------------------- 3 files changed, 83 deletions(-) diff --git a/modules/userId/index.js b/modules/userId/index.js index 5de8ad75978..4ab39493b92 100644 --- a/modules/userId/index.js +++ b/modules/userId/index.js @@ -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); diff --git a/src/constants.json b/src/constants.json index 7ffef9db1aa..5965d77a6c4 100644 --- a/src/constants.json +++ b/src/constants.json @@ -97,8 +97,5 @@ "BID_TARGETING_SET": "targetingSet", "RENDERED": "rendered", "BID_REJECTED": "bidRejected" - }, - "SUBMODULES_THAT_ALWAYS_REFRESH_ID": { - "parrableId": true } } diff --git a/test/spec/modules/userId_spec.js b/test/spec/modules/userId_spec.js index b48d0a9a98c..b5497b55ed1 100644 --- a/test/spec/modules/userId_spec.js +++ b/test/spec/modules/userId_spec.js @@ -1231,81 +1231,5 @@ describe('User ID', function() { events.emit(CONSTANTS.EVENTS.AUCTION_END, {}); expect(server.requests[0].url).to.equal('https://match.adsrvr.org/track/rid?ttd_pid=rubicon&fmt=json'); }); - - it('callback for submodules that always need to refresh stored id', function(done) { - let adUnits = [getAdUnitMock()]; - let innerAdUnits; - const parrableStoredId = '01.1111111111.test-eid'; - const parrableRefreshedId = '02.2222222222.test-eid'; - coreStorage.setCookie('_parrable_eid', parrableStoredId, (new Date(Date.now() + 5000).toUTCString())); - - const parrableIdSubmoduleMock = { - name: 'parrableId', - decode: function(value) { - return { 'parrableid': value }; - }, - getId: function() { - return { - callback: function(cb) { - cb(parrableRefreshedId); - } - }; - } - }; - - const parrableConfigMock = { - userSync: { - syncDelay: 0, - userIds: [{ - name: 'parrableId', - storage: { - type: 'cookie', - name: '_parrable_eid' - } - }] - } - }; - - setSubmoduleRegistry([parrableIdSubmoduleMock]); - attachIdSystem(parrableIdSubmoduleMock); - init(config); - config.setConfig(parrableConfigMock); - - // make first bid request, should use stored id value - requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - innerAdUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.parrableid'); - expect(bid.userId.parrableid).to.equal(parrableStoredId); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'parrable.com', - uids: [{id: parrableStoredId, atype: 1}] - }); - }); - }); - - // attach a handler for auction end event to run the second bid request - events.on(CONSTANTS.EVENTS.AUCTION_END, function handler(submodule) { - if (submodule === 'parrableIdSubmoduleMock') { - // make the second bid request, id should have been refreshed - requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - innerAdUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.parrableid'); - expect(bid.userId.parrableid).to.equal(parrableRefreshedId); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'parrable.com', - uids: [{id: parrableRefreshedId, atype: 1}] - }); - }); - }); - events.off(CONSTANTS.EVENTS.AUCTION_END, handler); - done(); - } - }); - - // emit an auction end event to run the submodule callback - events.emit(CONSTANTS.EVENTS.AUCTION_END, 'parrableIdSubmoduleMock'); - }); }); }); From 7bf438b3605ecfb530082c030ee5bfa8f29bd44e Mon Sep 17 00:00:00 2001 From: Ian Flournoy Date: Fri, 8 May 2020 17:56:13 -0400 Subject: [PATCH 09/10] PBID-11: Use better serialize implementation for Parrable compound cookie --- modules/parrableIdSystem.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/parrableIdSystem.js b/modules/parrableIdSystem.js index c38132f8f07..a4617e2dc60 100644 --- a/modules/parrableIdSystem.js +++ b/modules/parrableIdSystem.js @@ -40,17 +40,19 @@ function deserializeParrableId(parrableIdStr) { } function serializeParrableId(parrableId) { - let str = ''; + let components = []; + if (parrableId.eid) { - str += 'eid:' + parrableId.eid; + components.push('eid:' + parrableId.eid); } if (parrableId.ibaOptout) { - str += ',ibaOptout:1'; + components.push('ibaOptout:1'); } if (parrableId.ccpaOptout) { - str += ',ccpaOptout:1'; + components.push('ccpaOptout:1'); } - return str; + + return components.join(','); } function isValidConfig(configParams) { From 527303e23b020e4e3acba128fc79347365e2298f Mon Sep 17 00:00:00 2001 From: Ian Flournoy Date: Fri, 8 May 2020 17:56:34 -0400 Subject: [PATCH 10/10] PBID-11: Update parrableIdSystem interface documentation --- modules/parrableIdSystem.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/parrableIdSystem.js b/modules/parrableIdSystem.js index a4617e2dc60..91a018b70ce 100644 --- a/modules/parrableIdSystem.js +++ b/modules/parrableIdSystem.js @@ -180,12 +180,12 @@ export const parrableIdSubmodule = { /** * decode the stored id value for passing to bid requests * @function - * @param {string} value + * @param {ParrableId} parrableId * @return {(Object|undefined} */ - decode(value) { - if (value && utils.isPlainObject(value)) { - return { 'parrableid': value.eid }; + decode(parrableId) { + if (parrableId && utils.isPlainObject(parrableId)) { + return { 'parrableid': parrableId.eid }; } return undefined; }, @@ -195,7 +195,7 @@ export const parrableIdSubmodule = { * @function * @param {SubmoduleParams} [configParams] * @param {ConsentData} [consentData] - * @returns {function(callback:function)} + * @returns {function(callback:function), id:ParrableId} */ getId(configParams, gdprConsentData, currentStoredId) { return fetchId(configParams);