• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

prebid / Prebid.js / #298

29 May 2025 11:21AM UTC coverage: 82.464% (-7.7%) from 90.144%
#298

push

travis-ci

prebidjs-release
Prebid 9.45.0 release

12606 of 17518 branches covered (71.96%)

18622 of 22582 relevant lines covered (82.46%)

157.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

8.99
/libraries/liveIntentId/idSystem.js
1
/**
2
 * This module adds LiveIntentId to the User ID module.
3
 * The {@link module:modules/userId} module is required.
4
 * @module modules/idSystem
5
 * @requires module:modules/userId
6
 */
7
import { triggerPixel, logError } from '../../src/utils.js';
8
import { ajaxBuilder } from '../../src/ajax.js';
9
import { gdprDataHandler, uspDataHandler, gppDataHandler } from '../../src/adapterManager.js';
10
import { submodule } from '../../src/hook.js';
11
import { LiveConnect } from 'live-connect-js'; // eslint-disable-line prebid/validate-imports
12
import { getStorageManager } from '../../src/storageManager.js';
13
import { MODULE_TYPE_UID } from '../../src/activities/modules.js';
14
import { DEFAULT_AJAX_TIMEOUT, MODULE_NAME, composeResult, eids, GVLID, DEFAULT_DELAY, PRIMARY_IDS, parseRequestedAttributes, makeSourceEventToSend, setUpTreatment } from './shared.js'
15

16
/**
17
 * @typedef {import('../modules/userId/index.js').Submodule} Submodule
18
 * @typedef {import('../modules/userId/index.js').SubmoduleConfig} SubmoduleConfig
19
 * @typedef {import('../modules/userId/index.js').IdResponse} IdResponse
20
 */
21

22
const EVENTS_TOPIC = 'pre_lips';
1✔
23

24
export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME});
1✔
25
const calls = {
1✔
26
  ajaxGet: (url, onSuccess, onError, timeout, headers) => {
27
    ajaxBuilder(timeout)(
×
28
      url,
29
      {
30
        success: onSuccess,
31
        error: onError
32
      },
33
      undefined,
34
      {
35
        method: 'GET',
36
        withCredentials: true,
37
        customHeaders: headers
38
      }
39
    )
40
  },
41
  pixelGet: (url, onload) => triggerPixel(url, onload)
×
42
}
43

44
let eventFired = false;
1✔
45
let liveConnect = null;
1✔
46

47
/**
48
 * This function is used in tests.
49
 */
50
export function reset() {
51
  if (window && window.liQ_instances) {
×
52
    window.liQ_instances.forEach(i => i.eventBus.off(EVENTS_TOPIC, setEventFiredFlag));
×
53
    window.liQ_instances = [];
×
54
  }
55
  liveIntentIdSubmodule.setModuleMode(null);
×
56
  eventFired = false;
×
57
  liveConnect = null;
×
58
}
59

60
/**
61
 * This function is used in tests.
62
 */
63
export function setEventFiredFlag() {
64
  eventFired = true;
1✔
65
}
66

67
function parseLiveIntentCollectorConfig(collectConfig) {
68
  const config = {};
×
69
  collectConfig = collectConfig || {};
×
70
  collectConfig.appId && (config.appId = collectConfig.appId);
×
71
  collectConfig.fpiStorageStrategy && (config.storageStrategy = collectConfig.fpiStorageStrategy);
×
72
  collectConfig.fpiExpirationDays && (config.expirationDays = collectConfig.fpiExpirationDays);
×
73
  collectConfig.collectorUrl && (config.collectorUrl = collectConfig.collectorUrl);
×
74
  config.ajaxTimeout = collectConfig.ajaxTimeout || DEFAULT_AJAX_TIMEOUT;
×
75
  return config;
×
76
}
77

78
/**
79
 * Create requestedAttributes array to pass to LiveConnect.
80
 * @function
81
 * @param {Object} overrides - object with boolean values that will override defaults { 'foo': true, 'bar': false }
82
 * @returns {Array}
83
 */
84

