prebid.js 8.5.0 → 8.6.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.
Files changed (174) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/33acrossIdSystem.js +1 -1
  3. package/dist/adagioBidAdapter.js +1 -1
  4. package/dist/adbookpspBidAdapter.js +1 -1
  5. package/dist/adgenerationBidAdapter.js +1 -1
  6. package/dist/adqueryBidAdapter.js +1 -1
  7. package/dist/adrelevantisBidAdapter.js +1 -1
  8. package/dist/adsinteractiveBidAdapter.js +1 -1
  9. package/dist/adtrgtmeBidAdapter.js +1 -1
  10. package/dist/adxcgBidAdapter.js +1 -1
  11. package/dist/adyoulikeBidAdapter.js +1 -1
  12. package/dist/ajaBidAdapter.js +1 -1
  13. package/dist/amxBidAdapter.js +1 -1
  14. package/dist/amxIdSystem.js +1 -1
  15. package/dist/appierAnalyticsAdapter.js +1 -1
  16. package/dist/appnexusBidAdapter.js +1 -1
  17. package/dist/asoBidAdapter.js +1 -1
  18. package/dist/axonixBidAdapter.js +1 -1
  19. package/dist/bidglassBidAdapter.js +1 -1
  20. package/dist/big-richmediaBidAdapter.js +1 -1
  21. package/dist/bridBidAdapter.js +1 -1
  22. package/dist/bridgewellBidAdapter.js +1 -1
  23. package/dist/brightMountainMediaBidAdapter.js +1 -1
  24. package/dist/carodaBidAdapter.js +1 -1
  25. package/dist/chtnwBidAdapter.js +1 -1
  26. package/dist/concertBidAdapter.js +1 -1
  27. package/dist/connectadBidAdapter.js +1 -1
  28. package/dist/consumableBidAdapter.js +1 -1
  29. package/dist/conversantAnalyticsAdapter.js +1 -1
  30. package/dist/conversantBidAdapter.js +1 -1
  31. package/dist/craftBidAdapter.js +1 -1
  32. package/dist/criteoBidAdapter.js +1 -1
  33. package/dist/cwireBidAdapter.js +1 -1
  34. package/dist/dependencies.json +3 -0
  35. package/dist/dspxBidAdapter.js +1 -1
  36. package/dist/eplanningBidAdapter.js +1 -1
  37. package/dist/euidIdSystem.js +1 -1
  38. package/dist/feedadBidAdapter.js +1 -1
  39. package/dist/finativeBidAdapter.js +1 -1
  40. package/dist/freewheel-sspBidAdapter.js +1 -1
  41. package/dist/gmosspBidAdapter.js +1 -1
  42. package/dist/goldbachBidAdapter.js +1 -1
  43. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  44. package/dist/greenbidsRtdProvider.js +1 -1
  45. package/dist/gridBidAdapter.js +1 -1
  46. package/dist/growthCodeAnalyticsAdapter.js +1 -1
  47. package/dist/gumgumBidAdapter.js +1 -1
  48. package/dist/h12mediaBidAdapter.js +1 -1
  49. package/dist/hypelabBidAdapter.js +1 -1
  50. package/dist/id5IdSystem.js +1 -1
  51. package/dist/imdsBidAdapter.js +1 -1
  52. package/dist/improvedigitalBidAdapter.js +1 -1
  53. package/dist/insticatorBidAdapter.js +1 -1
  54. package/dist/ixBidAdapter.js +1 -1
  55. package/dist/justpremiumBidAdapter.js +1 -1
  56. package/dist/kargoBidAdapter.js +1 -1
  57. package/dist/konduitAnalyticsAdapter.js +1 -1
  58. package/dist/kueezBidAdapter.js +1 -1
  59. package/dist/kueezRtbBidAdapter.js +1 -1
  60. package/dist/kulturemediaBidAdapter.js +1 -1
  61. package/dist/lassoBidAdapter.js +1 -1
  62. package/dist/lifestreetBidAdapter.js +1 -1
  63. package/dist/logicadBidAdapter.js +1 -1
  64. package/dist/loglyliftBidAdapter.js +1 -1
  65. package/dist/magniteAnalyticsAdapter.js +1 -1
  66. package/dist/malltvAnalyticsAdapter.js +1 -1
  67. package/dist/marsmediaBidAdapter.js +1 -1
  68. package/dist/mediafuseBidAdapter.js +1 -1
  69. package/dist/mediasquareBidAdapter.js +1 -1
  70. package/dist/mgidBidAdapter.js +1 -1
  71. package/dist/minutemediaBidAdapter.js +1 -1
  72. package/dist/minutemediaplusBidAdapter.js +1 -1
  73. package/dist/mspa.js +1 -1
  74. package/dist/newspassidBidAdapter.js +1 -1
  75. package/dist/nexx360BidAdapter.js +1 -1
  76. package/dist/not-for-prod/prebid.js +135 -133
  77. package/dist/oguryBidAdapter.js +1 -1
  78. package/dist/onetagBidAdapter.js +1 -1
  79. package/dist/ooloAnalyticsAdapter.js +1 -1
  80. package/dist/optidigitalBidAdapter.js +1 -1
  81. package/dist/outbrainBidAdapter.js +1 -1
  82. package/dist/parrableIdSystem.js +1 -1
  83. package/dist/pixfutureBidAdapter.js +1 -1
  84. package/dist/prebid-core.js +1 -1
  85. package/dist/pubCircleBidAdapter.js +1 -0
  86. package/dist/publinkIdSystem.js +1 -1
  87. package/dist/pubmaticBidAdapter.js +1 -1
  88. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  89. package/dist/pxyzBidAdapter.js +1 -1
  90. package/dist/quantcastBidAdapter.js +1 -1
  91. package/dist/readpeakBidAdapter.js +1 -1
  92. package/dist/relaidoBidAdapter.js +1 -1
  93. package/dist/relevadRtdProvider.js +1 -1
  94. package/dist/retailspotBidAdapter.js +1 -1
  95. package/dist/rhythmoneBidAdapter.js +1 -1
  96. package/dist/riseBidAdapter.js +1 -1
  97. package/dist/rubiconBidAdapter.js +1 -1
  98. package/dist/seedingAllianceBidAdapter.js +1 -1
  99. package/dist/seedtagBidAdapter.js +1 -1
  100. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  101. package/dist/sharethroughBidAdapter.js +1 -1
  102. package/dist/shinezBidAdapter.js +1 -1
  103. package/dist/smaatoBidAdapter.js +1 -1
  104. package/dist/smartadserverBidAdapter.js +1 -1
  105. package/dist/smartxBidAdapter.js +1 -1
  106. package/dist/smilewantedBidAdapter.js +1 -1
  107. package/dist/sonobiBidAdapter.js +1 -1
  108. package/dist/sovrnAnalyticsAdapter.js +1 -1
  109. package/dist/sovrnBidAdapter.js +1 -1
  110. package/dist/ssmasBidAdapter.js +1 -1
  111. package/dist/sspBCBidAdapter.js +1 -1
  112. package/dist/stvBidAdapter.js +1 -1
  113. package/dist/sublimeBidAdapter.js +1 -1
  114. package/dist/tappxBidAdapter.js +1 -1
  115. package/dist/targetVideoBidAdapter.js +1 -1
  116. package/dist/teadsBidAdapter.js +1 -1
  117. package/dist/topicsFpdModule.js +1 -1
  118. package/dist/trionBidAdapter.js +1 -1
  119. package/dist/tripleliftBidAdapter.js +1 -1
  120. package/dist/ttdBidAdapter.js +1 -1
  121. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  122. package/dist/uid2IdSystem.js +1 -1
  123. package/dist/underdogmediaBidAdapter.js +1 -1
  124. package/dist/undertoneBidAdapter.js +1 -1
  125. package/dist/viantOrtbBidAdapter.js +1 -0
  126. package/dist/vidazooBidAdapter.js +1 -1
  127. package/dist/videobyteBidAdapter.js +1 -1
  128. package/dist/videojsVideoProvider.js +1 -1
  129. package/dist/visxBidAdapter.js +1 -1
  130. package/dist/vuukleBidAdapter.js +1 -1
  131. package/dist/widespaceBidAdapter.js +1 -1
  132. package/dist/winrBidAdapter.js +1 -1
  133. package/dist/yahoosspBidAdapter.js +1 -1
  134. package/dist/yieldmoBidAdapter.js +1 -1
  135. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  136. package/integrationExamples/videoModule/jwplayer/bidMarkedAsUsed.html +1 -1
  137. package/integrationExamples/videoModule/jwplayer/bidRequestScheduling.html +1 -1
  138. package/integrationExamples/videoModule/jwplayer/bidsBackHandlerOverride.html +137 -0
  139. package/integrationExamples/videoModule/jwplayer/eventListeners.html +1 -1
  140. package/integrationExamples/videoModule/jwplayer/eventsUI.html +1 -1
  141. package/integrationExamples/videoModule/jwplayer/gamAdServerMediation.html +1 -1
  142. package/integrationExamples/videoModule/jwplayer/mediaMetadata.html +1 -1
  143. package/integrationExamples/videoModule/jwplayer/playlist.html +1 -1
  144. package/integrationExamples/videoModule/videojs/bidsBackHandlerOverride.html +164 -0
  145. package/libraries/mspa/activityControls.js +51 -32
  146. package/modules/adgenerationBidAdapter.js +3 -3
  147. package/modules/adsinteractiveBidAdapter.js +2 -2
  148. package/modules/appnexusBidAdapter.js +1 -1
  149. package/modules/criteoBidAdapter.js +18 -0
  150. package/modules/cwireBidAdapter.js +19 -0
  151. package/modules/growthCodeAnalyticsAdapter.js +7 -2
  152. package/modules/newspassid.md +76 -0
  153. package/modules/newspassidBidAdapter.js +44 -18
  154. package/modules/pubCircleBidAdapter.js +231 -0
  155. package/modules/pubCircleBidAdapter.md +79 -0
  156. package/modules/relevadRtdProvider.js +6 -7
  157. package/modules/ssmasBidAdapter.js +2 -2
  158. package/modules/tappxBidAdapter.js +10 -1
  159. package/modules/tappxBidAdapter.md +17 -0
  160. package/modules/topicsFpdModule.js +21 -48
  161. package/modules/viantOrtbBidAdapter.js +113 -0
  162. package/modules/viantOrtbBidAdapter.md +54 -0
  163. package/modules/vidazooBidAdapter.js +9 -2
  164. package/modules/videojsVideoProvider.js +9 -2
  165. package/package.json +1 -1
  166. package/test/spec/libraries/mspa/activityControls_spec.js +145 -212
  167. package/test/spec/modules/adgenerationBidAdapter_spec.js +6 -6
  168. package/test/spec/modules/appnexusBidAdapter_spec.js +12 -1
  169. package/test/spec/modules/criteoBidAdapter_spec.js +31 -3
  170. package/test/spec/modules/cwireBidAdapter_spec.js +47 -0
  171. package/test/spec/modules/newspassidBidAdapter_spec.js +6 -0
  172. package/test/spec/modules/pubCircleBidAdapter_spec.js +399 -0
  173. package/test/spec/modules/topicsFpdModule_spec.js +343 -365
  174. package/test/spec/modules/viantOrtbBidAdapter_spec.js +432 -0
