Skip to content
This repository was archived by the owner on Mar 12, 2025. It is now read-only.

Commit f40a324

Browse files
radubarbosdumitrubarbos
and
dumitrubarbos
authored
Yahoo ConnectId - backend sync updates. (prebid#10590)
Co-authored-by: dumitrubarbos <[email protected]>
1 parent 24a90d3 commit f40a324

File tree

2 files changed

+107
-3
lines changed

2 files changed

+107
-3
lines changed

modules/connectIdSystem.js

+33-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {submodule} from '../src/hook.js';
1010
import {includes} from '../src/polyfill.js';
1111
import {getRefererInfo} from '../src/refererDetection.js';
1212
import {getStorageManager} from '../src/storageManager.js';
13-
import {formatQS, isPlainObject, logError, parseUrl} from '../src/utils.js';
13+
import {formatQS, isNumber, isPlainObject, logError, parseUrl} from '../src/utils.js';
1414
import {uspDataHandler, gppDataHandler} from '../src/adapterManager.js';
1515
import {MODULE_TYPE_UID} from '../src/activities/modules.js';
1616

@@ -26,6 +26,16 @@ const PLACEHOLDER = '__PIXEL_ID__';
2626
const UPS_ENDPOINT = `https://ups.analytics.yahoo.com/ups/${PLACEHOLDER}/fed`;
2727
const OVERRIDE_OPT_OUT_KEY = 'connectIdOptOut';
2828
const INPUT_PARAM_KEYS = ['pixelId', 'he', 'puid'];
29+
const O_AND_O_DOMAINS = [
30+
'yahoo.com',
31+
'aol.com',
32+
'aol.ca',
33+
'aol.de',
34+
'aol.co.uk',
35+
'engadget.com',
36+
'techcrunch.com',
37+
'autoblog.com',
38+
];
2939
export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME});
3040

