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

ParrableIdSystem: cache request filter status in first-party cookie #7044

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
3b0f871
Add tpcSupport, read it from xxhr and store it in compound cookie
victorigualada Apr 22, 2021
c04ffdf
Parse a cookie boolean number (0, 1) as a boolean value
victorigualada Apr 22, 2021
235f13d
Improve conditions
victorigualada Apr 22, 2021
8e0a8a1
Add tests
victorigualada Apr 23, 2021
320b68b
Tests passing
victorigualada Apr 23, 2021
925d0a4
Read the cookie splitting parrableId and params (tpc, tpcUntil)
victorigualada Apr 27, 2021
e2273fc
Adapt tests
victorigualada Apr 27, 2021
1fed201
Revert linting in test task
victorigualada Apr 27, 2021
304a184
Add request filter status handling
victorigualada Apr 28, 2021
6a0cdfe
Improve date treatment
victorigualada Apr 29, 2021
d6ae1fd
Replace Math.trunc with Math.floor
victorigualada May 9, 2021
a060e7d
Run only parrable tests
victorigualada May 12, 2021
2886cc4
Run all tests
victorigualada May 12, 2021
f7bf307
Add tpcSupport, read it from xxhr and store it in compound cookie
victorigualada Apr 22, 2021
54a9754
Parse a cookie boolean number (0, 1) as a boolean value
victorigualada Apr 22, 2021
c5a3e13
Improve conditions
victorigualada Apr 22, 2021
c81572f
Add tests
victorigualada Apr 23, 2021
6667268
Tests passing
victorigualada Apr 23, 2021
80e73ab
Read the cookie splitting parrableId and params (tpc, tpcUntil)
victorigualada Apr 27, 2021
3341002
Adapt tests
victorigualada Apr 27, 2021
23ee20b
Revert linting in test task
victorigualada Apr 27, 2021
4e11225
Add request filter status handling
victorigualada Apr 28, 2021
880e3ec
Improve date treatment
victorigualada Apr 29, 2021
2cc3800
Replace Math.trunc with Math.floor
victorigualada May 9, 2021
11902ab
Run only parrable tests
victorigualada May 12, 2021
4ac6243
Run all tests
victorigualada May 12, 2021
4f2d746
Increase cookie TTL
victorigualada May 24, 2021
49c09e4
Merge branch 'PBID-96_requestFilterStatus' of github.com:Parrable/Pre…
victorigualada May 24, 2021
6bb028f
Remove line break
victorigualada May 24, 2021
d971412
Increase cookie expire time to 20s
victorigualada May 26, 2021
3f8cb0f
Merge branch 'parrableIdSystem/PBID-96_requestFilterStatus' into PBID…
victorigualada May 27, 2021
da254ad
Fix lint problems
victorigualada May 27, 2021
1536cc4
Increase cookie time to 30s
victorigualada May 27, 2021
353a3d8
Merge remote-tracking branch 'origin/parrableIdSystem/PBID-96_request…
Jun 2, 2021
62905b7
Trigger CI run
Jun 2, 2021
efd224b
Merge pull request #19 from Parrable/PBID-96_requestFilterStatus
icflournoy Jun 17, 2021
1516b7f
Merge branch 'master' into parrableIdSystem/PBID-96_requestFilterStatus
Jun 17, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
41 changes: 37 additions & 4 deletions modules/parrableIdSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* @requires module:modules/userId
*/

// ci trigger: 1

import * as utils from '../src/utils.js'
import find from 'core-js-pure/features/array/find.js';
import { ajax } from '../src/ajax.js';
Expand Down Expand Up @@ -34,7 +36,7 @@ function deserializeParrableId(parrableIdStr) {

values.forEach(function(value) {
const pair = value.split(':');
if (+pair[1] === 1 || (pair[1] !== null && +pair[1] === 0)) { // unpack a value of 0 or 1 as boolean
if (pair[0] === 'ccpaOptout' || pair[0] === 'ibaOptout') { // unpack a value of 0 or 1 as boolean
parrableId[pair[0]] = Boolean(+pair[1]);
} else if (!isNaN(pair[1])) { // convert to number if is a number
parrableId[pair[0]] = +pair[1]
Expand Down Expand Up @@ -64,6 +66,10 @@ function serializeParrableId(parrableIdAndParams) {
components.push(tpcSupportComponent);
components.push(tpcUntil);
}
if (parrableIdAndParams.filteredUntil) {
components.push(`filteredUntil:${parrableIdAndParams.filteredUntil}`);
components.push(`filterHits:${parrableIdAndParams.filterHits}`);
}

return components.join(',');
}
Expand Down Expand Up @@ -96,12 +102,20 @@ function readCookie() {
const parrableIdStr = storage.getCookie(PARRABLE_COOKIE_NAME);
if (parrableIdStr) {
const parsedCookie = deserializeParrableId(decodeURIComponent(parrableIdStr));
const { tpc, tpcUntil, ...parrableId } = parsedCookie;
const { tpc, tpcUntil, filteredUntil, filterHits, ...parrableId } = parsedCookie;
let { eid, ibaOptout, ccpaOptout, ...params } = parsedCookie;

if ((Date.now() / 1000) >= tpcUntil) {
params.tpc = undefined;
}

if ((Date.now() / 1000) < filteredUntil) {
params.shouldFilter = true;
params.filteredUntil = filteredUntil;
} else {
params.shouldFilter = false;
params.filterHits = filterHits;
}
return { parrableId, params };
}
return null;
Expand Down Expand Up @@ -197,6 +211,11 @@ function epochFromTtl(ttl) {
return Math.floor((Date.now() / 1000) + ttl);
}

function incrementFilterHits(parrableId, params) {
params.filterHits += 1;
writeCookie({ ...parrableId, ...params })
}

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

Expand All @@ -212,7 +231,8 @@ function fetchId(configParams, gdprConsentData) {

const eid = parrableId ? parrableId.eid : null;
const refererInfo = getRefererInfo();
const tpcSupport = params ? params.tpc : null
const tpcSupport = params ? params.tpc : null;
const shouldFilter = params ? params.shouldFilter : null;
const uspString = uspDataHandler.getConsentData();
const gdprApplies = (gdprConsentData && typeof gdprConsentData.gdprApplies === 'boolean' && gdprConsentData.gdprApplies);
const gdprConsentString = (gdprConsentData && gdprApplies && gdprConsentData.consentString) || '';
Expand All @@ -230,6 +250,10 @@ function fetchId(configParams, gdprConsentData) {
tpcSupport
};

if (shouldFilter === false) {
data.filterHits = params.filterHits;
}

const searchParams = {
data: encodeBase64UrlSafe(btoa(JSON.stringify(data))),
gdpr: gdprApplies ? 1 : 0,
Expand Down Expand Up @@ -271,6 +295,10 @@ function fetchId(configParams, gdprConsentData) {
newParams.tpcSupport = responseObj.tpcSupport;
newParams.tpcUntil = epochFromTtl(responseObj.tpcSupportTtl);
}
if (responseObj.filterTtl) {
newParams.filteredUntil = epochFromTtl(responseObj.filterTtl);
newParams.filterHits = 0;
}
}
} catch (error) {
utils.logError(error);
Expand All @@ -288,7 +316,12 @@ function fetchId(configParams, gdprConsentData) {
cb();
}
};
ajax(PARRABLE_URL, callbacks, searchParams, options);

if (shouldFilter) {
incrementFilterHits(parrableId, params);
} else {
ajax(PARRABLE_URL, callbacks, searchParams, options);
}
};

return {
Expand Down
85 changes: 59 additions & 26 deletions test/spec/modules/parrableIdSystem_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ function serializeParrableId(parrableId) {
str += `,${tpcSupportComponent}`;
str += `,tpcUntil:${parrableId.tpcUntil}`;
}
if (parrableId.filteredUntil) {
str += `,filteredUntil:${parrableId.filteredUntil}`;
str += `,filterHits:${parrableId.filterHits}`;
}
return str;
}

Expand Down Expand Up @@ -249,7 +253,7 @@ describe('Parrable ID System', function() {
});
});

describe('third party cookie support status', function () {
describe('third party cookie support', function () {
let logErrorStub;
let callbackSpy = sinon.spy();

Expand Down Expand Up @@ -327,13 +331,30 @@ describe('Parrable ID System', function() {
);
});
});
});

describe('request-filter status', function () {
let logErrorStub;
let callbackSpy = sinon.spy();

beforeEach(function() {
logErrorStub = sinon.stub(utils, 'logError');
});

afterEach(function () {
callbackSpy.resetHistory();
removeParrableCookie();
});

describe('when getting tpcSupport from cookie', function () {
afterEach(function() {
logErrorStub.restore();
});

describe('when getting filterTtl from XHR response', function () {
let request;
let dateNowStub;
const dateNowMock = Date.now();
const tpcSupportTtl = dateNowMock;
const tpcUntilExpired = 1;
const filterTtl = 1000;

before(() => {
dateNowStub = sinon.stub(Date, 'now').returns(dateNowMock);
Expand All @@ -343,45 +364,57 @@ describe('Parrable ID System', function() {
dateNowStub.restore();
});

it('should send tpcSupport in the XHR', function () {
writeParrableCookie({
eid: P_COOKIE_EID,
tpc: true,
tpcUntil: (dateNowMock / 1000) + 1
});
it('should set filteredUntil in the cookie', function () {
let { callback } = parrableIdSubmodule.getId(P_CONFIG_MOCK);
callback(callbackSpy);
request = server.requests[0];

let queryParams = utils.parseQS(request.url.split('?')[1]);
let data = JSON.parse(atob(decodeBase64UrlSafe(queryParams.data)));
request.respond(
200,
RESPONSE_HEADERS,
JSON.stringify({ eid: P_XHR_EID, filterTtl })
);

expect(data.tpcSupport).to.equal(true);
expect(storage.getCookie(P_COOKIE_NAME)).to.equal(
encodeURIComponent(
'eid:' + P_XHR_EID +
',filteredUntil:' + Math.floor((dateNowMock / 1000) + filterTtl) +
',filterHits:0')
);
});

it('should unset tpcSupport from cookie when tpcUntil reached', function () {
it('should increment filterHits in the cookie', function () {
writeParrableCookie({
eid: P_COOKIE_EID,
tpcSupport: true,
tpcUntil: tpcUntilExpired
eid: P_XHR_EID,
filteredUntil: Math.floor((dateNowMock / 1000) + filterTtl),
filterHits: 0
});
let { callback } = parrableIdSubmodule.getId(P_CONFIG_MOCK);
callback(callbackSpy);
request = server.requests[0];

request.respond(
200,
RESPONSE_HEADERS,
JSON.stringify({ eid: P_XHR_EID, tpcSupport: false, tpcSupportTtl })
expect(storage.getCookie(P_COOKIE_NAME)).to.equal(
encodeURIComponent(
'eid:' + P_XHR_EID +
',filteredUntil:' + Math.floor((dateNowMock / 1000) + filterTtl) +
',filterHits:1')
);
});

it('should send filterHits in the XHR', function () {
const filterHits = 1;
writeParrableCookie({
eid: P_XHR_EID,
filteredUntil: Math.floor(dateNowMock / 1000),
filterHits
});
let { callback } = parrableIdSubmodule.getId(P_CONFIG_MOCK);
callback(callbackSpy);
request = server.requests[0];

let queryParams = utils.parseQS(request.url.split('?')[1]);
let data = JSON.parse(atob(decodeBase64UrlSafe(queryParams.data)));

expect(data.tpcSupport).to.equal(undefined);
expect(storage.getCookie(P_COOKIE_NAME)).to.equal(
encodeURIComponent('eid:' + P_XHR_EID + ',tpc:0,tpcUntil:' + Math.floor((dateNowMock / 1000) + tpcSupportTtl))
);
expect(data.filterHits).to.equal(filterHits);
});
});
});
Expand Down