@@ -8,7 +8,13 @@ import {
8
8
  import {gppDataHandler} from '../../src/adapterManager.js';
9
9
 
10
10
  // default interpretation for MSPA consent(s):
11
- // https://docs.google.com/document/d/1yPEVx3bBdSkIw-QNkQR5qi1ztmn9zoXk-LaGQB6iw7Q
11
+ // https://docs.prebid.org/features/mspa-usnat.html
12
+
13
+ const SENSITIVE_DATA_GEO = 7;
14
+
15
+ function isApplicable(val) {
16
+ return val != null && val !== 0
17
+ }
12
18
 
13
19
  export function isBasicConsentDenied(cd) {
14
20
  // service provider mode is always consent denied
@@ -18,47 +24,60 @@ export function isBasicConsentDenied(cd) {
18
24
  // minors 13+ who have not given consent
19
25
  cd.KnownChildSensitiveDataConsents[0] === 1 ||
20
26
  // minors under 13 cannot consent
21
- cd.KnownChildSensitiveDataConsents[1] !== 0 ||
22
- // sensitive category consent impossible without notice
23
- (cd.SensitiveDataProcessing.some(element => element === 2) && (cd.SensitiveDataLimitUseNotice !== 1 || cd.SensitiveDataProcessingOptOutNotice !== 1));
27
+ isApplicable(cd.KnownChildSensitiveDataConsents[1]);
24
28
  }
25
29
 
26
- export function isSensitiveNoticeMissing(cd) {
27
- return ['SensitiveDataProcessingOptOutNotice', 'SensitiveDataLimitUseNotice'].some(prop => cd[prop] === 2)
30
+ export function sensitiveNoticeIs(cd, value) {
31
+ return ['SensitiveDataProcessingOptOutNotice', 'SensitiveDataLimitUseNotice'].some(prop => cd[prop] === value)
28
32
  }
29
33
 
30
34
  export function isConsentDenied(cd) {
31
35
  return isBasicConsentDenied(cd) ||
32
- // user opts out
33
- (['SaleOptOut', 'SharingOptOut', 'TargetedAdvertisingOptOut'].some(prop => cd[prop] === 1)) ||
34
- // notice not given
35
- (['SaleOptOutNotice', 'SharingNotice', 'SharingOptOutNotice', 'TargetedAdvertisingOptOutNotice'].some(prop => cd[prop] === 2)) ||
36
- // sale opted in but notice does not apply
37
- ((cd.SaleOptOut === 2 && cd.SaleOptOutNotice === 0)) ||
38
- // targeted opted in but notice does not apply
39
- ((cd.TargetedAdvertisingOptOut === 2 && cd.TargetedAdvertisingOptOutNotice === 0)) ||
40
- // sharing opted in but notices do not apply
41
- ((cd.SharingOptOut === 2 && (cd.SharingNotice === 0 || cd.SharingOptOutNotice === 0)));
36
+ ['Sale', 'Sharing', 'TargetedAdvertising'].some(scope => {
37
+ const oo = cd[`${scope}OptOut`];
38
+ const notice = cd[`${scope}OptOutNotice`];
39
+ // user opted out
40
+ return oo === 1 ||
41
+ // opt-out notice was not given
42
+ notice === 2 ||
43
+ // do not trust CMP if it signals opt-in but no opt-out notice was given
44
+ (oo === 2 && notice === 0);
45
+ }) ||
46
+ // no sharing notice was given ...
47
+ cd.SharingNotice === 2 ||
48
+ // ... or the CMP says it was not applicable, while also claiming it got consent
49
+ (cd.SharingOptOut === 2 && cd.SharingNotice === 0);
42
50
  }
43
51
 
44
- export function isTransmitUfpdConsentDenied(cd) {
45
- // SensitiveDataProcessing[1-5,11]=1 OR SensitiveDataProcessing[6,7,9,10,12]<>0 OR
46
- const mustBeZero = [6, 7, 9, 10, 12];
47
- const mustBeZeroSubtractedVector = mustBeZero.map((number) => number - 1);
48
- const SensitiveDataProcessingMustBeZero = cd.SensitiveDataProcessing.filter(index => mustBeZeroSubtractedVector.includes(index));
49
- const cannotBeOne = [1, 2, 3, 4, 5, 11];
50
- const cannotBeOneSubtractedVector = cannotBeOne.map((number) => number - 1);
51
- const SensitiveDataProcessingCannotBeOne = cd.SensitiveDataProcessing.filter(index => cannotBeOneSubtractedVector.includes(index));
52
- return isConsentDenied(cd) ||
53
- isSensitiveNoticeMissing(cd) ||
54
- SensitiveDataProcessingCannotBeOne.some(val => val === 1) ||
55
- SensitiveDataProcessingMustBeZero.some(val => val !== 0);
56
- }
52
+ export const isTransmitUfpdConsentDenied = (() => {
53
+ // deny anything that smells like: genetic, biometric, state/national ID, financial, union membership,
54
+ // or personal communication data
55
+ const cannotBeInScope = [6, 7, 9, 10, 12].map(el => --el);
56
+ // require consent for everything else (except geo, which is treated separately)
57
+ const allExceptGeo = Array.from(Array(12).keys()).filter((el) => el !== SENSITIVE_DATA_GEO)
58
+ const mustHaveConsent = allExceptGeo.filter(el => !cannotBeInScope.includes(el));
59
+
60
+ return function (cd) {
61
+ return isConsentDenied(cd) ||
62
+ // no notice about sensitive data was given
63
+ sensitiveNoticeIs(cd, 2) ||
64
+ // extra-sensitive data is applicable
65
+ cannotBeInScope.some(i => isApplicable(cd.SensitiveDataProcessing[i])) ||
66
+ // user opted out for not-as-sensitive data
67
+ mustHaveConsent.some(i => cd.SensitiveDataProcessing[i] === 1) ||
68
+ // CMP says it has consent, but did not give notice about it
69
+ (sensitiveNoticeIs(cd, 0) && allExceptGeo.some(i => cd.SensitiveDataProcessing[i] === 2))
70
+ }
71
+ })();
57
72
 
58
73
  export function isTransmitGeoConsentDenied(cd) {
59
- return isBasicConsentDenied(cd) ||
60
- isSensitiveNoticeMissing(cd) ||
61
- cd.SensitiveDataProcessing[7] === 1
74
+ const geoConsent = cd.SensitiveDataProcessing[SENSITIVE_DATA_GEO];
75
+ return geoConsent === 1 ||
76
+ isBasicConsentDenied(cd) ||
77
+ // no sensitive data notice was given
78
+ sensitiveNoticeIs(cd, 2) ||
79
+ // do not trust CMP if it says it has consent for geo but didn't show a sensitive data notice
80
+ (sensitiveNoticeIs(cd, 0) && geoConsent === 2)
62
81
  }
63
82
 
64
83
  const CONSENT_RULES = {
@@ -28,7 +28,7 @@ export const spec = {
28
28
  buildRequests: function (validBidRequests, bidderRequest) {
29
29
  // convert Native ORTB definition to old-style prebid native definition
30
30
  validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests);
31
- const ADGENE_PREBID_VERSION = '1.6.0';
31
+ const ADGENE_PREBID_VERSION = '1.6.1';
32
32
  let serverRequests = [];
33
33
  for (let i = 0, len = validBidRequests.length; i < len; i++) {
34
34
  const validReq = validBidRequests[i];
@@ -59,9 +59,9 @@ export const spec = {
59
59
  data = tryAppendQueryString(data, 'adgext_id5_id_link_type', id5LinkType);
60
60
  data = tryAppendQueryString(data, 'adgext_imuid', imuid);
61
61
  data = tryAppendQueryString(data, 'adgext_uid2', validReq.userId ? validReq.userId.uid2 : null);
62
- data = tryAppendQueryString(data, 'gpid', gpid ? encodeURIComponent(gpid) : null);
62
+ data = tryAppendQueryString(data, 'gpid', gpid || null);
63
63
  data = tryAppendQueryString(data, 'uach', sua ? JSON.stringify(sua) : null);
64
- data = tryAppendQueryString(data, 'schain', validReq.schain ? encodeURIComponent(JSON.stringify(validReq.schain)) : null);
64
+ data = tryAppendQueryString(data, 'schain', validReq.schain ? JSON.stringify(validReq.schain) : null);
65
65
 
66
66
  // native以外にvideo等の対応が入った場合は要修正
67
67
  if (!validReq.mediaTypes || !validReq.mediaTypes.native) {
@@ -6,8 +6,8 @@ import { registerBidder } from '../src/adapters/bidderFactory.js';
6
6
  import { BANNER } from '../src/mediaTypes.js';
7
7
 
8
8
  const ADSINTERACTIVE_CODE = 'adsinteractive';
9
- const USER_SYNC_URL_IMAGE = 'https://pb.adsinteractive.com/img';
10
- const USER_SYNC_URL_IFRAME = 'https://pb.adsinteractive.com/sync';
9
+ const USER_SYNC_URL_IMAGE = 'https://sync.adsinteractive.com/img';
10
+ const USER_SYNC_URL_IFRAME = 'https://sync.adsinteractive.com/sync';
11
11
 
12
12
  export const spec = {
13
13
  code: ADSINTERACTIVE_CODE,
@@ -788,7 +788,7 @@ function bidToTag(bid) {
788
788
  tag.keywords = auKeywords;
789
789
  }
790
790
 
791
- let gpid = deepAccess(bid, 'ortb2Imp.ext.data.pbadslot');
791
+ let gpid = deepAccess(bid, 'ortb2Imp.ext.gpid') || deepAccess(bid, 'ortb2Imp.ext.data.pbadslot');
792
792
  if (gpid) {
793
793
  tag.gpid = gpid;
794
794
  }
@@ -10,6 +10,7 @@ import { getRefererInfo } from '../src/refererDetection.js';
10
10
  import { hasPurpose1Consent } from '../src/utils/gpdr.js';
11
11
  import { Renderer } from '../src/Renderer.js';
12
12
  import { OUTSTREAM } from '../src/video.js';
13
+ import { ajax } from '../src/ajax.js';
13
14
 
14
15
  const GVLID = 91;
15
16
  export const ADAPTER_VERSION = 36;
@@ -306,6 +307,23 @@ export const spec = {
306
307
  adapter.handleSetTargeting(bid);
307
308
  }
308
309
  },
310
+
311
+ /**
312
+ * @param {BidRequest[]} bidRequests
313
+ */
314
+ onDataDeletionRequest: (bidRequests) => {
315
+ const id = readFromAllStorages(BUNDLE_COOKIE_NAME);
316
+ if (id) {
317
+ deleteFromAllStorages(BUNDLE_COOKIE_NAME);
318
+ }
319
+ ajax('https://privacy.criteo.com/api/privacy/datadeletionrequest',
320
+ null,
321
+ JSON.stringify({ publisherUserId: id }),
322
+ {
323
+ contentType: 'application/json',
324
+ method: 'POST'
325
+ });
326
+ }
309
327
  };
310
328
 
311
329
  function readFromAllStorages(name) {
@@ -2,6 +2,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js';
2
2
  import {getStorageManager} from '../src/storageManager.js';
3
3
  import {BANNER} from '../src/mediaTypes.js';
4
4
  import {generateUUID, getParameterByName, isNumber, logError, logInfo} from '../src/utils.js';
5
+ import {hasPurpose1Consent} from '../src/utils/gpdr.js';
5
6
 
6
7
  // ------------------------------------
7
8
  const BIDDER_CODE = 'cwire';
@@ -230,5 +231,23 @@ export const spec = {
230
231
  navigator.sendBeacon(EVENT_ENDPOINT, JSON.stringify(event))
231
232
  },
232
233
 
234
+ getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) {
235
+ logInfo('Collecting user-syncs: ', JSON.stringify({syncOptions, gdprConsent, uspConsent, serverResponses}));
236
+
237
+ const syncs = []
238
+ if (hasPurpose1Consent(gdprConsent)) {
239
+ logInfo('GDPR purpose 1 consent was given, adding user-syncs')
240
+ let type = (syncOptions.pixelEnabled) ? 'image' : null ?? (syncOptions.iframeEnabled) ? 'iframe' : null
241
+ if (type) {
242
+ syncs.push({
243
+ type: type,
244
+ url: 'https://ib.adnxs.com/getuid?https://prebid.cwi.re/v1/cookiesync?xandrId=$UID'
245
+ })
246
+ }
247
+ }
248
+ logInfo('Collected user-syncs: ', JSON.stringify({syncs}))
249
+ return syncs
250
+ }
251
+
233
252
  };
234
253
  registerBidder(spec);
@@ -30,8 +30,8 @@ let bidRequestTimeout = 0;
30
30
  let analyticsType = 'endpoint';
31
31
 
32
32
  let growthCodeAnalyticsAdapter = Object.assign(adapter({url: url, analyticsType}), {
33
- track({eventType, eventData}) {
34
- eventData = eventData ? JSON.parse(JSON.stringify(eventData)) : {};
33
+ track({eventType, args}) {
34
+ let eventData = args ? JSON.parse(JSON.stringify(args)) : {};
35
35
  let data = {};
36
36
  if (!trackEvents.includes(eventType)) return;
37
37
  switch (eventType) {
@@ -98,6 +98,11 @@ let growthCodeAnalyticsAdapter = Object.assign(adapter({url: url, analyticsType}
98
98
  break;
99
99
  }
100
100
 
101
+ case CONSTANTS.EVENTS.NO_BID: {
102
+ data = eventData
103
+ break;
104
+ }
105
+
101
106
  default:
102
107
  return;
103
108
  }
@@ -0,0 +1,76 @@
1
+ ---
2
+ Module Name: NewspassId Bidder Adapter
3
+ Module Type: Bidder Adapter
4
+ Maintainer: techsupport@newspassid.com
5
+ layout: bidder
6
+ title: Newspass ID
7
+ description: LMC Newspass ID Prebid JS Bidder Adapter
8
+ biddercode: newspassid
9
+ gdpr_supported: false
10
+ gvl_id: none
11
+ usp_supported: true
12
+ coppa_supported: false
13
+ schain_supported: true
14
+ dchain_supported: false
15
+ userIds: criteo, id5Id, tdid, identityLink, liveIntentId, parrableId, pubCommonId, lotamePanoramaId, sharedId, fabrickId
16
+ media_types: banner
17
+ safeframes_ok: true
18
+ deals_supported: true
19
+ floors_supported: false
20
+ fpd_supported: false
21
+ pbjs: true
22
+ pbs: false
23
+ prebid_member: false
24
+ multiformat_supported: will-bid-on-any
25
+ ---
26
+
27
+ ### Description
28
+
29
+ LMC Newspass ID Prebid JS Bidder Adapter that connects to the NewspassId demand source(s).
30
+
31
+ The Newspass bid adapter supports Banner mediaTypes ONLY.
32
+ This is intended for USA audiences only, and does not support GDPR
33
+
34
+
35
+ ### Bid Params
36
+
37
+ {: .table .table-bordered .table-striped }
38
+
39
+ | Name | Scope | Description | Example | Type |
40
+ |-----------|----------|---------------------------|------------|----------|
41
+ | `siteId` | required | The site ID. | `"NPID0000001"` | `string` |
42
+ | `publisherId` | required | The publisher ID. | `"4204204201"` | `string` |
43
+ | `placementId` | required | The placement ID. | `"0420420421"` | `string` |
44
+ | `customData` | optional | publisher key-values used for targeting | `[{"settings":{},"targeting":{"key1": "value1", "key2": "value2"}}], ` | `array` |
45
+
46
+ ### Test Parameters
47
+
48
+
49
+ A test ad unit that will consistently return test creatives:
50
+
51
+ ```
52
+
53
+ //Banner adUnit
54
+
55
+ adUnits = [{
56
+ code: 'id-of-your-banner-div',
57
+ mediaTypes: {
58
+ banner: {
59
+ sizes: [[300, 250], [300,600]]
60
+ }
61
+ },
62
+ bids: [{
63
+ bidder: 'newspassid',
64
+ params: {
65
+ publisherId: 'NEWSPASS0001', /* an ID to identify the publisher account - required */
66
+ siteId: '4204204201', /* An ID used to identify a site within a publisher account - required */
67
+ placementId: '8000000015', /* an ID used to identify the piece of inventory - required - for appnexus test use 13144370. */
68
+ customData: [{"settings": {}, "targeting": {"key": "value", "key2": ["value1", "value2"]}}],/* optional array with 'targeting' placeholder for passing publisher specific key-values for targeting. */
69
+ }
70
+ }]
71
+ }];
72
+ ```
73
+
74
+ ### Note:
75
+
76
+ Please contact us at techsupport@newspassid.com for any assistance testing your implementation before going live into production.
@@ -1,15 +1,24 @@
1
- import {contains, deepAccess, deepSetValue, isArray, logError, logInfo, logWarn, parseUrl} from '../src/utils.js';
2
- import {registerBidder} from '../src/adapters/bidderFactory.js';
3
- import {BANNER, NATIVE} from '../src/mediaTypes.js';
1
+ import {
2
+ logInfo,
3
+ logError,
4
+ deepAccess,
5
+ logWarn,
6
+ deepSetValue,
7
+ isArray,
8
+ contains,
9
+ parseUrl,
10
+ generateUUID
11
+ } from '../src/utils.js';
12
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
13
+ import { BANNER, NATIVE } from '../src/mediaTypes.js';
4
14
  import {config} from '../src/config.js';
5
15
  import {getPriceBucketString} from '../src/cpmBucketManager.js';
6
16
  import {getRefererInfo} from '../src/refererDetection.js';
7
-
8
17
  const BIDDER_CODE = 'newspassid';
9
18
  const ORIGIN = 'https://bidder.newspassid.com' // applies only to auction & cookie
10
19
  const AUCTIONURI = '/openrtb2/auction';
11
20
  const NEWSPASSCOOKIESYNC = '/static/load-cookie.html';
12
- const NEWSPASSVERSION = '1.0.1';
21
+ const NEWSPASSVERSION = '1.1.4';
13
22
  export const spec = {
14
23
  version: NEWSPASSVERSION,
15
24
  code: BIDDER_CODE,
@@ -155,7 +164,7 @@ export const spec = {
155
164
  let placementId = placementIdOverrideFromGetParam || this.getPlacementId(npBidRequest); // prefer to use a valid override param, else the bidRequest placement Id
156
165
  obj.id = npBidRequest.bidId; // this causes an error if we change it to something else, even if you update the bidRequest object: "WARNING: Bidder newspass made bid for unknown request ID: mb7953.859498327448. Ignoring."
157
166
  obj.tagid = placementId;
158
- let parsed = parseUrl(getRefererInfo().page);
167
+ let parsed = parseUrl(this.getRefererInfo().page);
159
168
  obj.secure = parsed.protocol === 'https' ? 1 : 0;
160
169
  let arrBannerSizes = [];
161
170
  if (!npBidRequest.hasOwnProperty('mediaTypes')) {
@@ -189,7 +198,6 @@ export const spec = {
189
198
  deepSetValue(obj, 'ext.prebid', {'storedrequest': {'id': placementId}});
190
199
  obj.ext['newspassid'] = {};
191
200
  obj.ext['newspassid'].adUnitCode = npBidRequest.adUnitCode; // eg. 'mpu'
192
- obj.ext['newspassid'].transactionId = npBidRequest.transactionId; // this is the transactionId PER adUnit, common across bidders for this unit
193
201
  if (npBidRequest.params.hasOwnProperty('customData')) {
194
202
  obj.ext['newspassid'].customData = npBidRequest.params.customData;
195
203
  }
@@ -216,6 +224,10 @@ export const spec = {
216
224
  if (!schain && deepAccess(npBidRequest, 'schain')) {
217
225
  schain = npBidRequest.schain;
218
226
  }
227
+ let gpid = deepAccess(npBidRequest, 'ortb2Imp.ext.gpid');
228
+ if (gpid) {
229
+ deepSetValue(obj, 'ext.gpid', gpid);
230
+ }
219
231
  return obj;
220
232
  });
221
233
  let extObj = {};
@@ -240,7 +252,7 @@ export const spec = {
240
252
  let userExtEids = deepAccess(validBidRequests, '0.userIdAsEids', []); // generate the UserIDs in the correct format for UserId module
241
253
  npRequest.site = {
242
254
  'publisher': {'id': htmlParams.publisherId},
243
- 'page': getRefererInfo().page,
255
+ 'page': this.getRefererInfo().page,
244
256
  'id': htmlParams.siteId
245
257
  };
246
258
  npRequest.test = config.getConfig('debug') ? 1 : 0;
@@ -259,12 +271,9 @@ export const spec = {
259
271
  }
260
272
  if (singleRequest) {
261
273
  logInfo('buildRequests starting to generate response for a single request');
262
- // TODO: fix auctionId & transactionId leak: https://github.com/prebid/Prebid.js/issues/9781
263
- npRequest.id = bidderRequest.auctionId; // Unique ID of the bid request, provided by the exchange.
264
- npRequest.auctionId = bidderRequest.auctionId; // not sure if this should be here?
274
+ npRequest.id = generateUUID(); // Unique ID of the bid request, provided by the exchange. (REQUIRED)
265
275
  npRequest.imp = tosendtags;
266
276
  npRequest.ext = extObj;
267
- deepSetValue(npRequest, 'source.tid', bidderRequest.auctionId);// RTB 2.5 : tid is Transaction ID that must be common across all participants in this bid request (e.g., potentially multiple exchanges).
268
277
  deepSetValue(npRequest, 'user.ext.eids', userExtEids);
269
278
  var ret = {
270
279
  method: 'POST',
@@ -280,12 +289,9 @@ export const spec = {
280
289
  let arrRet = tosendtags.map(imp => {
281
290
  logInfo('buildRequests starting to generate non-single response, working on imp : ', imp);
282
291
  let npRequestSingle = Object.assign({}, npRequest);
283
- imp.ext['newspassid'].pageAuctionId = bidderRequest['auctionId']; // make a note in the ext object of what the original auctionId was, in the bidderRequest object
284
- npRequestSingle.id = imp.ext['newspassid'].transactionId; // Unique ID of the bid request, provided by the exchange.
285
- npRequestSingle.auctionId = imp.ext['newspassid'].transactionId; // not sure if this should be here?
292
+ npRequestSingle.id = generateUUID();
286
293
  npRequestSingle.imp = [imp];
287
294
  npRequestSingle.ext = extObj;
288
- deepSetValue(npRequestSingle, 'source.tid', bidderRequest.auctionId);// RTB 2.5 : tid is Transaction ID that must be common across all participants in this bid request (e.g., potentially multiple exchanges).
289
295
  deepSetValue(npRequestSingle, 'user.ext.eids', userExtEids);
290
296
  logInfo('buildRequests RequestSingle (for non-single) = ', npRequestSingle);
291
297
  return {
@@ -305,6 +311,7 @@ export const spec = {
305
311
  logInfo(`interpretResponse time: ${startTime}. buildRequests done -> interpretResponse start was ${startTime - this.propertyBag.buildRequestsEnd}ms`);
306
312
  logInfo(`serverResponse, request`, JSON.parse(JSON.stringify(serverResponse)), JSON.parse(JSON.stringify(request)));
307
313
  serverResponse = serverResponse.body || {};
314
+ let aucId = serverResponse.id; // this will be correct for single requests and non-single
308
315
  if (!serverResponse.hasOwnProperty('seatbid')) {
309
316
  return [];
310
317
  }
@@ -351,7 +358,7 @@ export const spec = {
351
358
  logInfo(`newspassid.enhancedAdserverTargeting is set to false, no per-bid keys will be sent to adserver.`);
352
359
  }
353
360
  let {seat: winningSeat, bid: winningBid} = this.getWinnerForRequestBid(thisBid.bidId, serverResponse.seatbid);
354
- adserverTargeting['np_auc_id'] = String(request.bidderRequest.auctionId);
361
+ adserverTargeting['np_auc_id'] = String(aucId);
355
362
  adserverTargeting['np_winner'] = String(winningSeat);
356
363
  adserverTargeting['np_bid'] = 'true';
357
364
  if (enhancedAdserverTargeting) {
@@ -490,10 +497,29 @@ export const spec = {
490
497
  return null;
491
498
  },
492
499
  getGetParametersAsObject() {
493
- let parsed = parseUrl(getRefererInfo().page);
500
+ let parsed = parseUrl(this.getRefererInfo().location); // was getRefererInfo().page but this is not backwards compatible
494
501
  logInfo('getGetParametersAsObject found:', parsed.search);
495
502
  return parsed.search;
496
503
  },
504
+ getRefererInfo() {
505
+ if (getRefererInfo().hasOwnProperty('location')) {
506
+ logInfo('FOUND location on getRefererInfo OK (prebid >= 7); will use getRefererInfo for location & page');
507
+ return getRefererInfo();
508
+ } else {
509
+ logInfo('DID NOT FIND location on getRefererInfo (prebid < 7); will use legacy code that ALWAYS worked reliably to get location & page ;-)');
510
+ try {
511
+ return {
512
+ page: top.location.href,
513
+ location: top.location.href
514
+ };
515
+ } catch (e) {
516
+ return {
517
+ page: window.location.href,
518
+ location: window.location.href
519
+ };
520
+ }
521
+ }
522
+ },
497
523
  blockTheRequest() {
498
524
  let npRequest = config.getConfig('newspassid.np_request');
499
525
  if (typeof npRequest == 'boolean' && !npRequest) {