prebid.js 7.29.0 → 7.30.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/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/adrelevantisBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.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/bidViewability.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/byDataAnalyticsAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/ccxBidAdapter.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/colossussspBidAdapter.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 -0
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/dfpAdServerVideo.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gridNMBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/inmarBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveyieldAnalyticsAdapter.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/minutemediaBidAdapter.js +1 -1
- package/dist/nexx360BidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +122 -120
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/prebidServerBidAdapter.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/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rtdModule.js +1 -1
- package/dist/rubiconAnalyticsAdapter.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/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.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/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/viouslyBidAdapter.js +1 -0
- 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/integrationExamples/gpt/gpp_us_hello_world.html +124 -0
- package/integrationExamples/gpt/gpp_us_hello_world_iframe.html +12 -0
- package/integrationExamples/gpt/gpp_us_hello_world_iframe_subpage.html +140 -0
- package/karma.conf.maker.js +1 -1
- package/modules/appnexusBidAdapter.js +23 -2
- package/modules/bidViewability.js +6 -1
- package/modules/ccxBidAdapter.js +3 -2
- package/modules/colossussspBidAdapter.js +8 -0
- package/modules/consentManagement.js +4 -4
- package/modules/consentManagementGpp.js +386 -0
- package/modules/dfpAdServerVideo.js +6 -1
- package/modules/gridBidAdapter.js +1 -2
- package/modules/lassoBidAdapter.js +2 -2
- package/modules/magniteAnalyticsAdapter.js +9 -1
- package/modules/onetagBidAdapter.js +20 -29
- package/modules/prebidServerBidAdapter/index.js +19 -8
- package/modules/rtdModule/index.js +2 -1
- package/modules/viouslyBidAdapter.js +209 -0
- package/modules/viouslyBidAdapter.md +35 -0
- package/package.json +1 -1
- package/src/adapterManager.js +11 -10
- package/src/adapters/bidderFactory.js +5 -5
- package/src/consentHandler.js +11 -0
- package/src/prebid.js +2 -1
- package/test/helpers/hookSetup.js +5 -0
- package/test/spec/modules/ViouslyBidAdapter_spec.js +378 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +46 -0
- package/test/spec/modules/colossussspBidAdapter_spec.js +89 -2
- package/test/spec/modules/consentManagementGpp_spec.js +577 -0
- package/test/spec/modules/gridBidAdapter_spec.js +0 -18
- package/test/spec/modules/magniteAnalyticsAdapter_spec.js +36 -14
- package/test/spec/modules/onetagBidAdapter_spec.js +29 -23
- package/test/spec/modules/topicsFpdModule_spec.js +41 -22
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This module adds GPP consentManagement support to prebid.js. It interacts with
|
|
3
|
+
* supported CMPs (Consent Management Platforms) to grab the user's consent information
|
|
4
|
+
* and make it available for any GPP supported adapters to read/pass this information to
|
|
5
|
+
* their system and for various other features/modules in Prebid.js.
|
|
6
|
+
*/
|
|
7
|
+
import {deepSetValue, isNumber, isPlainObject, isStr, logError, logInfo, logWarn} from '../src/utils.js';
|
|
8
|
+
import {config} from '../src/config.js';
|
|
9
|
+
import {gppDataHandler} from '../src/adapterManager.js';
|
|
10
|
+
import {includes} from '../src/polyfill.js';
|
|
11
|
+
import {timedAuctionHook} from '../src/utils/perfMetrics.js';
|
|
12
|
+
import { enrichFPD } from '../src/fpd/enrichment.js';
|
|
13
|
+
|
|
14
|
+
const DEFAULT_CMP = 'iab';
|
|
15
|
+
const DEFAULT_CONSENT_TIMEOUT = 10000;
|
|
16
|
+
const CMP_VERSION = 1;
|
|
17
|
+
|
|
18
|
+
export let userCMP;
|
|
19
|
+
export let consentTimeout;
|
|
20
|
+
export let staticConsentData;
|
|
21
|
+
|
|
22
|
+
let consentData;
|
|
23
|
+
let addedConsentHook = false;
|
|
24
|
+
|
|
25
|
+
// add new CMPs here, with their dedicated lookup function
|
|
26
|
+
const cmpCallMap = {
|
|
27
|
+
'iab': lookupIabConsent,
|
|
28
|
+
'static': lookupStaticConsentData
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* This function checks the state of the IAB gppData's applicableSection field (to ensure it's populated and has a valid value).
|
|
33
|
+
* section === 0 represents a CMP's default value when CMP is loading, it shoud not be used a real user's section.
|
|
34
|
+
*
|
|
35
|
+
* TODO --- The initial version of the GPP CMP API spec used this naming convention, but it was later changed as an update to the spec.
|
|
36
|
+
* CMPs should adjust their logic to use the new format (applicableSecctions), but that may not be the case with the initial release.
|
|
37
|
+
* Added support just in case for this transition period, can likely be removed at a later date...
|
|
38
|
+
* @param gppData represents the IAB gppData object
|
|
39
|
+
* @returns true|false
|
|
40
|
+
*/
|
|
41
|
+
function checkApplicableSectionIsReady(gppData) {
|
|
42
|
+
return gppData && Array.isArray(gppData.applicableSection) && gppData.applicableSection.length > 0 && gppData.applicableSection[0] !== 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* This function checks the state of the IAB gppData's applicableSections field (to ensure it's populated and has a valid value).
|
|
47
|
+
* section === 0 represents a CMP's default value when CMP is loading, it shoud not be used a real user's section.
|
|
48
|
+
* @param gppData represents the IAB gppData object
|
|
49
|
+
* @returns true|false
|
|
50
|
+
*/
|
|
51
|
+
function checkApplicableSectionsIsReady(gppData) {
|
|
52
|
+
return gppData && Array.isArray(gppData.applicableSections) && gppData.applicableSections.length > 0 && gppData.applicableSections[0] !== 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* This function reads the consent string from the config to obtain the consent information of the user.
|
|
57
|
+
* @param {function({})} onSuccess acts as a success callback when the value is read from config; pass along consentObject from CMP
|
|
58
|
+
*/
|
|
59
|
+
function lookupStaticConsentData({onSuccess, onError}) {
|
|
60
|
+
processCmpData(staticConsentData, {onSuccess, onError});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* This function handles interacting with an IAB compliant CMP to obtain the consent information of the user.
|
|
65
|
+
* Given the async nature of the CMP's API, we pass in acting success/error callback functions to exit this function
|
|
66
|
+
* based on the appropriate result.
|
|
67
|
+
* @param {function({})} onSuccess acts as a success callback when CMP returns a value; pass along consentObjectfrom CMP
|
|
68
|
+
* @param {function(string, ...{}?)} cmpError acts as an error callback while interacting with CMP; pass along an error message (string) and any extra error arguments (purely for logging)
|
|
69
|
+
*/
|
|
70
|
+
function lookupIabConsent({onSuccess, onError}) {
|
|
71
|
+
const cmpApiName = '__gpp';
|
|
72
|
+
const cmpCallbacks = {};
|
|
73
|
+
let registeredPostMessageResponseListener = false;
|
|
74
|
+
|
|
75
|
+
function findCMP() {
|
|
76
|
+
let f = window;
|
|
77
|
+
let cmpFrame;
|
|
78
|
+
let cmpDirectAccess = false;
|
|
79
|
+
while (true) {
|
|
80
|
+
try {
|
|
81
|
+
if (typeof f[cmpApiName] === 'function') {
|
|
82
|
+
cmpFrame = f;
|
|
83
|
+
cmpDirectAccess = true;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
} catch (e) {}
|
|
87
|
+
|
|
88
|
+
// need separate try/catch blocks due to the exception errors thrown when trying to check for a frame that doesn't exist in 3rd party env
|
|
89
|
+
try {
|
|
90
|
+
if (f.frames['__gppLocator']) {
|
|
91
|
+
cmpFrame = f;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
} catch (e) {}
|
|
95
|
+
|
|
96
|
+
if (f === window.top) break;
|
|
97
|
+
f = f.parent;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
cmpFrame,
|
|
102
|
+
cmpDirectAccess
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const {cmpFrame, cmpDirectAccess} = findCMP();
|
|
107
|
+
|
|
108
|
+
if (!cmpFrame) {
|
|
109
|
+
return onError('GPP CMP not found.');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const invokeCMP = (cmpDirectAccess) ? invokeCMPDirect : invokeCMPFrame;
|
|
113
|
+
|
|
114
|
+
function invokeCMPDirect({command, callback, parameter, version = CMP_VERSION}, resultCb) {
|
|
115
|
+
if (typeof resultCb === 'function') {
|
|
116
|
+
resultCb(cmpFrame[cmpApiName](command, callback, parameter, version));
|
|
117
|
+
} else {
|
|
118
|
+
cmpFrame[cmpApiName](command, callback, parameter, version);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function invokeCMPFrame({command, callback, parameter, version = CMP_VERSION}, resultCb) {
|
|
123
|
+
const callName = `${cmpApiName}Call`;
|
|
124
|
+
if (!registeredPostMessageResponseListener) {
|
|
125
|
+
// when we get the return message, call the stashed callback;
|
|
126
|
+
window.addEventListener('message', readPostMessageResponse, false);
|
|
127
|
+
registeredPostMessageResponseListener = true;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// call CMP via postMessage
|
|
131
|
+
const callId = Math.random().toString();
|
|
132
|
+
const msg = {
|
|
133
|
+
[callName]: {
|
|
134
|
+
command: command,
|
|
135
|
+
parameter,
|
|
136
|
+
version,
|
|
137
|
+
callId: callId
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
// TODO? - add logic to check if random was already used in the same session, and roll another if so?
|
|
142
|
+
cmpCallbacks[callId] = (typeof callback === 'function') ? callback : resultCb;
|
|
143
|
+
cmpFrame.postMessage(msg, '*');
|
|
144
|
+
|
|
145
|
+
function readPostMessageResponse(event) {
|
|
146
|
+
const cmpDataPkgName = `${cmpApiName}Return`;
|
|
147
|
+
const json = (typeof event.data === 'string' && event.data.includes(cmpDataPkgName)) ? JSON.parse(event.data) : event.data;
|
|
148
|
+
if (json[cmpDataPkgName] && json[cmpDataPkgName].callId) {
|
|
149
|
+
const payload = json[cmpDataPkgName];
|
|
150
|
+
|
|
151
|
+
if (cmpCallbacks.hasOwnProperty(payload.callId)) {
|
|
152
|
+
cmpCallbacks[payload.callId](payload.returnValue);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const startupMsg = (cmpDirectAccess) ? 'Detected GPP CMP API is directly accessible, calling it now...'
|
|
159
|
+
: 'Detected GPP CMP is outside the current iframe where Prebid.js is located, calling it now...';
|
|
160
|
+
logInfo(startupMsg);
|
|
161
|
+
|
|
162
|
+
invokeCMP({
|
|
163
|
+
command: 'addEventListener',
|
|
164
|
+
callback: function (evt) {
|
|
165
|
+
if (evt) {
|
|
166
|
+
logInfo(`Received a ${(cmpDirectAccess ? 'direct' : 'postmsg')} response from GPP CMP for event`, evt);
|
|
167
|
+
if (evt.eventName === 'sectionChange' || evt.pingData.cmpStatus === 'loaded') {
|
|
168
|
+
invokeCMP({command: 'getGPPData'}, function (gppData) {
|
|
169
|
+
logInfo(`Received a ${cmpDirectAccess ? 'direct' : 'postmsg'} response from GPP CMP for getGPPData`, gppData);
|
|
170
|
+
processCmpData(gppData, {onSuccess, onError});
|
|
171
|
+
});
|
|
172
|
+
} else if (evt.pingData.cmpStatus === 'error') {
|
|
173
|
+
onError('CMP returned with a cmpStatus:error response. Please check CMP setup.');
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Look up consent data and store it in the `consentData` global as well as `adapterManager.js`' gdprDataHandler.
|
|
182
|
+
*
|
|
183
|
+
* @param cb A callback that takes: a boolean that is true if the auction should be canceled; an error message and extra
|
|
184
|
+
* error arguments that will be undefined if there's no error.
|
|
185
|
+
*/
|
|
186
|
+
function loadConsentData(cb) {
|
|
187
|
+
let isDone = false;
|
|
188
|
+
let timer = null;
|
|
189
|
+
|
|
190
|
+
function done(consentData, shouldCancelAuction, errMsg, ...extraArgs) {
|
|
191
|
+
if (timer != null) {
|
|
192
|
+
clearTimeout(timer);
|
|
193
|
+
}
|
|
194
|
+
isDone = true;
|
|
195
|
+
gppDataHandler.setConsentData(consentData);
|
|
196
|
+
if (typeof cb === 'function') {
|
|
197
|
+
cb(shouldCancelAuction, errMsg, ...extraArgs);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (!includes(Object.keys(cmpCallMap), userCMP)) {
|
|
202
|
+
done(null, false, `GPP CMP framework (${userCMP}) is not a supported framework. Aborting consentManagement module and resuming auction.`);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const callbacks = {
|
|
207
|
+
onSuccess: (data) => done(data, false),
|
|
208
|
+
onError: function (msg, ...extraArgs) {
|
|
209
|
+
done(null, true, msg, ...extraArgs);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
cmpCallMap[userCMP](callbacks);
|
|
213
|
+
|
|
214
|
+
if (!isDone) {
|
|
215
|
+
const onTimeout = () => {
|
|
216
|
+
const continueToAuction = (data) => {
|
|
217
|
+
done(data, false, 'GPP CMP did not load, continuing auction...');
|
|
218
|
+
}
|
|
219
|
+
processCmpData(consentData, {
|
|
220
|
+
onSuccess: continueToAuction,
|
|
221
|
+
onError: () => continueToAuction(storeConsentData(undefined))
|
|
222
|
+
})
|
|
223
|
+
}
|
|
224
|
+
if (consentTimeout === 0) {
|
|
225
|
+
onTimeout();
|
|
226
|
+
} else {
|
|
227
|
+
timer = setTimeout(onTimeout, consentTimeout);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Like `loadConsentData`, but cache and re-use previously loaded data.
|
|
234
|
+
* @param cb
|
|
235
|
+
*/
|
|
236
|
+
function loadIfMissing(cb) {
|
|
237
|
+
if (consentData) {
|
|
238
|
+
logInfo('User consent information already known. Pulling internally stored information...');
|
|
239
|
+
// eslint-disable-next-line standard/no-callback-literal
|
|
240
|
+
cb(false);
|
|
241
|
+
} else {
|
|
242
|
+
loadConsentData(cb);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* If consentManagement module is enabled (ie included in setConfig), this hook function will attempt to fetch the
|
|
248
|
+
* user's encoded consent string from the supported CMP. Once obtained, the module will store this
|
|
249
|
+
* data as part of a gppConsent object which gets transferred to adapterManager's gppDataHandler object.
|
|
250
|
+
* This information is later added into the bidRequest object for any supported adapters to read/pass along to their system.
|
|
251
|
+
* @param {object} reqBidsConfigObj required; This is the same param that's used in pbjs.requestBids.
|
|
252
|
+
* @param {function} fn required; The next function in the chain, used by hook.js
|
|
253
|
+
*/
|
|
254
|
+
export const requestBidsHook = timedAuctionHook('gpp', function requestBidsHook(fn, reqBidsConfigObj) {
|
|
255
|
+
loadIfMissing(function (shouldCancelAuction, errMsg, ...extraArgs) {
|
|
256
|
+
if (errMsg) {
|
|
257
|
+
let log = logWarn;
|
|
258
|
+
if (shouldCancelAuction) {
|
|
259
|
+
log = logError;
|
|
260
|
+
errMsg = `${errMsg} Canceling auction as per consentManagement config.`;
|
|
261
|
+
}
|
|
262
|
+
log(errMsg, ...extraArgs);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (shouldCancelAuction) {
|
|
266
|
+
fn.stopTiming();
|
|
267
|
+
if (typeof reqBidsConfigObj.bidsBackHandler === 'function') {
|
|
268
|
+
reqBidsConfigObj.bidsBackHandler();
|
|
269
|
+
} else {
|
|
270
|
+
logError('Error executing bidsBackHandler');
|
|
271
|
+
}
|
|
272
|
+
} else {
|
|
273
|
+
fn.call(this, reqBidsConfigObj);
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* This function checks the consent data provided by CMP to ensure it's in an expected state.
|
|
280
|
+
* If it's bad, we call `onError`
|
|
281
|
+
* If it's good, then we store the value and call `onSuccess`
|
|
282
|
+
*/
|
|
283
|
+
function processCmpData(consentObject, {onSuccess, onError}) {
|
|
284
|
+
function checkData() {
|
|
285
|
+
const gppString = consentObject && consentObject.gppString;
|
|
286
|
+
const gppSection = (checkApplicableSectionsIsReady(consentObject)) ? consentObject.applicableSections
|
|
287
|
+
: (checkApplicableSectionIsReady(consentObject)) ? consentObject.applicableSection : [];
|
|
288
|
+
|
|
289
|
+
return !!(
|
|
290
|
+
(!Array.isArray(gppSection)) ||
|
|
291
|
+
(Array.isArray(gppSection) && (!gppString || !isStr(gppString)))
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (checkData()) {
|
|
296
|
+
onError(`CMP returned unexpected value during lookup process.`, consentObject);
|
|
297
|
+
} else {
|
|
298
|
+
onSuccess(storeConsentData(consentObject));
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Stores CMP data locally in module to make information available in adaptermanager.js for later in the auction
|
|
304
|
+
* @param {object} cmpConsentObject required; an object representing user's consent choices (can be undefined in certain use-cases for this function only)
|
|
305
|
+
*/
|
|
306
|
+
function storeConsentData(cmpConsentObject) {
|
|
307
|
+
consentData = {
|
|
308
|
+
gppString: (cmpConsentObject) ? cmpConsentObject.gppString : undefined,
|
|
309
|
+
|
|
310
|
+
fullGppData: (cmpConsentObject) || undefined,
|
|
311
|
+
};
|
|
312
|
+
consentData.applicableSections = (checkApplicableSectionsIsReady(cmpConsentObject)) ? cmpConsentObject.applicableSections
|
|
313
|
+
: (checkApplicableSectionIsReady(cmpConsentObject)) ? cmpConsentObject.applicableSection : [];
|
|
314
|
+
consentData.apiVersion = CMP_VERSION;
|
|
315
|
+
return consentData;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Simply resets the module's consentData variable back to undefined, mainly for testing purposes
|
|
320
|
+
*/
|
|
321
|
+
export function resetConsentData() {
|
|
322
|
+
consentData = undefined;
|
|
323
|
+
userCMP = undefined;
|
|
324
|
+
consentTimeout = undefined;
|
|
325
|
+
gppDataHandler.reset();
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* A configuration function that initializes some module variables, as well as add a hook into the requestBids function
|
|
330
|
+
* @param {{cmp:string, timeout:number, allowAuctionWithoutConsent:boolean, defaultGdprScope:boolean}} config required; consentManagement module config settings; cmp (string), timeout (int), allowAuctionWithoutConsent (boolean)
|
|
331
|
+
*/
|
|
332
|
+
export function setConsentConfig(config) {
|
|
333
|
+
config = config && config.gpp;
|
|
334
|
+
if (!config || typeof config !== 'object') {
|
|
335
|
+
logWarn('consentManagement.gpp config not defined, exiting consent manager module');
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (isStr(config.cmpApi)) {
|
|
340
|
+
userCMP = config.cmpApi;
|
|
341
|
+
} else {
|
|
342
|
+
userCMP = DEFAULT_CMP;
|
|
343
|
+
logInfo(`consentManagement.gpp config did not specify cmp. Using system default setting (${DEFAULT_CMP}).`);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (isNumber(config.timeout)) {
|
|
347
|
+
consentTimeout = config.timeout;
|
|
348
|
+
} else {
|
|
349
|
+
consentTimeout = DEFAULT_CONSENT_TIMEOUT;
|
|
350
|
+
logInfo(`consentManagement.gpp config did not specify timeout. Using system default setting (${DEFAULT_CONSENT_TIMEOUT}).`);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (userCMP === 'static') {
|
|
354
|
+
if (isPlainObject(config.consentData)) {
|
|
355
|
+
staticConsentData = config.consentData;
|
|
356
|
+
consentTimeout = 0;
|
|
357
|
+
} else {
|
|
358
|
+
logError(`consentManagement.gpp config with cmpApi: 'static' did not specify consentData. No consents will be available to adapters.`);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
logInfo('consentManagement.gpp module has been activated...');
|
|
363
|
+
|
|
364
|
+
if (!addedConsentHook) {
|
|
365
|
+
$$PREBID_GLOBAL$$.requestBids.before(requestBidsHook, 50);
|
|
366
|
+
}
|
|
367
|
+
addedConsentHook = true;
|
|
368
|
+
gppDataHandler.enable();
|
|
369
|
+
loadConsentData(); // immediately look up consent data to make it available without requiring an auction
|
|
370
|
+
}
|
|
371
|
+
config.getConfig('consentManagement', config => setConsentConfig(config.consentManagement));
|
|
372
|
+
|
|
373
|
+
export function enrichFPDHook(next, fpd) {
|
|
374
|
+
return next(fpd.then(ortb2 => {
|
|
375
|
+
const consent = gppDataHandler.getConsentData();
|
|
376
|
+
if (consent) {
|
|
377
|
+
if (Array.isArray(consent.applicableSections)) {
|
|
378
|
+
deepSetValue(ortb2, 'regs.gpp_sid', consent.applicableSections);
|
|
379
|
+
}
|
|
380
|
+
deepSetValue(ortb2, 'regs.gpp', consent.gppString);
|
|
381
|
+
}
|
|
382
|
+
return ortb2;
|
|
383
|
+
}));
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
enrichFPD.before(enrichFPDHook);
|
|
@@ -8,7 +8,7 @@ import { deepAccess, isEmpty, logError, parseSizesInput, formatQS, parseUrl, bui
|
|
|
8
8
|
import { config } from '../src/config.js';
|
|
9
9
|
import { getHook, submodule } from '../src/hook.js';
|
|
10
10
|
import { auctionManager } from '../src/auctionManager.js';
|
|
11
|
-
import { gdprDataHandler, uspDataHandler } from '../src/adapterManager.js';
|
|
11
|
+
import { gdprDataHandler, uspDataHandler, gppDataHandler } from '../src/adapterManager.js';
|
|
12
12
|
import * as events from '../src/events.js';
|
|
13
13
|
import CONSTANTS from '../src/constants.json';
|
|
14
14
|
import {getPPID} from '../src/adserver.js';
|
|
@@ -119,6 +119,11 @@ export function buildDfpVideoUrl(options) {
|
|
|
119
119
|
const uspConsent = uspDataHandler.getConsentData();
|
|
120
120
|
if (uspConsent) { queryParams.us_privacy = uspConsent; }
|
|
121
121
|
|
|
122
|
+
const gppConsent = gppDataHandler.getConsentData();
|
|
123
|
+
if (gppConsent) {
|
|
124
|
+
// TODO - need to know what to set here for queryParams...
|
|
125
|
+
}
|
|
126
|
+
|
|
122
127
|
if (!queryParams.ppid) {
|
|
123
128
|
const ppid = getPPID();
|
|
124
129
|
if (ppid != null) {
|
|
@@ -94,8 +94,7 @@ export const spec = {
|
|
|
94
94
|
let {bidderRequestId, auctionId, gdprConsent, uspConsent, timeout, refererInfo} = bidderRequest || {};
|
|
95
95
|
|
|
96
96
|
const referer = refererInfo ? encodeURIComponent(refererInfo.page) : '';
|
|
97
|
-
const
|
|
98
|
-
const tmax = timeout ? Math.min(bidderTimeout, timeout) : bidderTimeout;
|
|
97
|
+
const tmax = timeout || config.getConfig('bidderTimeout');
|
|
99
98
|
const imp = [];
|
|
100
99
|
const bidsMap = {};
|
|
101
100
|
const requests = [];
|
|
@@ -40,14 +40,14 @@ export const spec = {
|
|
|
40
40
|
auctionId: bidRequest.auctionId,
|
|
41
41
|
bidId: bidRequest.bidId,
|
|
42
42
|
transactionId: bidRequest.transactionId,
|
|
43
|
-
device: JSON.stringify(getDeviceData()),
|
|
43
|
+
device: encodeURIComponent(JSON.stringify(getDeviceData())),
|
|
44
44
|
sizes,
|
|
45
45
|
aimXR,
|
|
46
46
|
uid: '$UID',
|
|
47
47
|
params: JSON.stringify(bidRequest.params),
|
|
48
48
|
crumbs: JSON.stringify(bidRequest.crumbs),
|
|
49
49
|
prebidVersion: '$prebid.version$',
|
|
50
|
-
version:
|
|
50
|
+
version: 3,
|
|
51
51
|
coppa: config.getConfig('coppa') == true ? 1 : 0,
|
|
52
52
|
ccpa: bidderRequest.uspConsent || undefined
|
|
53
53
|
}
|
|
@@ -643,7 +643,15 @@ magniteAdapter.disableAnalytics = function () {
|
|
|
643
643
|
accountId = undefined;
|
|
644
644
|
resetConfs();
|
|
645
645
|
magniteAdapter.originDisableAnalytics();
|
|
646
|
-
}
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
magniteAdapter.onDataDeletionRequest = function () {
|
|
649
|
+
if (storage.localStorageIsEnabled()) {
|
|
650
|
+
storage.removeDataFromLocalStorage(COOKIE_NAME);
|
|
651
|
+
} else {
|
|
652
|
+
throw Error('Unable to access local storage, no data deleted');
|
|
653
|
+
}
|
|
654
|
+
};
|
|
647
655
|
|
|
648
656
|
magniteAdapter.MODULE_INITIALIZED_TIME = Date.now();
|
|
649
657
|
magniteAdapter.referrerHostname = '';
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { BANNER, VIDEO } from '../src/mediaTypes.js';
|
|
4
4
|
import { INSTREAM, OUTSTREAM } from '../src/video.js';
|
|
5
5
|
import { Renderer } from '../src/Renderer.js';
|
|
6
|
-
import {find} from '../src/polyfill.js';
|
|
6
|
+
import { find } from '../src/polyfill.js';
|
|
7
7
|
import { getStorageManager } from '../src/storageManager.js';
|
|
8
8
|
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
9
9
|
import { deepClone, logError, deepAccess } from '../src/utils.js';
|
|
@@ -13,7 +13,7 @@ const USER_SYNC_ENDPOINT = 'https://onetag-sys.com/usync/';
|
|
|
13
13
|
const BIDDER_CODE = 'onetag';
|
|
14
14
|
const GVLID = 241;
|
|
15
15
|
|
|
16
|
-
const storage = getStorageManager({gvlid: GVLID, bidderCode: BIDDER_CODE});
|
|
16
|
+
const storage = getStorageManager({ gvlid: GVLID, bidderCode: BIDDER_CODE });
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Determines whether or not the given bid request is valid.
|
|
@@ -53,7 +53,7 @@ export function isValid(type, bid) {
|
|
|
53
53
|
function buildRequests(validBidRequests, bidderRequest) {
|
|
54
54
|
const payload = {
|
|
55
55
|
bids: requestsToBids(validBidRequests),
|
|
56
|
-
...getPageInfo()
|
|
56
|
+
...getPageInfo(bidderRequest)
|
|
57
57
|
};
|
|
58
58
|
if (bidderRequest && bidderRequest.gdprConsent) {
|
|
59
59
|
payload.gdprConsent = {
|
|
@@ -74,7 +74,10 @@ function buildRequests(validBidRequests, bidderRequest) {
|
|
|
74
74
|
if (storage.hasLocalStorage()) {
|
|
75
75
|
payload.onetagSid = storage.getDataFromLocalStorage('onetag_sid');
|
|
76
76
|
}
|
|
77
|
-
} catch (e) {}
|
|
77
|
+
} catch (e) { }
|
|
78
|
+
const connection = navigator.connection || navigator.webkitConnection;
|
|
79
|
+
payload.networkConnectionType = (connection && connection.type) ? connection.type : null;
|
|
80
|
+
payload.networkEffectiveConnectionType = (connection && connection.effectiveType) ? connection.effectiveType : null;
|
|
78
81
|
return {
|
|
79
82
|
method: 'POST',
|
|
80
83
|
url: ENDPOINT,
|
|
@@ -112,7 +115,7 @@ function interpretResponse(serverResponse, bidderRequest) {
|
|
|
112
115
|
if (bid.mediaType === BANNER) {
|
|
113
116
|
responseBid.ad = bid.ad;
|
|
114
117
|
} else if (bid.mediaType === VIDEO) {
|
|
115
|
-
const {context, adUnitCode} = find(requestData.bids, (item) =>
|
|
118
|
+
const { context, adUnitCode } = find(requestData.bids, (item) =>
|
|
116
119
|
item.bidId === bid.requestId &&
|
|
117
120
|
item.type === VIDEO
|
|
118
121
|
);
|
|
@@ -141,7 +144,7 @@ function createRenderer(bid, rendererOptions = {}) {
|
|
|
141
144
|
loaded: false
|
|
142
145
|
});
|
|
143
146
|
try {
|
|
144
|
-
renderer.setRender(({renderer, width, height, vastXml, adUnitCode}) => {
|
|
147
|
+
renderer.setRender(({ renderer, width, height, vastXml, adUnitCode }) => {
|
|
145
148
|
renderer.push(() => {
|
|
146
149
|
window.onetag.Player.init({
|
|
147
150
|
...bid,
|
|
@@ -162,7 +165,6 @@ function createRenderer(bid, rendererOptions = {}) {
|
|
|
162
165
|
function getFrameNesting() {
|
|
163
166
|
let topmostFrame = window;
|
|
164
167
|
let parent = window.parent;
|
|
165
|
-
let currentFrameNesting = 0;
|
|
166
168
|
try {
|
|
167
169
|
while (topmostFrame !== topmostFrame.parent) {
|
|
168
170
|
parent = topmostFrame.parent;
|
|
@@ -170,13 +172,8 @@ function getFrameNesting() {
|
|
|
170
172
|
parent.location.href;
|
|
171
173
|
topmostFrame = topmostFrame.parent;
|
|
172
174
|
}
|
|
173
|
-
} catch (e) {
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
return {
|
|
177
|
-
topmostFrame,
|
|
178
|
-
currentFrameNesting
|
|
179
|
-
}
|
|
175
|
+
} catch (e) { }
|
|
176
|
+
return topmostFrame;
|
|
180
177
|
}
|
|
181
178
|
|
|
182
179
|
function getDocumentVisibility(window) {
|
|
@@ -197,21 +194,15 @@ function getDocumentVisibility(window) {
|
|
|
197
194
|
|
|
198
195
|
/**
|
|
199
196
|
* Returns information about the page needed by the server in an object to be converted in JSON
|
|
200
|
-
* @returns {{location: *, referrer: (*|string),
|
|
197
|
+
* @returns {{location: *, referrer: (*|string), stack: (*|Array.<String>), numIframes: (*|Number), wWidth: (*|Number), wHeight: (*|Number), sWidth, sHeight, date: string, timeOffset: number}}
|
|
201
198
|
*/
|
|
202
|
-
function getPageInfo() {
|
|
203
|
-
const
|
|
199
|
+
function getPageInfo(bidderRequest) {
|
|
200
|
+
const topmostFrame = getFrameNesting();
|
|
204
201
|
return {
|
|
205
|
-
location:
|
|
206
|
-
referrer:
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
: null,
|
|
210
|
-
ancestorOrigin:
|
|
211
|
-
window.location.ancestorOrigins && window.location.ancestorOrigins.length > 0
|
|
212
|
-
? window.location.ancestorOrigins[window.location.ancestorOrigins.length - 1]
|
|
213
|
-
: null,
|
|
214
|
-
masked: currentFrameNesting,
|
|
202
|
+
location: deepAccess(bidderRequest, 'refererInfo.page', null),
|
|
203
|
+
referrer: deepAccess(bidderRequest, 'refererInfo.ref', null),
|
|
204
|
+
stack: deepAccess(bidderRequest, 'refererInfo.stack', []),
|
|
205
|
+
numIframes: deepAccess(bidderRequest, 'refererInfo.numIframes', 0),
|
|
215
206
|
wWidth: topmostFrame.innerWidth,
|
|
216
207
|
wHeight: topmostFrame.innerHeight,
|
|
217
208
|
oWidth: topmostFrame.outerWidth,
|
|
@@ -230,7 +221,7 @@ function getPageInfo() {
|
|
|
230
221
|
timing: getTiming(),
|
|
231
222
|
version: {
|
|
232
223
|
prebid: '$prebid.version$',
|
|
233
|
-
adapter: '1.1.
|
|
224
|
+
adapter: '1.1.1'
|
|
234
225
|
}
|
|
235
226
|
};
|
|
236
227
|
}
|
|
@@ -344,7 +335,7 @@ function getSizes(sizes) {
|
|
|
344
335
|
const ret = [];
|
|
345
336
|
for (let i = 0; i < sizes.length; i++) {
|
|
346
337
|
const size = sizes[i];
|
|
347
|
-
ret.push({width: size[0], height: size[1]})
|
|
338
|
+
ret.push({ width: size[0], height: size[1] })
|
|
348
339
|
}
|
|
349
340
|
return ret;
|
|
350
341
|
}
|
|
@@ -216,7 +216,7 @@ export function resetSyncedStatus() {
|
|
|
216
216
|
/**
|
|
217
217
|
* @param {Array} bidderCodes list of bidders to request user syncs for.
|
|
218
218
|
*/
|
|
219
|
-
function queueSync(bidderCodes, gdprConsent, uspConsent, s2sConfig) {
|
|
219
|
+
function queueSync(bidderCodes, gdprConsent, uspConsent, gppConsent, s2sConfig) {
|
|
220
220
|
if (_s2sConfigs.length === _syncCount) {
|
|
221
221
|
return;
|
|
222
222
|
}
|
|
@@ -246,6 +246,15 @@ function queueSync(bidderCodes, gdprConsent, uspConsent, s2sConfig) {
|
|
|
246
246
|
payload.us_privacy = uspConsent;
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
+
if (gppConsent) {
|
|
250
|
+
// proposing the following formatting, can adjust if needed...
|
|
251
|
+
// update - leaving this param as an array, since it's part of a POST payload where the [] characters shouldn't matter too much
|
|
252
|
+
payload.gpp_sid = gppConsent.applicableSections
|
|
253
|
+
// should we add check if applicableSections was not equal to -1 (where user was out of scope)?
|
|
254
|
+
// this would be similar to what was done above for TCF
|
|
255
|
+
payload.gpp = gppConsent.gppString;
|
|
256
|
+
}
|
|
257
|
+
|
|
249
258
|
if (typeof s2sConfig.coopSync === 'boolean') {
|
|
250
259
|
payload.coopSync = s2sConfig.coopSync;
|
|
251
260
|
}
|
|
@@ -330,7 +339,7 @@ function doBidderSync(type, url, bidder, done, timeout) {
|
|
|
330
339
|
*
|
|
331
340
|
* @param {Array} bidders a list of bidder names
|
|
332
341
|
*/
|
|
333
|
-
function doClientSideSyncs(bidders, gdprConsent, uspConsent) {
|
|
342
|
+
function doClientSideSyncs(bidders, gdprConsent, uspConsent, gppConsent) {
|
|
334
343
|
bidders.forEach(bidder => {
|
|
335
344
|
let clientAdapter = adapterManager.getBidAdapter(bidder);
|
|
336
345
|
if (clientAdapter && clientAdapter.registerSyncs) {
|
|
@@ -341,7 +350,8 @@ function doClientSideSyncs(bidders, gdprConsent, uspConsent) {
|
|
|
341
350
|
clientAdapter,
|
|
342
351
|
[],
|
|
343
352
|
gdprConsent,
|
|
344
|
-
uspConsent
|
|
353
|
+
uspConsent,
|
|
354
|
+
gppConsent
|
|
345
355
|
)
|
|
346
356
|
);
|
|
347
357
|
}
|
|
@@ -411,12 +421,13 @@ function getMatchingConsentUrl(urlProp, gdprConsent) {
|
|
|
411
421
|
}
|
|
412
422
|
|
|
413
423
|
function getConsentData(bidRequests) {
|
|
414
|
-
let gdprConsent, uspConsent;
|
|
424
|
+
let gdprConsent, uspConsent, gppConsent;
|
|
415
425
|
if (Array.isArray(bidRequests) && bidRequests.length > 0) {
|
|
416
426
|
gdprConsent = bidRequests[0].gdprConsent;
|
|
417
427
|
uspConsent = bidRequests[0].uspConsent;
|
|
428
|
+
gppConsent = bidRequests[0].gppConsent;
|
|
418
429
|
}
|
|
419
|
-
return { gdprConsent, uspConsent };
|
|
430
|
+
return { gdprConsent, uspConsent, gppConsent };
|
|
420
431
|
}
|
|
421
432
|
|
|
422
433
|
/**
|
|
@@ -433,7 +444,7 @@ export function PrebidServer() {
|
|
|
433
444
|
done = adapterMetrics.startTiming('total').stopBefore(done);
|
|
434
445
|
bidRequests.forEach(req => useMetrics(req.metrics).join(adapterMetrics, {continuePropagation: false}));
|
|
435
446
|
|
|
436
|
-
let { gdprConsent, uspConsent } = getConsentData(bidRequests);
|
|
447
|
+
let { gdprConsent, uspConsent, gppConsent } = getConsentData(bidRequests);
|
|
437
448
|
|
|
438
449
|
if (Array.isArray(_s2sConfigs)) {
|
|
439
450
|
if (s2sBidRequest.s2sConfig && s2sBidRequest.s2sConfig.syncEndpoint && getMatchingConsentUrl(s2sBidRequest.s2sConfig.syncEndpoint, gdprConsent)) {
|
|
@@ -441,7 +452,7 @@ export function PrebidServer() {
|
|
|
441
452
|
.map(bidder => adapterManager.aliasRegistry[bidder] || bidder)
|
|
442
453
|
.filter((bidder, index, array) => (array.indexOf(bidder) === index));
|
|
443
454
|
|
|
444
|
-
queueSync(syncBidders, gdprConsent, uspConsent, s2sBidRequest.s2sConfig);
|
|
455
|
+
queueSync(syncBidders, gdprConsent, uspConsent, gppConsent, s2sBidRequest.s2sConfig);
|
|
445
456
|
}
|
|
446
457
|
|
|
447
458
|
processPBSRequest(s2sBidRequest, bidRequests, ajax, {
|
|
@@ -450,7 +461,7 @@ export function PrebidServer() {
|
|
|
450
461
|
bidRequests.forEach(bidderRequest => events.emit(CONSTANTS.EVENTS.BIDDER_DONE, bidderRequest));
|
|
451
462
|
}
|
|
452
463
|
done();
|
|
453
|
-
doClientSideSyncs(requestedBidders, gdprConsent, uspConsent);
|
|
464
|
+
doClientSideSyncs(requestedBidders, gdprConsent, uspConsent, gppConsent);
|
|
454
465
|
},
|
|
455
466
|
onError: done,
|
|
456
467
|
onBid: function ({adUnit, bid}) {
|
|
@@ -163,7 +163,7 @@ import {getHook, module} from '../../src/hook.js';
|
|
|
163
163
|
import {logError, logInfo, logWarn} from '../../src/utils.js';
|
|
164
164
|
import * as events from '../../src/events.js';
|
|
165
165
|
import CONSTANTS from '../../src/constants.json';
|
|
166
|
-
import adapterManager, {gdprDataHandler, uspDataHandler} from '../../src/adapterManager.js';
|
|
166
|
+
import adapterManager, {gdprDataHandler, uspDataHandler, gppDataHandler} from '../../src/adapterManager.js';
|
|
167
167
|
import {find} from '../../src/polyfill.js';
|
|
168
168
|
import {timedAuctionHook} from '../../src/utils/perfMetrics.js';
|
|
169
169
|
|
|
@@ -246,6 +246,7 @@ function getConsentData() {
|
|
|
246
246
|
return {
|
|
247
247
|
gdpr: gdprDataHandler.getConsentData(),
|
|
248
248
|
usp: uspDataHandler.getConsentData(),
|
|
249
|
+
gpp: gppDataHandler.getConsentData(),
|
|
249
250
|
coppa: !!(config.getConfig('coppa'))
|
|
250
251
|
}
|
|
251
252
|
}
|