prebid.js 8.0.0 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.devcontainer/devcontainer.json +3 -1
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/33acrossIdSystem.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/admanBidAdapter.js +1 -1
- package/dist/adqueryBidAdapter.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/adyoulikeBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/bedigitechBidAdapter.js +1 -1
- package/dist/beopBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/bidwatchAnalyticsAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bridBidAdapter.js +1 -0
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/categoryTranslation.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/cmp.js +1 -0
- package/dist/colossussspBidAdapter.js +1 -1
- package/dist/conceptxBidAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consentManagement.js +1 -1
- package/dist/consentManagementGpp.js +1 -1
- package/dist/consentManagementUsp.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantAnalyticsAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/cwireBidAdapter.js +1 -1
- package/dist/dependencies.json +15 -0
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/euidIdSystem.js +1 -1
- package/dist/feedadBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/freepassBidAdapter.js +1 -0
- package/dist/freewheel-sspBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/gppControl_usnat.js +1 -0
- package/dist/greenbidsAnalyticsAdapter.js +1 -1
- package/dist/greenbidsRtdProvider.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/hypelabBidAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/imdsBidAdapter.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/intentIqIdSystem.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/kargoBidAdapter.js +1 -1
- package/dist/kiviadsBidAdapter.js +1 -0
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.js +1 -1
- package/dist/kulturemediaBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveIntentIdSystem.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/magniteAnalyticsAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/mgidXBidAdapter.js +1 -0
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/minutemediaplusBidAdapter.js +1 -1
- package/dist/mspa.js +1 -0
- package/dist/nexx360BidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +146 -139
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/optidigitalBidAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/oxxionAnalyticsAdapter.js +1 -1
- package/dist/oxxionRtdProvider.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/retailspotBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rtbhouseBidAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/shinezBidAdapter.js +1 -1
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/stvBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/uid2IdSystem.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/userId.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/libraries/cmp/cmpClient.js +139 -0
- package/libraries/mspa/activityControls.js +91 -0
- package/modules/admanBidAdapter.js +5 -0
- package/modules/amxBidAdapter.js +11 -12
- package/modules/bedigitechBidAdapter.js +15 -12
- package/modules/bedigitechBidAdapter.md +2 -2
- package/modules/beopBidAdapter.js +0 -4
- package/modules/bidwatchAnalyticsAdapter.js +33 -5
- package/modules/bridBidAdapter.js +223 -0
- package/modules/categoryTranslation.js +3 -2
- package/modules/colossussspBidAdapter.js +9 -0
- package/modules/conceptxBidAdapter.js +6 -3
- package/modules/consentManagement.js +12 -86
- package/modules/consentManagementGpp.js +47 -126
- package/modules/consentManagementUsp.js +19 -97
- package/modules/freepassBidAdapter.js +98 -0
- package/modules/freepassBidAdapter.md +31 -0
- package/modules/freepassIdSystem.md +1 -1
- package/modules/gppControl_usnat.js +11 -0
- package/modules/greenbidsAnalyticsAdapter.js +7 -13
- package/modules/gridBidAdapter.js +3 -4
- package/modules/intentIqIdSystem.js +11 -9
- package/modules/ixBidAdapter.js +284 -55
- package/modules/kiviadsBidAdapter.js +212 -0
- package/modules/kiviadsBidAdapter.md +79 -0
- package/modules/liveIntentIdSystem.js +8 -3
- package/modules/mediasquareBidAdapter.js +19 -23
- package/modules/mgidXBidAdapter.js +263 -0
- package/modules/mgidXBidAdapter.md +79 -0
- package/modules/oxxionAnalyticsAdapter.js +33 -5
- package/modules/oxxionRtdProvider.js +124 -11
- package/modules/oxxionRtdProvider.md +19 -4
- package/modules/pubmaticBidAdapter.js +18 -2
- package/modules/rtbhouseBidAdapter.js +9 -2
- package/modules/rtbhouseBidAdapter.md +27 -8
- package/modules/rubiconBidAdapter.js +13 -1
- package/modules/sharethroughBidAdapter.js +14 -0
- package/modules/sonobiBidAdapter.js +4 -7
- package/modules/tripleliftBidAdapter.js +21 -1
- package/modules/userId/eids.js +29 -0
- package/modules/userId/eids.md +19 -2
- package/modules/userId/index.js +78 -29
- package/modules/userId/userId.md +3 -0
- package/package.json +1 -1
- package/src/activities/params.js +4 -1
- package/test/spec/libraries/cmp/cmpClient_spec.js +233 -0
- package/test/spec/libraries/mspa/activityControls_spec.js +315 -0
- package/test/spec/modules/admanBidAdapter_spec.js +8 -2
- package/test/spec/modules/adqueryBidAdapter_spec.js +5 -1
- package/test/spec/modules/amxBidAdapter_spec.js +6 -3
- package/test/spec/modules/bedigitechBidAdapter_spec.js +25 -36
- package/test/spec/modules/bidwatchAnalyticsAdapter_spec.js +21 -1
- package/test/spec/modules/bridBidAdapter_spec.js +129 -0
- package/test/spec/modules/byDataAnalyticsAdapter_spec.js +9 -7
- package/test/spec/modules/chtnwBidAdapter_spec.js +4 -1
- package/test/spec/modules/colossussspBidAdapter_spec.js +29 -0
- package/test/spec/modules/consentManagementGpp_spec.js +84 -7
- package/test/spec/modules/consentManagement_spec.js +8 -18
- package/test/spec/modules/datablocksBidAdapter_spec.js +7 -3
- package/test/spec/modules/eids_spec.js +87 -0
- package/test/spec/modules/freepassBidAdapter_spec.js +161 -0
- package/test/spec/modules/greenbidsAnalyticsAdapter_spec.js +0 -15
- package/test/spec/modules/gridBidAdapter_spec.js +29 -28
- package/test/spec/modules/insticatorBidAdapter_spec.js +6 -2
- package/test/spec/modules/intentIqIdSystem_spec.js +36 -2
- package/test/spec/modules/ixBidAdapter_spec.js +785 -15
- package/test/spec/modules/kiviadsBidAdapter_spec.js +404 -0
- package/test/spec/modules/lassoBidAdapter_spec.js +6 -4
- package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +17 -2
- package/test/spec/modules/liveIntentIdSystem_spec.js +11 -6
- package/test/spec/modules/mediasquareBidAdapter_spec.js +3 -0
- package/test/spec/modules/mgidXBidAdapter_spec.js +426 -0
- package/test/spec/modules/onetagBidAdapter_spec.js +81 -75
- package/test/spec/modules/orbidderBidAdapter_spec.js +6 -3
- package/test/spec/modules/oxxionAnalyticsAdapter_spec.js +21 -2
- package/test/spec/modules/oxxionRtdProvider_spec.js +113 -1
- package/test/spec/modules/pubmaticBidAdapter_spec.js +25 -0
- package/test/spec/modules/relaidoBidAdapter_spec.js +4 -3
- package/test/spec/modules/rtbhouseBidAdapter_spec.js +35 -0
- package/test/spec/modules/rubiconBidAdapter_spec.js +41 -0
- package/test/spec/modules/sharethroughBidAdapter_spec.js +75 -0
- package/test/spec/modules/sonobiBidAdapter_spec.js +15 -15
- package/test/spec/modules/tripleliftBidAdapter_spec.js +20 -1
- package/test/spec/modules/ucfunnelBidAdapter_spec.js +37 -16
- package/test/spec/modules/userId_spec.js +393 -6
package/modules/userId/index.js
CHANGED
|
@@ -130,7 +130,7 @@ import {find, includes} from '../../src/polyfill.js';
|
|
|
130
130
|
import {config} from '../../src/config.js';
|
|
131
131
|
import * as events from '../../src/events.js';
|
|
132
132
|
import {getGlobal} from '../../src/prebidGlobal.js';
|
|
133
|
-
import adapterManager, {gdprDataHandler} from '../../src/adapterManager.js';
|
|
133
|
+
import adapterManager, {gdprDataHandler, gppDataHandler} from '../../src/adapterManager.js';
|
|
134
134
|
import CONSTANTS from '../../src/constants.json';
|
|
135
135
|
import {module, ready as hooksReady} from '../../src/hook.js';
|
|
136
136
|
import {buildEidPermissions, createEidsArray, USER_IDS_CONFIG} from './eids.js';
|
|
@@ -195,6 +195,9 @@ let initializedSubmodules;
|
|
|
195
195
|
/** @type {SubmoduleConfig[]} */
|
|
196
196
|
let configRegistry = [];
|
|
197
197
|
|
|
198
|
+
/** @type {Object} */
|
|
199
|
+
let idPriority = {};
|
|
200
|
+
|
|
198
201
|
/** @type {Submodule[]} */
|
|
199
202
|
let submoduleRegistry = [];
|
|
200
203
|
|
|
@@ -406,7 +409,7 @@ function storedConsentDataMatchesConsentData(storedConsentData, consentData) {
|
|
|
406
409
|
* @param {SubmoduleContainer[]} submodules
|
|
407
410
|
* @param {function} cb - callback for after processing is done.
|
|
408
411
|
*/
|
|
409
|
-
function processSubmoduleCallbacks(submodules, cb) {
|
|
412
|
+
function processSubmoduleCallbacks(submodules, cb, allModules) {
|
|
410
413
|
cb = uidMetrics().fork().startTiming('userId.callbacks.total').stopBefore(cb);
|
|
411
414
|
const done = delayExecution(() => {
|
|
412
415
|
clearTimeout(timeoutID);
|
|
@@ -422,7 +425,7 @@ function processSubmoduleCallbacks(submodules, cb) {
|
|
|
422
425
|
}
|
|
423
426
|
// cache decoded value (this is copied to every adUnit bid)
|
|
424
427
|
submodule.idObj = submodule.submodule.decode(idObj, submodule.config);
|
|
425
|
-
updatePPID(
|
|
428
|
+
updatePPID(getCombinedSubmoduleIds(allModules));
|
|
426
429
|
} else {
|
|
427
430
|
logInfo(`${MODULE_NAME}: ${submodule.submodule.name} - request id responded with an empty value`);
|
|
428
431
|
}
|
|
@@ -447,14 +450,7 @@ function getCombinedSubmoduleIds(submodules) {
|
|
|
447
450
|
if (!Array.isArray(submodules) || !submodules.length) {
|
|
448
451
|
return {};
|
|
449
452
|
}
|
|
450
|
-
|
|
451
|
-
Object.keys(i.idObj).forEach(key => {
|
|
452
|
-
carry[key] = i.idObj[key];
|
|
453
|
-
});
|
|
454
|
-
return carry;
|
|
455
|
-
}, {});
|
|
456
|
-
|
|
457
|
-
return combinedSubmoduleIds;
|
|
453
|
+
return getPrioritizedCombinedSubmoduleIds(submodules)
|
|
458
454
|
}
|
|
459
455
|
|
|
460
456
|
/**
|
|
@@ -466,9 +462,14 @@ function getSubmoduleId(submodules, sourceName) {
|
|
|
466
462
|
if (!Array.isArray(submodules) || !submodules.length) {
|
|
467
463
|
return {};
|
|
468
464
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
465
|
+
|
|
466
|
+
const prioritisedIds = getPrioritizedCombinedSubmoduleIds(submodules);
|
|
467
|
+
const eligibleIdName = Object.keys(prioritisedIds).find(idName => {
|
|
468
|
+
const config = USER_IDS_CONFIG[idName];
|
|
469
|
+
return config?.source === sourceName || (isFn(config?.getSource) && config.getSource() === sourceName);
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
return eligibleIdName ? {[eligibleIdName]: prioritisedIds[eligibleIdName]} : [];
|
|
472
473
|
}
|
|
473
474
|
|
|
474
475
|
/**
|
|
@@ -480,15 +481,38 @@ function getCombinedSubmoduleIdsForBidder(submodules, bidder) {
|
|
|
480
481
|
if (!Array.isArray(submodules) || !submodules.length || !bidder) {
|
|
481
482
|
return {};
|
|
482
483
|
}
|
|
483
|
-
|
|
484
|
+
const eligibleSubmodules = submodules
|
|
484
485
|
.filter(i => !i.config.bidders || !isArray(i.config.bidders) || includes(i.config.bidders, bidder))
|
|
486
|
+
|
|
487
|
+
return getPrioritizedCombinedSubmoduleIds(eligibleSubmodules);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* @param {SubmoduleContainer[]} submodules
|
|
492
|
+
*/
|
|
493
|
+
function getPrioritizedCombinedSubmoduleIds(submodules) {
|
|
494
|
+
const combinedIdStates = submodules
|
|
485
495
|
.filter(i => isPlainObject(i.idObj) && Object.keys(i.idObj).length)
|
|
486
496
|
.reduce((carry, i) => {
|
|
487
497
|
Object.keys(i.idObj).forEach(key => {
|
|
488
|
-
|
|
498
|
+
const maybeCurrentIdPriority = idPriority[key]?.indexOf(i.submodule.name);
|
|
499
|
+
const currentIdPriority = isNumber(maybeCurrentIdPriority) ? maybeCurrentIdPriority : -1;
|
|
500
|
+
const currentIdState = {priority: currentIdPriority, value: i.idObj[key]};
|
|
501
|
+
if (carry[key]) {
|
|
502
|
+
const winnerIdState = currentIdState.priority > carry[key].priority ? currentIdState : carry[key];
|
|
503
|
+
carry[key] = winnerIdState;
|
|
504
|
+
} else {
|
|
505
|
+
carry[key] = currentIdState;
|
|
506
|
+
}
|
|
489
507
|
});
|
|
490
508
|
return carry;
|
|
491
509
|
}, {});
|
|
510
|
+
|
|
511
|
+
const result = {};
|
|
512
|
+
Object.keys(combinedIdStates).forEach(key => {
|
|
513
|
+
result[key] = combinedIdStates[key].value
|
|
514
|
+
});
|
|
515
|
+
return result;
|
|
492
516
|
}
|
|
493
517
|
|
|
494
518
|
/**
|
|
@@ -550,10 +574,13 @@ function idSystemInitializer({delay = GreedyPromise.timeout} = {}) {
|
|
|
550
574
|
function timeGdpr() {
|
|
551
575
|
return gdprDataHandler.promise.finally(initMetrics.startTiming('userId.init.gdpr'));
|
|
552
576
|
}
|
|
577
|
+
function timeGpp() {
|
|
578
|
+
return gppDataHandler.promise.finally(initMetrics.startTiming('userId.init.gpp'))
|
|
579
|
+
}
|
|
553
580
|
|
|
554
581
|
let done = cancelAndTry(
|
|
555
582
|
GreedyPromise.all([hooksReady, startInit.promise])
|
|
556
|
-
.then(timeGdpr)
|
|
583
|
+
.then(() => GreedyPromise.all([timeGdpr(), timeGpp()]).then(([gdpr]) => gdpr))
|
|
557
584
|
.then(checkRefs((consentData) => {
|
|
558
585
|
initSubmodules(initModules, allModules, consentData);
|
|
559
586
|
}))
|
|
@@ -561,7 +588,7 @@ function idSystemInitializer({delay = GreedyPromise.timeout} = {}) {
|
|
|
561
588
|
.then(checkRefs(() => {
|
|
562
589
|
const modWithCb = initModules.filter(item => isFn(item.callback));
|
|
563
590
|
if (modWithCb.length) {
|
|
564
|
-
return new GreedyPromise((resolve) => processSubmoduleCallbacks(modWithCb, resolve));
|
|
591
|
+
return new GreedyPromise((resolve) => processSubmoduleCallbacks(modWithCb, resolve, initModules));
|
|
565
592
|
}
|
|
566
593
|
}))
|
|
567
594
|
);
|
|
@@ -600,7 +627,7 @@ function idSystemInitializer({delay = GreedyPromise.timeout} = {}) {
|
|
|
600
627
|
return sm.callback != null;
|
|
601
628
|
});
|
|
602
629
|
if (cbModules.length) {
|
|
603
|
-
return new GreedyPromise((resolve) => processSubmoduleCallbacks(cbModules, resolve));
|
|
630
|
+
return new GreedyPromise((resolve) => processSubmoduleCallbacks(cbModules, resolve, initModules));
|
|
604
631
|
}
|
|
605
632
|
}))
|
|
606
633
|
);
|
|
@@ -783,7 +810,7 @@ function getUserIdsAsync() {
|
|
|
783
810
|
);
|
|
784
811
|
}
|
|
785
812
|
|
|
786
|
-
function populateSubmoduleId(submodule, consentData, storedConsentData, forceRefresh) {
|
|
813
|
+
function populateSubmoduleId(submodule, consentData, storedConsentData, forceRefresh, allSubmodules) {
|
|
787
814
|
// There are two submodule configuration types to handle: storage or value
|
|
788
815
|
// 1. storage: retrieve user id data from cookie/html storage or with the submodule's getId method
|
|
789
816
|
// 2. value: pass directly to bids
|
|
@@ -832,7 +859,7 @@ function populateSubmoduleId(submodule, consentData, storedConsentData, forceRef
|
|
|
832
859
|
if (response.id) { submodule.idObj = submodule.submodule.decode(response.id, submodule.config); }
|
|
833
860
|
}
|
|
834
861
|
}
|
|
835
|
-
updatePPID(
|
|
862
|
+
updatePPID(getCombinedSubmoduleIds(allSubmodules));
|
|
836
863
|
}
|
|
837
864
|
|
|
838
865
|
function updatePPID(userIds = getUserIds()) {
|
|
@@ -879,7 +906,7 @@ function initSubmodules(dest, submodules, consentData, forceRefresh = false) {
|
|
|
879
906
|
const initialized = submodules.reduce((carry, submodule) => {
|
|
880
907
|
return submoduleMetrics(submodule.submodule.name).measureTime('init', () => {
|
|
881
908
|
try {
|
|
882
|
-
populateSubmoduleId(submodule, consentData, storedConsentData, forceRefresh);
|
|
909
|
+
populateSubmoduleId(submodule, consentData, storedConsentData, forceRefresh, submodules);
|
|
883
910
|
carry.push(submodule);
|
|
884
911
|
} catch (e) {
|
|
885
912
|
logError(`Error in userID module '${submodule.submodule.name}':`, e);
|
|
@@ -1010,6 +1037,25 @@ function updateSubmodules() {
|
|
|
1010
1037
|
}
|
|
1011
1038
|
}
|
|
1012
1039
|
|
|
1040
|
+
/**
|
|
1041
|
+
* This function will update the idPriority according to the provided configuration
|
|
1042
|
+
* @param {Object} idPriorityConfig
|
|
1043
|
+
* @param {SubmoduleContainer[]} submodules
|
|
1044
|
+
*/
|
|
1045
|
+
function updateIdPriority(idPriorityConfig, submodules) {
|
|
1046
|
+
if (idPriorityConfig) {
|
|
1047
|
+
const result = {};
|
|
1048
|
+
const aliasToName = new Map(submodules.map(s => s.submodule.aliasName ? [s.submodule.aliasName, s.submodule.name] : []));
|
|
1049
|
+
Object.keys(idPriorityConfig).forEach(key => {
|
|
1050
|
+
const priority = isArray(idPriorityConfig[key]) ? [...idPriorityConfig[key]].reverse() : []
|
|
1051
|
+
result[key] = priority.map(s => aliasToName.has(s) ? aliasToName.get(s) : s);
|
|
1052
|
+
});
|
|
1053
|
+
idPriority = result;
|
|
1054
|
+
} else {
|
|
1055
|
+
idPriority = {};
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1013
1059
|
export function requestDataDeletion(next, ...args) {
|
|
1014
1060
|
logInfo('UserID: received data deletion request; deleting all stored IDs...')
|
|
1015
1061
|
submodules.forEach(submodule => {
|
|
@@ -1069,13 +1115,16 @@ export function init(config, {delay = GreedyPromise.timeout} = {}) {
|
|
|
1069
1115
|
configListener = config.getConfig('userSync', conf => {
|
|
1070
1116
|
// Note: support for 'usersync' was dropped as part of Prebid.js 4.0
|
|
1071
1117
|
const userSync = conf.userSync;
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1118
|
+
if (userSync) {
|
|
1119
|
+
ppidSource = userSync.ppid;
|
|
1120
|
+
if (userSync.userIds) {
|
|
1121
|
+
configRegistry = userSync.userIds;
|
|
1122
|
+
syncDelay = isNumber(userSync.syncDelay) ? userSync.syncDelay : DEFAULT_SYNC_DELAY;
|
|
1123
|
+
auctionDelay = isNumber(userSync.auctionDelay) ? userSync.auctionDelay : NO_AUCTION_DELAY;
|
|
1124
|
+
updateSubmodules();
|
|
1125
|
+
updateIdPriority(userSync.idPriority, submodules);
|
|
1126
|
+
initIdSystem({ready: true});
|
|
1127
|
+
}
|
|
1079
1128
|
}
|
|
1080
1129
|
});
|
|
1081
1130
|
|
package/modules/userId/userId.md
CHANGED
package/package.json
CHANGED
package/src/activities/params.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {MODULE_TYPE_BIDDER} from './modules.js';
|
|
2
|
+
import {hook} from '../hook.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Component ID - who is trying to perform the activity?
|
|
@@ -54,6 +55,8 @@ export function activityParamsBuilder(resolveAlias) {
|
|
|
54
55
|
if (moduleType === MODULE_TYPE_BIDDER) {
|
|
55
56
|
defaults[ACTIVITY_PARAM_ADAPTER_CODE] = resolveAlias(moduleName);
|
|
56
57
|
}
|
|
57
|
-
return Object.assign(defaults, params);
|
|
58
|
+
return buildActivityParams(Object.assign(defaults, params));
|
|
58
59
|
}
|
|
59
60
|
}
|
|
61
|
+
|
|
62
|
+
export const buildActivityParams = hook('sync', params => params);
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import {cmpClient} from '../../../../libraries/cmp/cmpClient.js';
|
|
2
|
+
|
|
3
|
+
describe('cmpClient', () => {
|
|
4
|
+
function mockWindow(props = {}) {
|
|
5
|
+
let listeners = [];
|
|
6
|
+
const win = {
|
|
7
|
+
addEventListener: sinon.stub().callsFake((evt, listener) => {
|
|
8
|
+
evt === 'message' && listeners.push(listener)
|
|
9
|
+
}),
|
|
10
|
+
postMessage: sinon.stub().callsFake((msg) => {
|
|
11
|
+
listeners.forEach(ln => ln({data: msg}))
|
|
12
|
+
}),
|
|
13
|
+
...props,
|
|
14
|
+
};
|
|
15
|
+
win.top = win.parent?.top || win;
|
|
16
|
+
return win;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
it('should return undefined when there is no CMP', () => {
|
|
20
|
+
expect(cmpClient({apiName: 'missing'}, mockWindow())).to.not.exist;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should return undefined when parent is inaccessible', () => {
|
|
24
|
+
const win = mockWindow();
|
|
25
|
+
win.top = mockWindow();
|
|
26
|
+
expect(cmpClient({apiName: 'missing'}, win)).to.not.exist;
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
describe('direct access', () => {
|
|
30
|
+
let mockApiFn;
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
mockApiFn = sinon.stub();
|
|
33
|
+
})
|
|
34
|
+
Object.entries({
|
|
35
|
+
'on same frame': () => mockWindow({mockApiFn}),
|
|
36
|
+
'on parent frame': () => mockWindow({parent: mockWindow({parent: mockWindow({parent: mockWindow(), mockApiFn})})}),
|
|
37
|
+
}).forEach(([t, mkWindow]) => {
|
|
38
|
+
describe(t, () => {
|
|
39
|
+
let win, mkClient;
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
win = mkWindow();
|
|
42
|
+
mkClient = (opts) => cmpClient(Object.assign({apiName: 'mockApiFn'}, opts), win)
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should mark client function as direct', () => {
|
|
46
|
+
expect(mkClient().isDirect).to.equal(true);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should find and call the CMP api function', () => {
|
|
50
|
+
mkClient()({command: 'mockCmd'});
|
|
51
|
+
sinon.assert.calledWith(mockApiFn, 'mockCmd');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe('should return a promise that', () => {
|
|
55
|
+
let cbResult;
|
|
56
|
+
beforeEach(() => {
|
|
57
|
+
cbResult = [];
|
|
58
|
+
mockApiFn.callsFake((cmd, callback) => {
|
|
59
|
+
if (typeof callback === 'function') {
|
|
60
|
+
callback.apply(this, cbResult);
|
|
61
|
+
}
|
|
62
|
+
return 'val'
|
|
63
|
+
})
|
|
64
|
+
})
|
|
65
|
+
Object.entries({
|
|
66
|
+
callback: [sinon.stub(), 'undefined', undefined],
|
|
67
|
+
'no callback': [undefined, 'api return value', 'val']
|
|
68
|
+
}).forEach(([t, [callback, tResult, expectedResult]]) => {
|
|
69
|
+
describe(`when ${t} is provided`, () => {
|
|
70
|
+
Object.entries({
|
|
71
|
+
'no success flag': undefined,
|
|
72
|
+
'success is set': true
|
|
73
|
+
}).forEach(([t, success]) => {
|
|
74
|
+
it(`resolves to ${tResult} (${t})`, (done) => {
|
|
75
|
+
cbResult = ['cbVal', success];
|
|
76
|
+
mkClient()({callback}).then((val) => {
|
|
77
|
+
expect(val).to.equal(expectedResult);
|
|
78
|
+
done();
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
});
|
|
82
|
+
})
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('rejects to undefined when callback is provided and success = false', () => {
|
|
86
|
+
cbResult = ['cbVal', false];
|
|
87
|
+
mkClient()({callback: sinon.stub()}).catch(val => {
|
|
88
|
+
expect(val).to.equal('cbVal');
|
|
89
|
+
done();
|
|
90
|
+
})
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('rejects when CMP api throws', (done) => {
|
|
94
|
+
mockApiFn.reset();
|
|
95
|
+
const e = new Error();
|
|
96
|
+
mockApiFn.throws(e);
|
|
97
|
+
mkClient()({}).catch(val => {
|
|
98
|
+
expect(val).to.equal(e);
|
|
99
|
+
done();
|
|
100
|
+
});
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it('should use apiArgs to choose and order the arguments to pass to the API fn', () => {
|
|
105
|
+
mkClient({apiArgs: ['parameter', 'command']})({
|
|
106
|
+
command: 'mockCmd',
|
|
107
|
+
parameter: 'mockParam',
|
|
108
|
+
callback() {}
|
|
109
|
+
});
|
|
110
|
+
sinon.assert.calledWith(mockApiFn, 'mockParam', 'mockCmd');
|
|
111
|
+
});
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
describe('postMessage access', () => {
|
|
117
|
+
let messenger, win, response;
|
|
118
|
+
beforeEach(() => {
|
|
119
|
+
response = {};
|
|
120
|
+
messenger = sinon.stub().callsFake((msg) => {
|
|
121
|
+
if (msg.mockApiCall) {
|
|
122
|
+
win.postMessage({mockApiReturn: {callId: msg.mockApiCall.callId, ...response}});
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
function mkClient(options) {
|
|
128
|
+
return cmpClient(Object.assign({apiName: 'mockApi'}, options), win);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
Object.entries({
|
|
132
|
+
'on same frame': () => {
|
|
133
|
+
win = mockWindow({frames: {mockApiLocator: true}});
|
|
134
|
+
win.addEventListener('message', (evt) => messenger(evt.data));
|
|
135
|
+
},
|
|
136
|
+
'on parent frame': () => {
|
|
137
|
+
win = mockWindow({parent: mockWindow({frames: {mockApiLocator: true}})})
|
|
138
|
+
win.parent.addEventListener('message', evt => messenger(evt.data))
|
|
139
|
+
}
|
|
140
|
+
}).forEach(([t, setup]) => {
|
|
141
|
+
describe(t, () => {
|
|
142
|
+
beforeEach(setup);
|
|
143
|
+
|
|
144
|
+
it('should mark client as not direct', () => {
|
|
145
|
+
expect(mkClient().isDirect).to.equal(false);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('should find and message the CMP frame', () => {
|
|
149
|
+
mkClient()({command: 'mockCmd', parameter: 'param'});
|
|
150
|
+
sinon.assert.calledWithMatch(messenger, {
|
|
151
|
+
mockApiCall: {
|
|
152
|
+
command: 'mockCmd',
|
|
153
|
+
parameter: 'param'
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('should use apiArgs to choose what to include in the message payload', () => {
|
|
159
|
+
mkClient({apiArgs: ['command']})({
|
|
160
|
+
command: 'cmd',
|
|
161
|
+
parameter: 'param'
|
|
162
|
+
});
|
|
163
|
+
sinon.assert.calledWithMatch(messenger, sinon.match((arg) => {
|
|
164
|
+
return arg.mockApiCall.command === 'cmd' &&
|
|
165
|
+
!arg.mockApiCall.hasOwnProperty('parameter');
|
|
166
|
+
}))
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('should not include callback in the payload, but still run it on response', () => {
|
|
170
|
+
const cb = sinon.stub();
|
|
171
|
+
mkClient({apiArgs: ['command', 'callback']})({
|
|
172
|
+
command: 'cmd',
|
|
173
|
+
callback: cb
|
|
174
|
+
});
|
|
175
|
+
sinon.assert.calledWithMatch(messenger, sinon.match(arg => !arg.mockApiCall.hasOwnProperty('callback')));
|
|
176
|
+
sinon.assert.called(cb);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('should use callbackArgs to decide what to pass to callback', () => {
|
|
180
|
+
const cb = sinon.stub();
|
|
181
|
+
response = {a: 'one', b: 'two'};
|
|
182
|
+
mkClient({callbackArgs: ['a', 'b']})({callback: cb});
|
|
183
|
+
sinon.assert.calledWith(cb, 'one', 'two');
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
describe('should return a promise that', () => {
|
|
187
|
+
beforeEach(() => {
|
|
188
|
+
response = {returnValue: 'val'}
|
|
189
|
+
})
|
|
190
|
+
Object.entries({
|
|
191
|
+
'callback': [sinon.stub(), 'undefined', undefined],
|
|
192
|
+
'no callback': [undefined, 'response returnValue', 'val'],
|
|
193
|
+
}).forEach(([t, [callback, tResult, expectedResult]]) => {
|
|
194
|
+
describe(`when ${t} is provided`, () => {
|
|
195
|
+
Object.entries({
|
|
196
|
+
'no success flag': {},
|
|
197
|
+
'with success flag': {success: true}
|
|
198
|
+
}).forEach(([t, resp]) => {
|
|
199
|
+
it(`resolves to ${tResult} (${t})`, () => {
|
|
200
|
+
Object.assign(response, resp);
|
|
201
|
+
mkClient()({callback}).then((val) => {
|
|
202
|
+
expect(val).to.equal(expectedResult);
|
|
203
|
+
})
|
|
204
|
+
})
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it(`rejects to ${tResult} when success = false`, (done) => {
|
|
208
|
+
response.success = false;
|
|
209
|
+
mkClient()({callback}).catch((err) => {
|
|
210
|
+
expect(err).to.equal(expectedResult);
|
|
211
|
+
done();
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
})
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it('should re-use callback for messages with same callId', () => {
|
|
219
|
+
messenger.reset();
|
|
220
|
+
let callId;
|
|
221
|
+
messenger.callsFake((msg) => { if (msg.mockApiCall) callId = msg.mockApiCall.callId });
|
|
222
|
+
const callback = sinon.stub();
|
|
223
|
+
mkClient()({callback});
|
|
224
|
+
expect(callId).to.exist;
|
|
225
|
+
win.postMessage({mockApiReturn: {callId, returnValue: 'a'}});
|
|
226
|
+
win.postMessage({mockApiReturn: {callId, returnValue: 'b'}});
|
|
227
|
+
sinon.assert.calledWith(callback, 'a');
|
|
228
|
+
sinon.assert.calledWith(callback, 'b');
|
|
229
|
+
})
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
});
|