85
function initializeLiveConnect(configParams) {
86
  if (liveConnect) {
×
87
    return liveConnect;
×
88
  }
89

90
  configParams = configParams || {};
×
91
  const fpidConfig = configParams.fpid || {};
×
92

93
  const publisherId = configParams.publisherId || 'any';
×
94
  const identityResolutionConfig = {
×
95
    publisherId: publisherId,
96
    requestedAttributes: parseRequestedAttributes(configParams.requestedAttributesOverrides),
97
    extraAttributes: {
98
      ipv4: configParams.ipv4,
99
      ipv6: configParams.ipv6
100
    }
101
  };
102
  if (configParams.url) {
×
103
    identityResolutionConfig.url = configParams.url;
×
104
  };
105

106
  identityResolutionConfig.ajaxTimeout = configParams.ajaxTimeout || DEFAULT_AJAX_TIMEOUT;
×
107

108
  const liveConnectConfig = parseLiveIntentCollectorConfig(configParams.liCollectConfig);
×
109

110
  if (!liveConnectConfig.appId && configParams.distributorId) {
×
111
    liveConnectConfig.distributorId = configParams.distributorId;
×
112
    identityResolutionConfig.source = configParams.distributorId;
×
113
  } else {
114
    identityResolutionConfig.source = configParams.partner || 'prebid';
×
115
  }
116

117
  liveConnectConfig.wrapperName = 'prebid';
×
118
  liveConnectConfig.trackerVersion = '$prebid.version$';
×
119
  liveConnectConfig.identityResolutionConfig = identityResolutionConfig;
×
120
  liveConnectConfig.identifiersToResolve = configParams.identifiersToResolve || [];
×
121
  liveConnectConfig.fireEventDelay = configParams.fireEventDelay;
×
122

123
  liveConnectConfig.idCookie = {};
×
124
  liveConnectConfig.idCookie.name = fpidConfig.name;
×
125
  liveConnectConfig.idCookie.strategy = fpidConfig.strategy == 'html5' ? 'localStorage' : fpidConfig.strategy;
×
126

127
  const usPrivacyString = uspDataHandler.getConsentData();
×
128
  if (usPrivacyString) {
×
129
    liveConnectConfig.usPrivacyString = usPrivacyString;
×
130
  }
131
  const gdprConsent = gdprDataHandler.getConsentData();
×
132
  if (gdprConsent) {
×
133
    liveConnectConfig.gdprApplies = gdprConsent.gdprApplies;
×
134
    liveConnectConfig.gdprConsent = gdprConsent.consentString;
×
135
  }
136
  const gppConsent = gppDataHandler.getConsentData();
×
137
  if (gppConsent) {
×
138
    liveConnectConfig.gppString = gppConsent.gppString;
×
139
    liveConnectConfig.gppApplicableSections = gppConsent.applicableSections;
×
140
  }
141
  // The second param is the storage object, LS & Cookie manipulation uses PBJS.
142
  // The third param is the ajax and pixel object, the AJAX and pixel use PBJS.
143
  liveConnect = liveIntentIdSubmodule.getInitializer()(liveConnectConfig, storage, calls);
×
144

145
  const sourceEvent = makeSourceEventToSend(configParams)
×
146
  if (sourceEvent != null) {
×
147
    liveConnect.push(sourceEvent);
×
148
  }
149
  return liveConnect;
×
150
}
151

152
function tryFireEvent() {
153
  if (!eventFired && liveConnect) {
×
154
    const eventDelay = liveConnect.config.fireEventDelay || DEFAULT_DELAY;
×
155
    setTimeout(() => {
×
156
      const instances = window.liQ_instances;
×
157
      instances.forEach(i => i.eventBus.once(EVENTS_TOPIC, setEventFiredFlag));
×
158
      if (!eventFired && liveConnect) {
×
159
        liveConnect.fire();
×
160
      }
161
    }, eventDelay);
162
  }
163
}
164

165
/** @type {Submodule} */
166
export const liveIntentIdSubmodule = {
1✔
167
  moduleMode: '$$LIVE_INTENT_MODULE_MODE$$',
168
  /**
169
   * Used to link submodule with config.
170
   * @type {string}
171
   */
172
  name: MODULE_NAME,
173
  gvlid: GVLID,
174
  setModuleMode(mode) {
175
    this.moduleMode = mode;
×
176
  },
177
  getInitializer() {
178
    return (liveConnectConfig, storage, calls) => LiveConnect(liveConnectConfig, storage, calls, this.moduleMode);
×
179
  },
180

181
  /**
182
   * Decode the stored id value for passing to bid requests.
183
   * Note that lipb object is a wrapper for everything, and
184
   * internally it could contain more data other than `lipbid`
185
   * (e.g. `segments`) depending on the `partner` and `publisherId`
186
   * params.
187
   * @function
188
   * @param {{unifiedId:string}} value
189
   * @param {SubmoduleConfig|undefined} config
190
   * @returns {{lipb:Object}}
191
   */
192
  decode(value, config) {
193
    const configParams = (config && config.params) || {};
×
194
    setUpTreatment(configParams);
×
195

196
    if (!liveConnect) {
×
197
      initializeLiveConnect(configParams);
×
198
    }
199
    tryFireEvent();
×
200

201
    return composeResult(value, configParams);
×
202
  },
203

204
  /**
205
   * Performs action to obtain id and return a value in the callback's response argument.
206
   * @function
207
   * @param {SubmoduleConfig} [config]
208
   * @returns {IdResponse|undefined}
209
   */
210
  getId(config) {
211
    const configParams = (config && config.params) || {};
×
212
    setUpTreatment(configParams);
×
213

214
    const liveConnect = initializeLiveConnect(configParams);
×
215
    if (!liveConnect) {
×
216
      return;
×
217
    }
218
    tryFireEvent();
×
219
    const result = function(callback) {
×
220
      liveConnect.resolve(
×
221
        response => {
222
          callback(response);
×
223
        },
224
        error => {
225
          logError(`${MODULE_NAME}: ID fetch encountered an error: `, error);
×
226
          callback();
×
227
        }
228
      )
229
    }
230

231
    return { callback: result };
×
232
  },
233
  primaryIds: PRIMARY_IDS,
234
  eids
235
};
236

237
submodule('userId', liveIntentIdSubmodule);
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc