Skip to content

Commit 9bec364

Browse files
radubarbosdumitrubarbos
authored and
Michele Nasti
committed
Connect id : storage duration updates and no longer require puid or he to be set (prebid#9965)
* Yahoo connect id storage updates. * Yahoo connect id storage updates. * Yahoo connect id storage updates. * Yahoo connect id storage updates. * Yahoo ConnectId - test fixes. * Yahoo ConnectId - updated doc. * Yahoo ConnectId - test cleanup. --------- Co-authored-by: dumitrubarbos <[email protected]>
1 parent 195e62a commit 9bec364

File tree

3 files changed

+326
-38
lines changed

3 files changed

+326
-38
lines changed

modules/connectIdSystem.js

Lines changed: 80 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ import {uspDataHandler} from '../src/adapterManager.js';
1515
import {MODULE_TYPE_UID} from '../src/activities/modules.js';
1616

1717
const MODULE_NAME = 'connectId';
18-
const STORAGE_EXPIRY_DAYS = 14;
18+
const STORAGE_EXPIRY_DAYS = 365;
19+
const STORAGE_DURATION = 60 * 60 * 24 * 1000 * STORAGE_EXPIRY_DAYS;
20+
const ID_EXPIRY_DAYS = 14;
21+
const VALID_ID_DURATION = 60 * 60 * 24 * 1000 * ID_EXPIRY_DAYS;
22+
const PUID_EXPIRY_DAYS = 30;
23+
const PUID_EXPIRY = 60 * 60 * 24 * 1000 * PUID_EXPIRY_DAYS;
1924
const VENDOR_ID = 25;
2025
const PLACEHOLDER = '__PIXEL_ID__';
2126
const UPS_ENDPOINT = `https://ups.analytics.yahoo.com/ups/${PLACEHOLDER}/fed`;
@@ -28,11 +33,11 @@ export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleNam
2833
* @param {Object} obj
2934
*/
3035
function storeObject(obj) {
31-
const expires = Date.now() + (60 * 60 * 24 * 1000 * STORAGE_EXPIRY_DAYS);
36+
const expires = Date.now() + STORAGE_DURATION;
3237
if (storage.cookiesAreEnabled()) {
3338
setEtldPlusOneCookie(MODULE_NAME, JSON.stringify(obj), new Date(expires), getSiteHostname());
34-
} else if (storage.localStorageIsEnabled()) {
35-
obj.__expires = expires;
39+
}
40+
if (storage.localStorageIsEnabled()) {
3641
storage.setDataInLocalStorage(MODULE_NAME, JSON.stringify(obj));
3742
}
3843
}
@@ -75,7 +80,9 @@ function getIdFromLocalStorage() {
7580
if (storedIdData) {
7681
try {
7782
storedIdData = JSON.parse(storedIdData);
78-
} catch {}
83+
} catch (e) {
84+
logError(`${MODULE_NAME} module: error while reading the local storage data.`);
85+
}
7986
if (isPlainObject(storedIdData) && storedIdData.__expires &&
8087
storedIdData.__expires <= Date.now()) {
8188
storage.removeDataFromLocalStorage(MODULE_NAME);
@@ -87,6 +94,34 @@ function getIdFromLocalStorage() {
8794
return null;
8895
}
8996

97+
function syncLocalStorageToCookie() {
98+
if (!storage.cookiesAreEnabled()) {
99+
return;
100+
}
101+
const value = getIdFromLocalStorage();
102+
const newCookieExpireTime = Date.now() + STORAGE_DURATION;
103+
setEtldPlusOneCookie(MODULE_NAME, JSON.stringify(value), new Date(newCookieExpireTime), getSiteHostname());
104+
}
105+
106+
function isStale(storedIdData) {
107+
if (isPlainObject(storedIdData) && storedIdData.lastSynced &&
108+
(storedIdData.lastSynced + VALID_ID_DURATION) <= Date.now()) {
109+
return true;
110+
}
111+
return false;
112+
}
113+
114+
function getStoredId() {
115+
let storedId = getIdFromCookie();
116+
if (!storedId) {
117+
storedId = getIdFromLocalStorage();
118+
if (storedId && !isStale(storedId)) {
119+
syncLocalStorageToCookie();
120+
}
121+
}
122+
return storedId;
123+
}
124+
90125
function getSiteHostname() {
91126
const pageInfo = parseUrl(getRefererInfo().page);
92127
return pageInfo.hostname;
@@ -127,16 +162,31 @@ export const connectIdSubmodule = {
127162
return;
128163
}
129164
const params = config.params || {};
130-
if (!params || (typeof params.he !== 'string' && typeof params.puid !== 'string') ||
165+
if (!params ||
131166
(typeof params.pixelId === 'undefined' && typeof params.endpoint === 'undefined')) {
132-
logError(`${MODULE_NAME} module: configurataion requires the 'pixelId' and at ` +
133-
`least one of the 'he' or 'puid' parameters to be defined.`);
167+
logError(`${MODULE_NAME} module: configuration requires the 'pixelId'.`);
134168
return;
135169
}
136170

137-
const storedId = getIdFromCookie() || getIdFromLocalStorage();
171+
const storedId = getStoredId();
172+
173+
let shouldResync = isStale(storedId);
174+
138175
if (storedId) {
139-
return {id: storedId};
176+
if (isPlainObject(storedId) && storedId.puid && storedId.lastUsed && !params.puid &&
177+
(storedId.lastUsed + PUID_EXPIRY) <= Date.now()) {
178+
delete storedId.puid;
179+
shouldResync = true;
180+
}
181+
if ((params.he && params.he !== storedId.he) ||
182+
(params.puid && params.puid !== storedId.puid)) {
183+
shouldResync = true;
184+
}
185+
if (!shouldResync) {
186+
storedId.lastUsed = Date.now();
187+
storeObject(storedId);
188+
return {id: storedId};
189+
}
140190
}
141191

142192
const uspString = uspDataHandler.getConsentData() || '';
@@ -159,14 +209,27 @@ export const connectIdSubmodule = {
159209
}
160210
});
161211

212+
const hashedEmail = params.he || storedId?.he;
213+
if (hashedEmail) {
214+
data.he = hashedEmail;
215+
}
216+
if (!data.puid && storedId?.puid) {
217+
data.puid = storedId.puid;
218+
}
219+
162220
const resp = function (callback) {
163221
const callbacks = {
164222
success: response => {
165223
let responseObj;
166224
if (response) {
167225
try {
168226
responseObj = JSON.parse(response);
169-
if (isPlainObject(responseObj) && Object.keys(responseObj).length > 0) {
227+
if (isPlainObject(responseObj) && Object.keys(responseObj).length > 0 &&
228+
(!!responseObj.connectId || !!responseObj.connectid)) {
229+
responseObj.he = params.he;
230+
responseObj.puid = params.puid || responseObj.puid;
231+
responseObj.lastSynced = Date.now();
232+
responseObj.lastUsed = Date.now();
170233
storeObject(responseObj);
171234
} else {
172235
logError(`${MODULE_NAME} module: UPS response returned an invalid payload ${response}`);
@@ -186,7 +249,12 @@ export const connectIdSubmodule = {
186249
let url = `${params.endpoint || endpoint}?${formatQS(data)}`;
187250
connectIdSubmodule.getAjaxFn()(url, callbacks, null, {method: 'GET', withCredentials: true});
188251
};
189-
return {callback: resp};
252+
const result = {callback: resp};
253+
if (shouldResync && storedId) {
254+
result.id = storedId;
255+
}
256+
257+
return result;
190258
},
191259

192260
/**

modules/connectIdSystem.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,15 @@
22

33
Yahoo ConnectID user ID Module.
44

5+
*Note: The storage config should be ommited as the module handles the storage of the needed information.
6+
57
### Prebid Params
68

79
```
810
pbjs.setConfig({
911
userSync: {
1012
userIds: [{
1113
name: 'connectId',
12-
storage: {
13-
name: 'connectId',
14-
type: 'html5',
15-
expires: 15
16-
},
1714
params: {
1815
pixelId: 58776,
1916
he: '0bef996248d63cea1529cb86de31e9547a712d9f380146e98bbd39beec70355a'
@@ -31,5 +28,5 @@ The below parameters apply only to the Yahoo ConnectID user ID Module.
3128
| params | Required | Object | Container of all module params. ||
3229
| params.pixelId | Required | Number |
3330
The Yahoo-supplied publisher-specific pixel ID. | `"0000"` |
34-
| params.he | Optional | String | The SHA-256 hashed user email address which has been lowercased prior to hashing. Pass both `he` and `puid` params if present, otherwise pass either of the two that is available. |`"ed8ddbf5a171981db8ef938596ca297d5e3f84bcc280041c5880dba3baf9c1d4"`|
35-
| params.puid | Optional | String | The publisher supplied user identifier such as a first-party cookie. Pass both `he` and `puid` params if present, otherwise pass either of the two that is available. | `"ab9iibf5a231ii1db8ef911596ca297d5e3f84biii00041c5880dba3baf9c1da"` |
31+
| params.he | Optional | String | The SHA-256 hashed user email address which has been lowercased prior to hashing. |`"ed8ddbf5a171981db8ef938596ca297d5e3f84bcc280041c5880dba3baf9c1d4"`|
32+
| params.puid | Optional | String | A domain-specific user identifier such as a first-party cookie. If not passed, a puid value will be auto-generated and stored in local and / or cookie storage. | `"ab9iibf5a231ii1db8ef911596ca297d5e3f84biii00041c5880dba3baf9c1da"` |

0 commit comments

Comments
 (0)