Skip to content

Commit

Permalink
Yahoo ConnectId - backend sync updates. (prebid#10590)
Browse files Browse the repository at this point in the history
Co-authored-by: dumitrubarbos <[email protected]>
  • Loading branch information
radubarbos and dumitrubarbos authored Oct 27, 2023
1 parent 24a90d3 commit f40a324
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 3 deletions.
36 changes: 33 additions & 3 deletions modules/connectIdSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {submodule} from '../src/hook.js';
import {includes} from '../src/polyfill.js';
import {getRefererInfo} from '../src/refererDetection.js';
import {getStorageManager} from '../src/storageManager.js';
import {formatQS, isPlainObject, logError, parseUrl} from '../src/utils.js';
import {formatQS, isNumber, isPlainObject, logError, parseUrl} from '../src/utils.js';
import {uspDataHandler, gppDataHandler} from '../src/adapterManager.js';
import {MODULE_TYPE_UID} from '../src/activities/modules.js';

Expand All @@ -26,6 +26,16 @@ const PLACEHOLDER = '__PIXEL_ID__';
const UPS_ENDPOINT = `https://ups.analytics.yahoo.com/ups/${PLACEHOLDER}/fed`;
const OVERRIDE_OPT_OUT_KEY = 'connectIdOptOut';
const INPUT_PARAM_KEYS = ['pixelId', 'he', 'puid'];
const O_AND_O_DOMAINS = [
'yahoo.com',
'aol.com',
'aol.ca',
'aol.de',
'aol.co.uk',
'engadget.com',
'techcrunch.com',
'autoblog.com',
];
export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME});

/**
Expand Down Expand Up @@ -104,9 +114,11 @@ function syncLocalStorageToCookie() {
}

function isStale(storedIdData) {
if (isPlainObject(storedIdData) && storedIdData.lastSynced &&
(storedIdData.lastSynced + VALID_ID_DURATION) <= Date.now()) {
if (isOAndOTraffic()) {
return true;
} else if (isPlainObject(storedIdData) && storedIdData.lastSynced) {
const validTTL = storedIdData.ttl || VALID_ID_DURATION;
return storedIdData.lastSynced + validTTL <= Date.now();
}
return false;
}
Expand All @@ -127,6 +139,17 @@ function getSiteHostname() {
return pageInfo.hostname;
}

function isOAndOTraffic() {
let referer = getRefererInfo().ref;

if (referer) {
referer = parseUrl(referer).hostname;
const subDomains = referer.split('.');
referer = subDomains.slice(subDomains.length - 2, subDomains.length).join('.');
}
return O_AND_O_DOMAINS.indexOf(referer) >= 0;
}

/** @type {Submodule} */
export const connectIdSubmodule = {
/**
Expand Down Expand Up @@ -238,6 +261,13 @@ export const connectIdSubmodule = {
responseObj.puid = params.puid || responseObj.puid;
responseObj.lastSynced = Date.now();
responseObj.lastUsed = Date.now();
if (isNumber(responseObj.ttl)) {
let validTTLMiliseconds = responseObj.ttl * 60 * 60 * 1000;
if (validTTLMiliseconds > VALID_ID_DURATION) {
validTTLMiliseconds = VALID_ID_DURATION;
}
responseObj.ttl = validTTLMiliseconds;
}
storeObject(responseObj);
} else {
logError(`${MODULE_NAME} module: UPS response returned an invalid payload ${response}`);
Expand Down
74 changes: 74 additions & 0 deletions test/spec/modules/connectIdSystem_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {connectIdSubmodule, storage} from 'modules/connectIdSystem.js';
import {server} from '../../mocks/xhr';
import {parseQS, parseUrl} from 'src/utils.js';
import {uspDataHandler, gppDataHandler} from 'src/adapterManager.js';
import * as refererDetection from '../../../src/refererDetection';

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

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

it('returns an object with the stored ID from cookies and syncs because of expired TTL', () => {
const last2Days = Date.now() - (60 * 60 * 24 * 1000 * 2);
const last21Days = Date.now() - (60 * 60 * 24 * 1000 * 21);
const ttl = 10000;
const cookieData = {connectId: 'foo', he: 'email', lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl};
getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData));

let result = invokeGetIdAPI({
he: HASHED_EMAIL,
pixelId: PIXEL_ID
}, consentData);

expect(result).to.be.an('object').that.has.all.keys('id', 'callback');
expect(result.id).to.deep.equal(cookieData);
expect(typeof result.callback).to.equal('function');
});

it('returns an object with the stored ID from cookies and not syncs because of valid TTL', () => {
const last2Days = Date.now() - (60 * 60 * 24 * 1000 * 2);
const last21Days = Date.now() - (60 * 60 * 24 * 1000 * 21);
const ttl = 60 * 60 * 24 * 1000 * 3;
const cookieData = {connectId: 'foo', he: HASHED_EMAIL, lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl};
getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData));

let result = invokeGetIdAPI({
he: HASHED_EMAIL,
pixelId: PIXEL_ID
}, consentData);

expect(result).to.be.an('object').that.has.all.keys('id');
cookieData.lastUsed = result.id.lastUsed;
expect(result.id).to.deep.equal(cookieData);
});

it('returns an object with the stored ID from cookies and not syncs because of valid TTL with provided puid', () => {
const last2Days = Date.now() - (60 * 60 * 24 * 1000 * 2);
const last21Days = Date.now() - (60 * 60 * 24 * 1000 * 21);
const ttl = 60 * 60 * 24 * 1000 * 3;
const cookieData = {connectId: 'foo', he: HASHED_EMAIL, lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl};
getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData));

let result = invokeGetIdAPI({
he: HASHED_EMAIL,
pixelId: PIXEL_ID,
puid: '9'
}, consentData);

expect(result).to.be.an('object').that.has.all.keys('id');
cookieData.lastUsed = result.id.lastUsed;
expect(result.id).to.deep.equal(cookieData);
});

it('returns an object with the stored ID from cookies and syncs because is O&O traffic', () => {
const last2Days = Date.now() - (60 * 60 * 24 * 1000 * 2);
const last21Days = Date.now() - (60 * 60 * 24 * 1000 * 21);
const ttl = 60 * 60 * 24 * 1000 * 3;
const cookieData = {connectId: 'foo', he: HASHED_EMAIL, lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl};
getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData));
const getRefererInfoStub = sinon.stub(refererDetection, 'getRefererInfo');
getRefererInfoStub.returns({
ref: 'https://dev.fc.yahoo.com?test'
});
let result = invokeGetIdAPI({
he: HASHED_EMAIL,
pixelId: PIXEL_ID
}, consentData);
getRefererInfoStub.restore();

expect(result).to.be.an('object').that.has.all.keys('id', 'callback');
expect(result.id).to.deep.equal(cookieData);
expect(typeof result.callback).to.equal('function');
});

it('Makes an ajax GET request to the production API endpoint with stored puid when id is stale', () => {
const last15Days = Date.now() - (60 * 60 * 24 * 1000 * 15);
const last29Days = Date.now() - (60 * 60 * 24 * 1000 * 29);
Expand Down

0 comments on commit f40a324

Please sign in to comment.