3141
/**
@@ -104,9 +114,11 @@ function syncLocalStorageToCookie() {
104114
}
105115

106116
function isStale(storedIdData) {
107-
if (isPlainObject(storedIdData) && storedIdData.lastSynced &&
108-
(storedIdData.lastSynced + VALID_ID_DURATION) <= Date.now()) {
117+
if (isOAndOTraffic()) {
109118
return true;
119+
} else if (isPlainObject(storedIdData) && storedIdData.lastSynced) {
120+
const validTTL = storedIdData.ttl || VALID_ID_DURATION;
121+
return storedIdData.lastSynced + validTTL <= Date.now();
110122
}
111123
return false;
112124
}
@@ -127,6 +139,17 @@ function getSiteHostname() {
127139
return pageInfo.hostname;
128140
}
129141

142+
function isOAndOTraffic() {
143+
let referer = getRefererInfo().ref;
144+
145+
if (referer) {
146+
referer = parseUrl(referer).hostname;
147+
const subDomains = referer.split('.');
148+
referer = subDomains.slice(subDomains.length - 2, subDomains.length).join('.');
149+
}
150+
return O_AND_O_DOMAINS.indexOf(referer) >= 0;
151+
}
152+
130153
/** @type {Submodule} */
131154
export const connectIdSubmodule = {
132155
/**
@@ -238,6 +261,13 @@ export const connectIdSubmodule = {
238261
responseObj.puid = params.puid || responseObj.puid;
239262
responseObj.lastSynced = Date.now();
240263
responseObj.lastUsed = Date.now();
264+
if (isNumber(responseObj.ttl)) {
265+
let validTTLMiliseconds = responseObj.ttl * 60 * 60 * 1000;
266+
if (validTTLMiliseconds > VALID_ID_DURATION) {
267+
validTTLMiliseconds = VALID_ID_DURATION;
268+
}
269+
responseObj.ttl = validTTLMiliseconds;
270+
}
241271
storeObject(responseObj);
242272
} else {
243273
logError(`${MODULE_NAME} module: UPS response returned an invalid payload ${response}`);

test/spec/modules/connectIdSystem_spec.js

+74
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {connectIdSubmodule, storage} from 'modules/connectIdSystem.js';
33
import {server} from '../../mocks/xhr';
44
import {parseQS, parseUrl} from 'src/utils.js';
55
import {uspDataHandler, gppDataHandler} from 'src/adapterManager.js';
6+
import * as refererDetection from '../../../src/refererDetection';
67

78
const TEST_SERVER_URL = 'http://localhost:9876/';
89

@@ -288,6 +289,79 @@ describe('Yahoo ConnectID Submodule', () => {
288289
expect(setCookieStub.firstCall.args[2]).to.equal(expiryDelta.toUTCString());
289290
});
290291

292+
it('returns an object with the stored ID from cookies and syncs because of expired TTL', () => {
293+
const last2Days = Date.now() - (60 * 60 * 24 * 1000 * 2);
294+
const last21Days = Date.now() - (60 * 60 * 24 * 1000 * 21);
295+
const ttl = 10000;
296+
const cookieData = {connectId: 'foo', he: 'email', lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl};
297+
getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData));
298+
299+
let result = invokeGetIdAPI({
300+
he: HASHED_EMAIL,
301+
pixelId: PIXEL_ID
302+
}, consentData);
303+
304+
expect(result).to.be.an('object').that.has.all.keys('id', 'callback');
305+
expect(result.id).to.deep.equal(cookieData);
306+
expect(typeof result.callback).to.equal('function');
307+
});
308+
309+
it('returns an object with the stored ID from cookies and not syncs because of valid TTL', () => {
310+
const last2Days = Date.now() - (60 * 60 * 24 * 1000 * 2);
311+
const last21Days = Date.now() - (60 * 60 * 24 * 1000 * 21);
312+
const ttl = 60 * 60 * 24 * 1000 * 3;
313+
const cookieData = {connectId: 'foo', he: HASHED_EMAIL, lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl};
314+
getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData));
315+
316+
let result = invokeGetIdAPI({
317+
he: HASHED_EMAIL,
318+
pixelId: PIXEL_ID
319+
}, consentData);
320+
321+
expect(result).to.be.an('object').that.has.all.keys('id');
322+
cookieData.lastUsed = result.id.lastUsed;
323+
expect(result.id).to.deep.equal(cookieData);
324+
});
325+
326+
it('returns an object with the stored ID from cookies and not syncs because of valid TTL with provided puid', () => {
327+
const last2Days = Date.now() - (60 * 60 * 24 * 1000 * 2);
328+
const last21Days = Date.now() - (60 * 60 * 24 * 1000 * 21);
329+
const ttl = 60 * 60 * 24 * 1000 * 3;
330+
const cookieData = {connectId: 'foo', he: HASHED_EMAIL, lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl};
331+
getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData));
332+
333+
let result = invokeGetIdAPI({
334+
he: HASHED_EMAIL,
335+
pixelId: PIXEL_ID,
336+
puid: '9'
337+
}, consentData);
338+
339+
expect(result).to.be.an('object').that.has.all.keys('id');
340+
cookieData.lastUsed = result.id.lastUsed;
341+
expect(result.id).to.deep.equal(cookieData);
342+
});
343+
344+
it('returns an object with the stored ID from cookies and syncs because is O&O traffic', () => {
345+
const last2Days = Date.now() - (60 * 60 * 24 * 1000 * 2);
346+
const last21Days = Date.now() - (60 * 60 * 24 * 1000 * 21);
347+
const ttl = 60 * 60 * 24 * 1000 * 3;
348+
const cookieData = {connectId: 'foo', he: HASHED_EMAIL, lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl};
349+
getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData));
350+
const getRefererInfoStub = sinon.stub(refererDetection, 'getRefererInfo');
351+
getRefererInfoStub.returns({
352+
ref: 'https://dev.fc.yahoo.com?test'
353+
});
354+
let result = invokeGetIdAPI({
355+
he: HASHED_EMAIL,
356+
pixelId: PIXEL_ID
357+
}, consentData);
358+
getRefererInfoStub.restore();
359+
360+
expect(result).to.be.an('object').that.has.all.keys('id', 'callback');
361+
expect(result.id).to.deep.equal(cookieData);
362+
expect(typeof result.callback).to.equal('function');
363+
});
364+
291365
it('Makes an ajax GET request to the production API endpoint with stored puid when id is stale', () => {
292366
const last15Days = Date.now() - (60 * 60 * 24 * 1000 * 15);
293367
const last29Days = Date.now() - (60 * 60 * 24 * 1000 * 29);

0 commit comments

Comments
 (0)