prebid.js 6.28.0 → 6.29.2
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/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adoceanBidAdapter.js +1 -1
- package/dist/adrelevantisBidAdapter.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/audiencerunBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bluebillywigBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectIdSystem.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consentManagement.js +1 -1
- 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/currency.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/gdprEnforcement.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/impactifyBidAdapter.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/jixieBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -0
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/mediakeysBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/merkleIdSystem.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +120 -119
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/oneVideoBidAdapter.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 +3 -3
- package/dist/pubCommonId.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticAnalyticsAdapter.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/rubiconAnalyticsAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharedIdSystem.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.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/sortableBidAdapter.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/taboolaBidAdapter.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/trustxBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.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/modules/adoceanBidAdapter.js +29 -1
- package/modules/consentManagement.js +20 -10
- package/modules/currency.js +2 -2
- package/modules/gdprEnforcement.js +15 -9
- package/modules/insticatorBidAdapter.js +109 -42
- package/modules/ixBidAdapter.js +3 -2
- package/modules/ixBidAdapter.md +1 -1
- package/modules/lassoBidAdapter.js +133 -0
- package/modules/lassoBidAdapter.md +29 -0
- package/modules/merkleIdSystem.js +43 -31
- package/modules/pubCommonId.js +2 -1
- package/modules/pubmaticAnalyticsAdapter.js +49 -33
- package/modules/sharedIdSystem.js +5 -11
- package/modules/synacormediaBidAdapter.js +11 -2
- package/modules/taboolaBidAdapter.js +1 -1
- package/modules/userId/eids.js +25 -5
- package/modules/userId/index.js +39 -21
- package/package.json +1 -1
- package/src/auction.js +6 -5
- package/src/consentHandler.js +11 -11
- package/src/hook.js +2 -2
- package/src/storageManager.js +5 -4
- package/src/utils/promise.js +96 -21
- package/src/utils.js +3 -2
- package/test/helpers/consentData.js +2 -1
- package/test/spec/auctionmanager_spec.js +1 -6
- package/test/spec/modules/adoceanBidAdapter_spec.js +25 -1
- package/test/spec/modules/consentManagement_spec.js +75 -16
- package/test/spec/modules/eids_spec.js +48 -3
- package/test/spec/modules/gdprEnforcement_spec.js +100 -53
- package/test/spec/modules/idxIdSystem_spec.js +1 -1
- package/test/spec/modules/insticatorBidAdapter_spec.js +46 -1
- package/test/spec/modules/ixBidAdapter_spec.js +1 -1
- package/test/spec/modules/lassoBidAdapter_spec.js +177 -0
- package/test/spec/modules/merkleIdSystem_spec.js +58 -37
- package/test/spec/modules/parrableIdSystem_spec.js +2 -1
- package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +117 -0
- package/test/spec/modules/synacormediaBidAdapter_spec.js +74 -0
- package/test/spec/modules/userId_spec.js +42 -3
- package/test/spec/modules/vidazooBidAdapter_spec.js +9 -4
- package/test/spec/unit/pbjs_api_spec.js +2 -6
- package/test/spec/unit/utils/promise_spec.js +283 -38
- package/test/helpers/syncPromise.js +0 -71
|
@@ -18,6 +18,8 @@ const TCF2 = {
|
|
|
18
18
|
'purpose7': { id: 7, name: 'measurement' }
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
const VENDORLESS_MODULE_TYPES = ['fpid-module'];
|
|
22
|
+
|
|
21
23
|
/*
|
|
22
24
|
These rules would be used if `consentManagement.gdpr.rules` is undefined by the publisher.
|
|
23
25
|
*/
|
|
@@ -123,9 +125,10 @@ function getGvlidForAnalyticsAdapter(code) {
|
|
|
123
125
|
* @param {Object} consentData - gdpr consent data
|
|
124
126
|
* @param {string=} currentModule - Bidder code of the current module
|
|
125
127
|
* @param {number=} gvlId - GVL ID for the module
|
|
128
|
+
* @param {string=} moduleType module type
|
|
126
129
|
* @returns {boolean}
|
|
127
130
|
*/
|
|
128
|
-
export function validateRules(rule, consentData, currentModule, gvlId) {
|
|
131
|
+
export function validateRules(rule, consentData, currentModule, gvlId, moduleType) {
|
|
129
132
|
const purposeId = TCF2[Object.keys(TCF2).filter(purposeName => TCF2[purposeName].name === rule.purpose)[0]].id;
|
|
130
133
|
|
|
131
134
|
// return 'true' if vendor present in 'vendorExceptions'
|
|
@@ -138,12 +141,14 @@ export function validateRules(rule, consentData, currentModule, gvlId) {
|
|
|
138
141
|
const vendorConsent = deepAccess(consentData, `vendorData.vendor.consents.${gvlId}`);
|
|
139
142
|
const liTransparency = deepAccess(consentData, `vendorData.purpose.legitimateInterests.${purposeId}`);
|
|
140
143
|
|
|
144
|
+
const vendorlessModule = includes(VENDORLESS_MODULE_TYPES, moduleType);
|
|
145
|
+
|
|
141
146
|
/*
|
|
142
147
|
Since vendor exceptions have already been handled, the purpose as a whole is allowed if it's not being enforced
|
|
143
148
|
or the user has consented. Similar with vendors.
|
|
144
149
|
*/
|
|
145
150
|
const purposeAllowed = rule.enforcePurpose === false || purposeConsent === true;
|
|
146
|
-
const vendorAllowed = rule.enforceVendor === false || vendorConsent === true;
|
|
151
|
+
const vendorAllowed = rule.enforceVendor === false || vendorConsent === true || vendorlessModule === true;
|
|
147
152
|
|
|
148
153
|
/*
|
|
149
154
|
Few if any vendors should be declaring Legitimate Interest for Device Access (Purpose 1), but some are claiming
|
|
@@ -162,15 +167,16 @@ export function validateRules(rule, consentData, currentModule, gvlId) {
|
|
|
162
167
|
* @param {Function} fn reference to original function (used by hook logic)
|
|
163
168
|
* @param {Number=} gvlid gvlid of the module
|
|
164
169
|
* @param {string=} moduleName name of the module
|
|
170
|
+
* @param {string=} moduleType module type
|
|
165
171
|
*/
|
|
166
|
-
export function deviceAccessHook(fn, gvlid, moduleName, result) {
|
|
172
|
+
export function deviceAccessHook(fn, gvlid, moduleName, moduleType, result) {
|
|
167
173
|
result = Object.assign({}, {
|
|
168
174
|
hasEnforcementHook: true
|
|
169
175
|
});
|
|
170
176
|
if (!hasDeviceAccess()) {
|
|
171
177
|
logWarn('Device access is disabled by Publisher');
|
|
172
178
|
result.valid = false;
|
|
173
|
-
fn.call(this, gvlid, moduleName, result);
|
|
179
|
+
fn.call(this, gvlid, moduleName, moduleType, result);
|
|
174
180
|
} else {
|
|
175
181
|
const consentData = gdprDataHandler.getConsentData();
|
|
176
182
|
if (consentData && consentData.gdprApplies) {
|
|
@@ -183,24 +189,24 @@ export function deviceAccessHook(fn, gvlid, moduleName, result) {
|
|
|
183
189
|
gvlid = getGvlid(moduleName) || gvlid;
|
|
184
190
|
}
|
|
185
191
|
const curModule = moduleName || curBidder;
|
|
186
|
-
let isAllowed = validateRules(purpose1Rule, consentData, curModule, gvlid);
|
|
192
|
+
let isAllowed = validateRules(purpose1Rule, consentData, curModule, gvlid, moduleType);
|
|
187
193
|
if (isAllowed) {
|
|
188
194
|
result.valid = true;
|
|
189
|
-
fn.call(this, gvlid, moduleName, result);
|
|
195
|
+
fn.call(this, gvlid, moduleName, moduleType, result);
|
|
190
196
|
} else {
|
|
191
197
|
curModule && logWarn(`TCF2 denied device access for ${curModule}`);
|
|
192
198
|
result.valid = false;
|
|
193
199
|
storageBlocked.push(curModule);
|
|
194
|
-
fn.call(this, gvlid, moduleName, result);
|
|
200
|
+
fn.call(this, gvlid, moduleName, moduleType, result);
|
|
195
201
|
}
|
|
196
202
|
} else {
|
|
197
203
|
// The module doesn't enforce TCF1.1 strings
|
|
198
204
|
result.valid = true;
|
|
199
|
-
fn.call(this, gvlid, moduleName, result);
|
|
205
|
+
fn.call(this, gvlid, moduleName, moduleType, result);
|
|
200
206
|
}
|
|
201
207
|
} else {
|
|
202
208
|
result.valid = true;
|
|
203
|
-
fn.call(this, gvlid, moduleName, result);
|
|
209
|
+
fn.call(this, gvlid, moduleName, moduleType, result);
|
|
204
210
|
}
|
|
205
211
|
}
|
|
206
212
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {config} from '../src/config.js';
|
|
2
|
-
import {BANNER} from '../src/mediaTypes.js';
|
|
2
|
+
import {BANNER, VIDEO} from '../src/mediaTypes.js';
|
|
3
3
|
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
4
4
|
import {deepAccess, generateUUID, logError, isArray} from '../src/utils.js';
|
|
5
5
|
import {getStorageManager} from '../src/storageManager.js';
|
|
@@ -48,14 +48,9 @@ function setUserId(userId) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
function
|
|
51
|
+
function buildBanner(bidRequest) {
|
|
52
52
|
const format = [];
|
|
53
|
-
const
|
|
54
|
-
insticator: {
|
|
55
|
-
adUnitId: bidRequest.params.adUnitId,
|
|
56
|
-
},
|
|
57
|
-
}
|
|
58
|
-
|
|
53
|
+
const pos = deepAccess(bidRequest, 'mediaTypes.banner.pos');
|
|
59
54
|
const sizes =
|
|
60
55
|
deepAccess(bidRequest, 'mediaTypes.banner.sizes') || bidRequest.sizes;
|
|
61
56
|
|
|
@@ -66,27 +61,47 @@ function buildImpression(bidRequest) {
|
|
|
66
61
|
});
|
|
67
62
|
}
|
|
68
63
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
ext.gpid = gpid;
|
|
64
|
+
return {
|
|
65
|
+
format,
|
|
66
|
+
pos,
|
|
73
67
|
}
|
|
68
|
+
}
|
|
74
69
|
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
const
|
|
70
|
+
function buildVideo(bidRequest) {
|
|
71
|
+
const w = deepAccess(bidRequest, 'mediaTypes.video.w');
|
|
72
|
+
const h = deepAccess(bidRequest, 'mediaTypes.video.h');
|
|
73
|
+
const mimes = deepAccess(bidRequest, 'mediaTypes.video.mimes');
|
|
78
74
|
|
|
79
75
|
return {
|
|
76
|
+
mimes,
|
|
77
|
+
w,
|
|
78
|
+
h,
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function buildImpression(bidRequest) {
|
|
83
|
+
const imp = {
|
|
80
84
|
id: bidRequest.bidId,
|
|
81
85
|
tagid: bidRequest.adUnitCode,
|
|
82
|
-
instl,
|
|
83
|
-
secure,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
instl: deepAccess(bidRequest, 'ortb2Imp.instl'),
|
|
87
|
+
secure: location.protocol === 'https:' ? 1 : 0,
|
|
88
|
+
ext: {
|
|
89
|
+
gpid: deepAccess(bidRequest, 'ortb2Imp.ext.gpid'),
|
|
90
|
+
insticator: {
|
|
91
|
+
adUnitId: bidRequest.params.adUnitId,
|
|
92
|
+
},
|
|
87
93
|
},
|
|
88
|
-
|
|
89
|
-
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (deepAccess(bidRequest, 'mediaTypes.banner')) {
|
|
97
|
+
imp.banner = buildBanner(bidRequest);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (deepAccess(bidRequest, 'mediaTypes.video')) {
|
|
101
|
+
imp.video = buildVideo(bidRequest);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return imp;
|
|
90
105
|
}
|
|
91
106
|
|
|
92
107
|
function buildDevice() {
|
|
@@ -252,31 +267,83 @@ function validateSizes(sizes) {
|
|
|
252
267
|
);
|
|
253
268
|
}
|
|
254
269
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
270
|
+
function validateAdUnitId(bid) {
|
|
271
|
+
if (!bid.params.adUnitId) {
|
|
272
|
+
logError('insticator: missing adUnitId bid parameter');
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
259
275
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
logError('insticator: missing adUnitId bid parameter');
|
|
263
|
-
return false;
|
|
264
|
-
}
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
265
278
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
279
|
+
function validateMediaType(bid) {
|
|
280
|
+
if (!(BANNER in bid.mediaTypes || VIDEO in bid.mediaTypes)) {
|
|
281
|
+
logError('insticator: expected banner or video in mediaTypes');
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
270
284
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
!validateSizes(bid.mediaTypes.banner.sizes)
|
|
274
|
-
) {
|
|
275
|
-
logError('insticator: banner sizes not specified or invalid');
|
|
276
|
-
return false;
|
|
277
|
-
}
|
|
285
|
+
return true;
|
|
286
|
+
}
|
|
278
287
|
|
|
288
|
+
function validateBanner(bid) {
|
|
289
|
+
const banner = deepAccess(bid, 'mediaTypes.banner');
|
|
290
|
+
|
|
291
|
+
if (banner === undefined) {
|
|
279
292
|
return true;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (
|
|
296
|
+
!validateSizes(bid.sizes) &&
|
|
297
|
+
!validateSizes(bid.mediaTypes.banner.sizes)
|
|
298
|
+
) {
|
|
299
|
+
logError('insticator: banner sizes not specified or invalid');
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return true;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function validateVideo(bid) {
|
|
307
|
+
const video = deepAccess(bid, 'mediaTypes.video');
|
|
308
|
+
|
|
309
|
+
if (video === undefined) {
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const videoSize = [
|
|
314
|
+
deepAccess(bid, 'mediaTypes.video.w'),
|
|
315
|
+
deepAccess(bid, 'mediaTypes.video.h'),
|
|
316
|
+
];
|
|
317
|
+
|
|
318
|
+
if (
|
|
319
|
+
!validateSize(videoSize)
|
|
320
|
+
) {
|
|
321
|
+
logError('insticator: video size not specified or invalid');
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const mimes = deepAccess(bid, 'mediaTypes.video.mimes');
|
|
326
|
+
|
|
327
|
+
if (!Array.isArray(mimes) || mimes.length === 0) {
|
|
328
|
+
logError('insticator: mimes not specified');
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
return true;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export const spec = {
|
|
336
|
+
code: BIDDER_CODE,
|
|
337
|
+
gvlid: GVLID,
|
|
338
|
+
supportedMediaTypes: [ BANNER, VIDEO ],
|
|
339
|
+
|
|
340
|
+
isBidRequestValid: function (bid) {
|
|
341
|
+
return (
|
|
342
|
+
validateAdUnitId(bid) &&
|
|
343
|
+
validateMediaType(bid) &&
|
|
344
|
+
validateBanner(bid) &&
|
|
345
|
+
validateVideo(bid)
|
|
346
|
+
);
|
|
280
347
|
},
|
|
281
348
|
|
|
282
349
|
buildRequests: function (validBidRequests, bidderRequest) {
|
package/modules/ixBidAdapter.js
CHANGED
|
@@ -30,7 +30,8 @@ import {Renderer} from '../src/Renderer.js';
|
|
|
30
30
|
const BIDDER_CODE = 'ix';
|
|
31
31
|
const ALIAS_BIDDER_CODE = 'roundel';
|
|
32
32
|
const GLOBAL_VENDOR_ID = 10;
|
|
33
|
-
const
|
|
33
|
+
const MODULE_TYPE = 'bid-adapter';
|
|
34
|
+
const SECURE_BID_URL = 'https://htlb.casalemedia.com/openrtb/pbjs';
|
|
34
35
|
const SUPPORTED_AD_TYPES = [BANNER, VIDEO];
|
|
35
36
|
const BANNER_ENDPOINT_VERSION = 7.2;
|
|
36
37
|
const VIDEO_ENDPOINT_VERSION = 8.1;
|
|
@@ -1086,7 +1087,7 @@ function localStorageHandler(data) {
|
|
|
1086
1087
|
hasEnforcementHook: false,
|
|
1087
1088
|
valid: hasDeviceAccess()
|
|
1088
1089
|
};
|
|
1089
|
-
validateStorageEnforcement(GLOBAL_VENDOR_ID, BIDDER_CODE, DEFAULT_ENFORCEMENT_SETTINGS, (permissions) => {
|
|
1090
|
+
validateStorageEnforcement(GLOBAL_VENDOR_ID, BIDDER_CODE, MODULE_TYPE, DEFAULT_ENFORCEMENT_SETTINGS, (permissions) => {
|
|
1090
1091
|
if (permissions.valid) {
|
|
1091
1092
|
storeErrorEventData(data);
|
|
1092
1093
|
}
|
package/modules/ixBidAdapter.md
CHANGED
|
@@ -423,4 +423,4 @@ The `size` parameter is no longer a required field, the `siteId` will now be ass
|
|
|
423
423
|
In your browser of choice, create a new tab and open the developer tools. In
|
|
424
424
|
developer tools, select the network tab. Then, navigate to a page where IX is
|
|
425
425
|
setup to bid. Now, in the network tab, search for requests to
|
|
426
|
-
`casalemedia.com/
|
|
426
|
+
`casalemedia.com/openrtb/pbjs`. These are the bid requests.
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
2
|
+
import { BANNER } from '../src/mediaTypes.js';
|
|
3
|
+
import { getStorageManager } from '../src/storageManager.js';
|
|
4
|
+
import { ajax } from '../src/ajax.js';
|
|
5
|
+
import { config } from '../src/config.js';
|
|
6
|
+
|
|
7
|
+
const BIDDER_CODE = 'lasso';
|
|
8
|
+
const ENDPOINT_URL = 'https://trc.lhmos.com/prebid';
|
|
9
|
+
const GET_IUD_URL = 'https://secure.adnxs.com/getuid?';
|
|
10
|
+
const COOKIE_NAME = 'aim-xr';
|
|
11
|
+
const storage = getStorageManager({bidderCode: BIDDER_CODE});
|
|
12
|
+
|
|
13
|
+
export const spec = {
|
|
14
|
+
code: BIDDER_CODE,
|
|
15
|
+
isBidRequestValid: function(bid) {
|
|
16
|
+
return !!(bid.params && bid.params.adUnitId);
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
buildRequests: function(validBidRequests, bidderRequest) {
|
|
20
|
+
if (validBidRequests.length === 0) {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let aimXR = '';
|
|
25
|
+
if (storage.cookiesAreEnabled) {
|
|
26
|
+
aimXR = storage.getCookie(COOKIE_NAME, undefined);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return validBidRequests.map(bidRequest => {
|
|
30
|
+
let sizes = []
|
|
31
|
+
if (bidRequest.mediaTypes && bidRequest.mediaTypes[BANNER] && bidRequest.mediaTypes[BANNER].sizes) {
|
|
32
|
+
sizes = bidRequest.mediaTypes[BANNER].sizes;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const payload = {
|
|
36
|
+
auctionStart: bidderRequest.auctionStart,
|
|
37
|
+
url: encodeURIComponent(window.location.href),
|
|
38
|
+
bidderRequestId: bidRequest.bidderRequestId,
|
|
39
|
+
adUnitCode: bidRequest.adUnitCode,
|
|
40
|
+
auctionId: bidRequest.auctionId,
|
|
41
|
+
bidId: bidRequest.bidId,
|
|
42
|
+
transactionId: bidRequest.transactionId,
|
|
43
|
+
device: JSON.stringify(getDeviceData()),
|
|
44
|
+
sizes,
|
|
45
|
+
aimXR,
|
|
46
|
+
uid: '$UID',
|
|
47
|
+
params: JSON.stringify(bidRequest.params),
|
|
48
|
+
crumbs: JSON.stringify(bidRequest.crumbs),
|
|
49
|
+
prebidVersion: '$prebid.version$',
|
|
50
|
+
version: 1,
|
|
51
|
+
coppa: config.getConfig('coppa') == true ? 1 : 0,
|
|
52
|
+
ccpa: bidderRequest.uspConsent || undefined
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
method: 'GET',
|
|
57
|
+
url: getBidRequestUrl(aimXR),
|
|
58
|
+
data: payload,
|
|
59
|
+
options: {
|
|
60
|
+
withCredentials: false
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
interpretResponse: function(serverResponse) {
|
|
67
|
+
const response = serverResponse && serverResponse.body;
|
|
68
|
+
const bidResponses = [];
|
|
69
|
+
|
|
70
|
+
if (!response) {
|
|
71
|
+
return bidResponses;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const bidResponse = {
|
|
75
|
+
requestId: response.bidid,
|
|
76
|
+
cpm: response.bid.price,
|
|
77
|
+
currency: response.cur,
|
|
78
|
+
width: response.bid.w,
|
|
79
|
+
height: response.bid.h,
|
|
80
|
+
creativeId: response.bid.crid,
|
|
81
|
+
netRevenue: response.netRevenue,
|
|
82
|
+
ttl: response.ttl,
|
|
83
|
+
ad: response.bid.ad,
|
|
84
|
+
mediaType: response.bid.mediaType,
|
|
85
|
+
meta: {
|
|
86
|
+
secondaryCatIds: response.bid.cat,
|
|
87
|
+
advertiserDomains: response.bid.advertiserDomains,
|
|
88
|
+
advertiserName: response.meta.advertiserName,
|
|
89
|
+
mediaType: response.bid.mediaType
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
bidResponses.push(bidResponse);
|
|
93
|
+
return bidResponses;
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
onTimeout: function(timeoutData) {
|
|
97
|
+
if (timeoutData === null) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
ajax(ENDPOINT_URL + '/timeout', null, JSON.stringify(timeoutData), {
|
|
101
|
+
method: 'POST',
|
|
102
|
+
withCredentials: false
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
onBidWon: function(bid) {
|
|
107
|
+
ajax(ENDPOINT_URL + '/won', null, JSON.stringify(bid), {
|
|
108
|
+
method: 'POST',
|
|
109
|
+
withCredentials: false
|
|
110
|
+
});
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
supportedMediaTypes: [BANNER]
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function getBidRequestUrl(aimXR) {
|
|
117
|
+
if (!aimXR) {
|
|
118
|
+
return GET_IUD_URL + ENDPOINT_URL + '/request';
|
|
119
|
+
}
|
|
120
|
+
return ENDPOINT_URL + '/request'
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function getDeviceData() {
|
|
124
|
+
const win = window.top;
|
|
125
|
+
return {
|
|
126
|
+
ua: navigator.userAgent,
|
|
127
|
+
width: win.innerWidth || win.document.documentElement.clientWidth || win.document.body.clientWidth,
|
|
128
|
+
height: win.innerHeight || win.document.documentElement.clientHeight || win.document.body.clientHeight,
|
|
129
|
+
browserLanguage: navigator.language,
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
registerBidder(spec);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
**Module Name**: Lasso Bidder Adapter
|
|
4
|
+
**Module Type**: Bidder Adapter
|
|
5
|
+
**Maintainer**: headerbidding@lassomarketing.io
|
|
6
|
+
|
|
7
|
+
# Description
|
|
8
|
+
|
|
9
|
+
Connects to Lasso demand source to fetch bids.
|
|
10
|
+
Only banner format supported.
|
|
11
|
+
|
|
12
|
+
# Test Parameters
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
var adUnits = [{
|
|
16
|
+
code: 'banner-ad-unit',
|
|
17
|
+
mediaTypes: {
|
|
18
|
+
banner: {
|
|
19
|
+
sizes: [[300, 250]],
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
bids: [{
|
|
23
|
+
bidder: 'lasso',
|
|
24
|
+
params: {
|
|
25
|
+
adUnitId: '0'
|
|
26
|
+
}
|
|
27
|
+
}]
|
|
28
|
+
}];
|
|
29
|
+
```
|
|
@@ -11,7 +11,7 @@ import {submodule} from '../src/hook.js'
|
|
|
11
11
|
import {getStorageManager} from '../src/storageManager.js';
|
|
12
12
|
|
|
13
13
|
const MODULE_NAME = 'merkleId';
|
|
14
|
-
const ID_URL = 'https://
|
|
14
|
+
const ID_URL = 'https://prebid.sv.rkdms.com/identity/';
|
|
15
15
|
const DEFAULT_REFRESH = 7 * 3600;
|
|
16
16
|
const SESSION_COOKIE_NAME = '_svsid';
|
|
17
17
|
|
|
@@ -30,19 +30,19 @@ function getSession(configParams) {
|
|
|
30
30
|
function setCookie(name, value, expires) {
|
|
31
31
|
let expTime = new Date();
|
|
32
32
|
expTime.setTime(expTime.getTime() + expires * 1000 * 60);
|
|
33
|
-
storage.setCookie(name, value, expTime.toUTCString());
|
|
33
|
+
storage.setCookie(name, value, expTime.toUTCString(), 'Lax');
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
function setSession(storage, response) {
|
|
37
|
-
logInfo('Merkle setting
|
|
38
|
-
if (response && response
|
|
39
|
-
setCookie(SESSION_COOKIE_NAME, response
|
|
37
|
+
logInfo('Merkle setting ' + `${SESSION_COOKIE_NAME}`);
|
|
38
|
+
if (response && response[SESSION_COOKIE_NAME] && typeof response[SESSION_COOKIE_NAME] === 'string') {
|
|
39
|
+
setCookie(SESSION_COOKIE_NAME, response[SESSION_COOKIE_NAME], storage.expires);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
function constructUrl(configParams) {
|
|
44
44
|
const session = getSession(configParams);
|
|
45
|
-
let url = configParams.endpoint + `?
|
|
45
|
+
let url = configParams.endpoint + `?sv_domain=${configParams.sv_domain}&sv_pubid=${configParams.sv_pubid}&ssp_ids=${configParams.ssp_ids.join()}`;
|
|
46
46
|
if (session) {
|
|
47
47
|
url = `${url}&sv_session=${session}`;
|
|
48
48
|
}
|
|
@@ -86,45 +86,52 @@ function generateId(configParams, configStorage) {
|
|
|
86
86
|
/** @type {Submodule} */
|
|
87
87
|
export const merkleIdSubmodule = {
|
|
88
88
|
/**
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
* used to link submodule with config
|
|
90
|
+
* @type {string}
|
|
91
|
+
*/
|
|
92
92
|
name: MODULE_NAME,
|
|
93
|
+
|
|
93
94
|
/**
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
* decode the stored id value for passing to bid requests
|
|
96
|
+
* @function
|
|
97
|
+
* @param {string} value
|
|
98
|
+
* @returns {{eids:arrayofields}}
|
|
99
|
+
*/
|
|
99
100
|
decode(value) {
|
|
101
|
+
// Legacy support for a single id
|
|
100
102
|
const id = (value && value.pam_id && typeof value.pam_id.id === 'string') ? value.pam_id : undefined;
|
|
101
103
|
logInfo('Merkle id ' + JSON.stringify(id));
|
|
102
|
-
|
|
104
|
+
|
|
105
|
+
if (id) {
|
|
106
|
+
return {'merkleId': id}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Supports multiple IDs for different SSPs
|
|
110
|
+
const merkleIds = (value && value?.merkleId && Array.isArray(value.merkleId)) ? value.merkleId : undefined;
|
|
111
|
+
logInfo('merkleIds: ' + JSON.stringify(merkleIds));
|
|
112
|
+
|
|
113
|
+
return merkleIds ? {'merkleId': merkleIds} : undefined;
|
|
103
114
|
},
|
|
115
|
+
|
|
104
116
|
/**
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
117
|
+
* performs action to obtain id and return a value in the callback's response argument
|
|
118
|
+
* @function
|
|
119
|
+
* @param {SubmoduleConfig} [config]
|
|
120
|
+
* @param {ConsentData} [consentData]
|
|
121
|
+
* @returns {IdResponse|undefined}
|
|
122
|
+
*/
|
|
111
123
|
getId(config, consentData) {
|
|
112
124
|
logInfo('User ID - merkleId generating id');
|
|
113
125
|
|
|
114
126
|
const configParams = (config && config.params) || {};
|
|
115
127
|
|
|
116
|
-
if (
|
|
117
|
-
logError('User ID - merkleId submodule requires a valid
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (typeof configParams.sv_cid !== 'string') {
|
|
122
|
-
logError('User ID - merkleId submodule requires a valid sv_cid string to be defined');
|
|
128
|
+
if (typeof configParams.sv_pubid !== 'string') {
|
|
129
|
+
logError('User ID - merkleId submodule requires a valid sv_pubid string to be defined');
|
|
123
130
|
return;
|
|
124
131
|
}
|
|
125
132
|
|
|
126
|
-
if (
|
|
127
|
-
logError('User ID - merkleId submodule requires a valid
|
|
133
|
+
if (!Array.isArray(configParams.ssp_ids)) {
|
|
134
|
+
logError('User ID - merkleId submodule requires a valid ssp_ids array to be defined');
|
|
128
135
|
return;
|
|
129
136
|
}
|
|
130
137
|
|
|
@@ -132,6 +139,7 @@ export const merkleIdSubmodule = {
|
|
|
132
139
|
logError('User ID - merkleId submodule does not currently handle consent strings');
|
|
133
140
|
return;
|
|
134
141
|
}
|
|
142
|
+
|
|
135
143
|
if (typeof configParams.endpoint !== 'string') {
|
|
136
144
|
logWarn('User ID - merkleId submodule endpoint string is not defined');
|
|
137
145
|
configParams.endpoint = ID_URL
|
|
@@ -146,7 +154,7 @@ export const merkleIdSubmodule = {
|
|
|
146
154
|
return {callback: resp};
|
|
147
155
|
},
|
|
148
156
|
extendId: function (config = {}, consentData, storedId) {
|
|
149
|
-
logInfo('User ID -
|
|
157
|
+
logInfo('User ID - stored id ' + storedId);
|
|
150
158
|
const configParams = (config && config.params) || {};
|
|
151
159
|
|
|
152
160
|
if (typeof configParams.endpoint !== 'string') {
|
|
@@ -162,15 +170,18 @@ export const merkleIdSubmodule = {
|
|
|
162
170
|
if (typeof configParams.sv_domain !== 'string') {
|
|
163
171
|
configParams.sv_domain = merkleIdSubmodule.findRootDomain();
|
|
164
172
|
}
|
|
173
|
+
|
|
165
174
|
const configStorage = (config && config.storage) || {};
|
|
166
175
|
if (configStorage && configStorage.refreshInSeconds && typeof configParams.refreshInSeconds === 'number') {
|
|
167
176
|
return {id: storedId};
|
|
168
177
|
}
|
|
178
|
+
|
|
169
179
|
let refreshInSeconds = DEFAULT_REFRESH;
|
|
170
180
|
if (configParams && configParams.refreshInSeconds && typeof configParams.refreshInSeconds === 'number') {
|
|
171
181
|
refreshInSeconds = configParams.refreshInSeconds;
|
|
172
182
|
logInfo('User ID - merkleId param refreshInSeconds' + refreshInSeconds);
|
|
173
183
|
}
|
|
184
|
+
|
|
174
185
|
const storedDate = new Date(storedId.date);
|
|
175
186
|
let refreshNeeded = false;
|
|
176
187
|
if (storedDate) {
|
|
@@ -181,6 +192,7 @@ export const merkleIdSubmodule = {
|
|
|
181
192
|
return {callback: resp};
|
|
182
193
|
}
|
|
183
194
|
}
|
|
195
|
+
|
|
184
196
|
logInfo('User ID - merkleId not refreshed');
|
|
185
197
|
return {id: storedId};
|
|
186
198
|
}
|
package/modules/pubCommonId.js
CHANGED
|
@@ -9,7 +9,8 @@ import * as events from '../src/events.js';
|
|
|
9
9
|
import CONSTANTS from '../src/constants.json';
|
|
10
10
|
import { getStorageManager } from '../src/storageManager.js';
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const MODULE_TYPE = 'fpid-module';
|
|
13
|
+
const storage = getStorageManager({moduleType: MODULE_TYPE});
|
|
13
14
|
|
|
14
15
|
const ID_NAME = '_pubcid';
|
|
15
16
|
const OPTOUT_NAME = '_pubcid_optout';
|