@@ -22,8 +22,9 @@ import {
22
22
CLIENT_HINTS_KEY ,
23
23
EMPTY ,
24
24
GVLID ,
25
- VERSION ,
25
+ VERSION , INVALID_ID , GDPR_ENDPOINT , VR_ENDPOINT , SYNC_ENDPOINT , SCREEN_PARAMS , GDPR_SYNC_ENDPOINT , SYNC_REFRESH_MILL
26
26
} from '../libraries/intentIqConstants/intentIqConstants.js' ;
27
+ import { SYNC_KEY } from '../libraries/intentIqUtils/getSyncKey.js' ;
27
28
28
29
/**
29
30
* @typedef {import('../modules/userId/index.js').Submodule } Submodule
@@ -44,9 +45,7 @@ const encoderCH = {
44
45
wow64 : 7 ,
45
46
fullVersionList : 8
46
47
} ;
47
- const INVALID_ID = 'INVALID_ID' ;
48
- const ENDPOINT = 'https://api.intentiq.com' ;
49
- const GDPR_ENDPOINT = 'https://api-gdpr.intentiq.com' ;
48
+
50
49
export let firstPartyData ;
51
50
52
51
/**
@@ -82,6 +81,89 @@ export function decryptData(encryptedText) {
82
81
return bytes . toString ( Utf8 ) ;
83
82
}
84
83
84
+ function collectDeviceInfo ( ) {
85
+ return {
86
+ windowInnerHeight : window . innerHeight ,
87
+ windowInnerWidth : window . innerWidth ,
88
+ devicePixelRatio : window . devicePixelRatio ,
89
+ windowScreenHeight : window . screen . height ,
90
+ windowScreenWidth : window . screen . width ,
91
+ language : navigator . language
92
+ }
93
+ }
94
+
95
+ function addUniquenessToUrl ( url ) {
96
+ url += '&tsrnd=' + Math . floor ( Math . random ( ) * 1000 ) + '_' + new Date ( ) . getTime ( ) ;
97
+ return url ;
98
+ }
99
+
100
+ function appendDeviceInfoToUrl ( url , deviceInfo ) {
101
+ const screenParamsString = Object . entries ( SCREEN_PARAMS )
102
+ . map ( ( [ index , param ] ) => {
103
+ const value = ( deviceInfo ) [ param ] ;
104
+ return `${ index } :${ value } ` ;
105
+ } )
106
+ . join ( ',' ) ;
107
+
108
+ url += `&cz=${ encodeURIComponent ( screenParamsString ) } ` ;
109
+ url += `&dw=${ deviceInfo . windowScreenWidth } &dh=${ deviceInfo . windowScreenHeight } &dpr=${ deviceInfo . devicePixelRatio } &lan=${ deviceInfo . language } ` ;
110
+ return url ;
111
+ }
112
+
113
+ function appendFirstPartyData ( url , firstPartyData , partnerData ) {
114
+ url += firstPartyData . pid ? '&pid=' + encodeURIComponent ( firstPartyData . pid ) : '' ;
115
+ url += firstPartyData . pcid ? '&iiqidtype=2&iiqpcid=' + encodeURIComponent ( firstPartyData . pcid ) : '' ;
116
+ url += firstPartyData . pcidDate ? '&iiqpciddate=' + encodeURIComponent ( firstPartyData . pcidDate ) : '' ;
117
+ return url
118
+ }
119
+
120
+ function appendCMPData ( url , cmpData ) {
121
+ url += cmpData . uspString ? '&us_privacy=' + encodeURIComponent ( cmpData . uspString ) : '' ;
122
+ url += cmpData . gppString ? '&gpp=' + encodeURIComponent ( cmpData . gppString ) : '' ;
123
+ url += cmpData . gdprApplies
124
+ ? '&gdpr_consent=' + encodeURIComponent ( cmpData . gdprString ) + '&gdpr=1'
125
+ : '&gdpr=0' ;
126
+ return url
127
+ }
128
+
129
+ export function createPixelUrl ( firstPartyData , clientHints , configParams , partnerData , cmpData ) {
130
+ const deviceInfo = collectDeviceInfo ( )
131
+
132
+ let url = cmpData . gdprString ? GDPR_SYNC_ENDPOINT : SYNC_ENDPOINT ;
133
+ url += '/profiles_engine/ProfilesEngineServlet?at=20&mi=10&secure=1'
134
+ url += '&dpi=' + configParams . partner ;
135
+ url = appendFirstPartyData ( url , firstPartyData , partnerData ) ;
136
+ url = addUniquenessToUrl ( url ) ;
137
+ url += partnerData ?. clientType ? '&idtype=' + partnerData . clientType : '' ;
138
+ if ( deviceInfo ) url = appendDeviceInfoToUrl ( url , deviceInfo )
139
+ url += VERSION ? '&jsver=' + VERSION : '' ;
140
+ if ( clientHints ) url += '&uh=' + encodeURIComponent ( clientHints ) ;
141
+ url = appendVrrefAndFui ( url , configParams . domainName ) ;
142
+ url = appendCMPData ( url , cmpData )
143
+ return url ;
144
+ }
145
+
146
+ function sendSyncRequest ( allowedStorage , url , partner , firstPartyData , newUser ) {
147
+ const lastSyncDate = Number ( readData ( SYNC_KEY ( partner ) || '' , allowedStorage ) ) || false ;
148
+ const lastSyncElapsedTime = Date . now ( ) - lastSyncDate
149
+
150
+ if ( firstPartyData . isOptedOut ) {
151
+ const needToDoSync = ( Date . now ( ) - ( firstPartyData ?. date || firstPartyData ?. sCal || Date . now ( ) ) ) > SYNC_REFRESH_MILL
152
+ if ( newUser || needToDoSync ) {
153
+ ajax ( url , ( ) => {
154
+ } , undefined , { method : 'GET' , withCredentials : true } ) ;
155
+ if ( firstPartyData ?. date ) {
156
+ firstPartyData . date = Date . now ( )
157
+ storeData ( FIRST_PARTY_KEY , JSON . stringify ( firstPartyData ) , allowedStorage , firstPartyData ) ;
158
+ }
159
+ }
160
+ } else if ( ! lastSyncDate || lastSyncElapsedTime > SYNC_REFRESH_MILL ) {
161
+ storeData ( SYNC_KEY ( partner ) , Date . now ( ) + '' , allowedStorage ) ;
162
+ ajax ( url , ( ) => {
163
+ } , undefined , { method : 'GET' , withCredentials : true } ) ;
164
+ }
165
+ }
166
+
85
167
/**
86
168
* Parse json if possible, else return null
87
169
* @param data
@@ -161,6 +243,7 @@ export const intentIqIdSubmodule = {
161
243
decode ( value ) {
162
244
return value && value != '' && INVALID_ID != value ? { 'intentIqId' : value } : undefined ;
163
245
} ,
246
+
164
247
/**
165
248
* performs action to obtain id and return a value in the callback's response argument
166
249
* @function
@@ -210,13 +293,7 @@ export const intentIqIdSubmodule = {
210
293
211
294
const currentBrowserLowerCase = detectBrowser ( ) ;
212
295
const browserBlackList = typeof configParams . browserBlackList === 'string' ? configParams . browserBlackList . toLowerCase ( ) : '' ;
213
-
214
- // Check if current browser is in blacklist
215
- if ( browserBlackList ?. includes ( currentBrowserLowerCase ) ) {
216
- logError ( 'User ID - intentIqId submodule: browser is in blacklist!' ) ;
217
- if ( configParams . callback ) configParams . callback ( '' , BLACK_LIST ) ;
218
- return ;
219
- }
296
+ let newUser = false ;
220
297
221
298
if ( ! firstPartyData ?. pcid ) {
222
299
const firstPartyId = generateGUID ( ) ;
@@ -230,6 +307,7 @@ export const intentIqIdSubmodule = {
230
307
gdprString : EMPTY ,
231
308
date : Date . now ( )
232
309
} ;
310
+ newUser = true ;
233
311
storeData ( FIRST_PARTY_KEY , JSON . stringify ( firstPartyData ) , allowedStorage , firstPartyData ) ;
234
312
} else if ( ! firstPartyData . pcidDate ) {
235
313
firstPartyData . pcidDate = Date . now ( ) ;
@@ -284,7 +362,6 @@ export const intentIqIdSubmodule = {
284
362
firstPartyData . uspString = cmpData . uspString ;
285
363
firstPartyData . gppString = cmpData . gppString ;
286
364
firstPartyData . gdprString = cmpData . gdprString ;
287
- firstPartyData . date = Date . now ( ) ;
288
365
shouldCallServer = true ;
289
366
storeData ( FIRST_PARTY_KEY , JSON . stringify ( firstPartyData ) , allowedStorage , firstPartyData ) ;
290
367
storeData ( FIRST_PARTY_DATA_KEY , JSON . stringify ( partnerData ) , allowedStorage , firstPartyData ) ;
@@ -297,26 +374,29 @@ export const intentIqIdSubmodule = {
297
374
firePartnerCallback ( )
298
375
}
299
376
377
+ // Check if current browser is in blacklist
378
+ if ( browserBlackList ?. includes ( currentBrowserLowerCase ) ) {
379
+ logError ( 'User ID - intentIqId submodule: browser is in blacklist! Data will be not provided.' ) ;
380
+ if ( configParams . callback ) configParams . callback ( '' , BLACK_LIST ) ;
381
+ const url = createPixelUrl ( firstPartyData , clientHints , configParams , partnerData , cmpData )
382
+ sendSyncRequest ( allowedStorage , url , configParams . partner , firstPartyData , newUser )
383
+ return
384
+ }
385
+
300
386
if ( ! shouldCallServer ) {
301
387
if ( isGroupB ) runtimeEids = { eids : [ ] } ;
302
388
firePartnerCallback ( ) ;
303
389
return { id : runtimeEids . eids } ;
304
390
}
305
391
306
392
// use protocol relative urls for http or https
307
- let url = `${ gdprDetected ? GDPR_ENDPOINT : ENDPOINT } /profiles_engine/ProfilesEngineServlet?at=39&mi=10&dpi=${ configParams . partner } &pt=17&dpn=1` ;
393
+ let url = `${ gdprDetected ? GDPR_ENDPOINT : VR_ENDPOINT } /profiles_engine/ProfilesEngineServlet?at=39&mi=10&dpi=${ configParams . partner } &pt=17&dpn=1` ;
308
394
url += configParams . pcid ? '&pcid=' + encodeURIComponent ( configParams . pcid ) : '' ;
309
395
url += configParams . pai ? '&pai=' + encodeURIComponent ( configParams . pai ) : '' ;
310
- url += firstPartyData . pcid ? '&iiqidtype=2&iiqpcid=' + encodeURIComponent ( firstPartyData . pcid ) : '' ;
311
- url += firstPartyData . pid ? '&pid=' + encodeURIComponent ( firstPartyData . pid ) : '' ;
396
+ url = appendFirstPartyData ( url , firstPartyData , partnerData ) ;
312
397
url += ( partnerData . cttl ) ? '&cttl=' + encodeURIComponent ( partnerData . cttl ) : '' ;
313
398
url += ( partnerData . rrtt ) ? '&rrtt=' + encodeURIComponent ( partnerData . rrtt ) : '' ;
314
- url += firstPartyData . pcidDate ? '&iiqpciddate=' + encodeURIComponent ( firstPartyData . pcidDate ) : '' ;
315
- url += cmpData . uspString ? '&us_privacy=' + encodeURIComponent ( cmpData . uspString ) : '' ;
316
- url += cmpData . gppString ? '&gpp=' + encodeURIComponent ( cmpData . gppString ) : '' ;
317
- url += cmpData . gdprApplies
318
- ? '&gdpr_consent=' + encodeURIComponent ( cmpData . gdprString ) + '&gdpr=1'
319
- : '&gdpr=0' ;
399
+ url = appendCMPData ( url , cmpData )
320
400
url += clientHints ? '&uh=' + encodeURIComponent ( clientHints ) : '' ;
321
401
url += VERSION ? '&jsver=' + VERSION : '' ;
322
402
url += firstPartyData ?. group ? '&testGroup=' + encodeURIComponent ( firstPartyData . group ) : '' ;
@@ -403,7 +483,7 @@ export const intentIqIdSubmodule = {
403
483
}
404
484
405
485
if ( 'ct' in respJson ) {
406
- partnerData . ct = respJson . ct ;
486
+ partnerData . clientType = respJson . ct ;
407
487
}
408
488
409
489
if ( 'sid' in respJson ) {
0 commit comments