prebid.js 9.53.2 → 9.53.3
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/33acrossAnalyticsAdapter.js +1 -1
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/33acrossIdSystem.js +1 -1
- package/dist/BTBidAdapter.js +1 -1
- package/dist/adagioAnalyticsAdapter.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adagioRtdProvider.js +1 -1
- package/dist/adagioUtils.js +1 -1
- package/dist/addefendBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adlooxRtdProvider.js +1 -1
- package/dist/adqueryBidAdapter.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adstirBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgAnalyticsAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/adyoulikeBidAdapter.js +1 -1
- package/dist/agmaAnalyticsAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/aniviewBidAdapter.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/beopBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bitmediaBidAdapter.js +1 -1
- package/dist/bridBidAdapter.js +1 -1
- package/dist/bridgeuppBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/chunk-core.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/contxtfulBidAdapter.js +1 -1
- package/dist/conversantAnalyticsAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/cwireBidAdapter.js +1 -1
- package/dist/dailymotionBidAdapter.js +1 -1
- package/dist/debugging-standalone.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/dxkultureBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/equativBidAdapter.js +1 -1
- package/dist/eskimiBidAdapter.js +1 -1
- package/dist/euidIdSystem.js +1 -1
- package/dist/exadsBidAdapter.js +1 -1
- package/dist/excoBidAdapter.js +1 -1
- package/dist/feedadBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/freewheel-sspBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/greenbidsAnalyticsAdapter.js +1 -1
- package/dist/greenbidsBidAdapter.js +1 -1
- package/dist/greenbidsRtdProvider.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/hypelabBidAdapter.js +1 -1
- package/dist/id5AnalyticsAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/imdsBidAdapter.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/inmobiBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/intentIqAnalyticsAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/jixieBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/kargoBidAdapter.js +1 -1
- package/dist/kimberliteBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveIntentId.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/luceadBidAdapter.js +1 -1
- package/dist/mabidderBidAdapter.js +1 -1
- package/dist/madsenseBidAdapter.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/medianetBidAdapter.js +1 -1
- package/dist/medianetUtils.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/missenaBidAdapter.js +1 -1
- package/dist/mobilefuseBidAdapter.js +1 -1
- package/dist/nextMillenniumBidAdapter.js +1 -1
- package/dist/nexx360Utils.js +1 -1
- package/dist/nobidAnalyticsAdapter.js +1 -1
- package/dist/nobidBidAdapter.js +1 -1
- package/dist/nodalsAiRtdProvider.js +1 -1
- package/dist/not-for-prod/prebid.js +172 -172
- package/dist/objectGuard.js +1 -1
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/openxBidAdapter.js +1 -1
- package/dist/optidigitalBidAdapter.js +1 -1
- package/dist/orbidderBidAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticAnalyticsAdapter.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubmaticIdSystem.js +1 -1
- package/dist/pubmaticRtdProvider.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pubxaiAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/retailspotBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseUtils.js +1 -1
- package/dist/rtdModule.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/showheroes-bsBidAdapter.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/snigelBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sparteoBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/stvBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/taboolaBidAdapter.js +1 -1
- package/dist/tappxBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/terceptAnalyticsAdapter.js +1 -1
- package/dist/themoneytizerBidAdapter.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/unrulyBidAdapter.js +1 -1
- package/dist/userId.js +1 -1
- package/dist/vidazooUtils.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/yahooAdsBidAdapter.js +1 -1
- package/dist/yandexBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/libraries/objectGuard/objectGuard.js +149 -48
- package/libraries/objectGuard/ortbGuard.js +33 -43
- package/modules/adagioAnalyticsAdapter.js +6 -1
- package/modules/adagioBidAdapter.js +12 -5
- package/modules/adagioRtdProvider.js +41 -35
- package/modules/pubmaticAnalyticsAdapter.js +311 -587
- package/modules/pubmaticBidAdapter.js +71 -8
- package/modules/pubmaticIdSystem.js +4 -4
- package/modules/pubmaticRtdProvider.js +12 -60
- package/modules/rtdModule/index.js +1 -5
- package/modules/ttdBidAdapter.js +0 -5
- package/modules/userId/eids.js +1 -1
- package/modules/userId/index.js +32 -1
- package/package.json +1 -1
- package/src/auction.js +3 -0
- package/test/spec/activities/objectGuard_spec.js +156 -32
- package/test/spec/activities/ortbGuard_spec.js +10 -15
- package/test/spec/modules/adagioAnalyticsAdapter_spec.js +94 -24
- package/test/spec/modules/adagioRtdProvider_spec.js +17 -17
- package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +634 -916
- package/test/spec/modules/pubmaticBidAdapter_spec.js +260 -1
- package/test/spec/modules/pubmaticRtdProvider_spec.js +78 -400
- package/test/spec/modules/ttdBidAdapter_spec.js +0 -33
- package/test/spec/modules/userId_spec.js +115 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {isData,
|
|
2
|
-
import {
|
|
1
|
+
import {isData, sessionedApplies} from '../../src/activities/redactor.js';
|
|
2
|
+
import {deepEqual, logWarn} from '../../src/utils.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @typedef {import('../src/activities/redactor.js').TransformationRuleDef} TransformationRuleDef
|
|
@@ -12,66 +12,182 @@ import {deepAccess, deepClone, deepEqual, deepSetValue} from '../../src/utils.js
|
|
|
12
12
|
/**
|
|
13
13
|
* Create a factory function for object guards using the given rules.
|
|
14
14
|
*
|
|
15
|
-
* An object guard is a
|
|
16
|
-
*
|
|
17
|
-
* - `verify` is a function that, when called, will check that the guarded object was not modified
|
|
18
|
-
* in a way that violates any "write protect" rules, and rolls back any offending changes.
|
|
15
|
+
* An object guard is a view on the guarded object that applies "redact" rules (the same rules used in activites/redactor.js),
|
|
16
|
+
* and prevents writes (including deltes) that violate "write protect" rules.
|
|
19
17
|
*
|
|
20
18
|
* This is meant to provide sandboxed version of a privacy-sensitive object, where reads
|
|
21
19
|
* are filtered through redaction rules and writes are checked against write protect rules.
|
|
22
20
|
*
|
|
23
|
-
* @param {Array[TransformationRule]} rules
|
|
24
|
-
* @return {function(*, ...[*]): ObjectGuard}
|
|
25
21
|
*/
|
|
26
22
|
export function objectGuard(rules) {
|
|
27
23
|
const root = {};
|
|
28
|
-
|
|
24
|
+
|
|
25
|
+
// rules are associated with specific portions of the object, e.g. "user.eids"
|
|
26
|
+
// build a tree representation of them, where the root is the object itself,
|
|
27
|
+
// and each node's children are properties of the corresponding (nested) object.
|
|
29
28
|
|
|
30
29
|
rules.forEach(rule => {
|
|
31
|
-
if (rule.wp) writeRules.push(rule);
|
|
32
|
-
if (!rule.get) return;
|
|
33
30
|
rule.paths.forEach(path => {
|
|
34
31
|
let node = root;
|
|
35
32
|
path.split('.').forEach(el => {
|
|
36
|
-
node.children = node.children
|
|
37
|
-
node.children[el] = node.children[el]
|
|
33
|
+
node.children = node.children ?? {};
|
|
34
|
+
node.children[el] = node.children[el] ?? { parent: node, path: node.path ? `${node.path}.${el}` : el };
|
|
38
35
|
node = node.children[el];
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
node.wpRules = node.wpRules ?? [];
|
|
37
|
+
node.redactRules = node.redactRules ?? [];
|
|
38
|
+
});
|
|
39
|
+
(rule.wp ? node.wpRules : node.redactRules).push(rule);
|
|
40
|
+
if (rule.wp) {
|
|
41
|
+
// mark the whole path as write protected, so that write operations
|
|
42
|
+
// on parents do not need to walk down the tree
|
|
43
|
+
let parent = node;
|
|
44
|
+
while (parent && !parent.hasWP) {
|
|
45
|
+
parent.hasWP = true;
|
|
46
|
+
parent = parent.parent;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
41
49
|
});
|
|
42
50
|
});
|
|
43
51
|
|
|
44
|
-
|
|
52
|
+
function getRedactRule(node) {
|
|
53
|
+
if (node.redactRule == null) {
|
|
54
|
+
node.redactRule = node.redactRules.length === 0 ? false : {
|
|
55
|
+
check: (applies) => node.redactRules.some(applies),
|
|
56
|
+
get(val) {
|
|
57
|
+
for (const rule of node.redactRules) {
|
|
58
|
+
val = rule.get(val);
|
|
59
|
+
if (!isData(val)) break;
|
|
60
|
+
}
|
|
61
|
+
return val;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return node.redactRule;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getWPRule(node) {
|
|
69
|
+
if (node.wpRule == null) {
|
|
70
|
+
node.wpRule = node.wpRules.length === 0 ? false : {
|
|
71
|
+
check: (applies) => node.wpRules.some(applies),
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return node.wpRule;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* clean up `newValue` so that it doesn't violate any write protect rules
|
|
79
|
+
* when set onto the property represented by 'node'.
|
|
80
|
+
*
|
|
81
|
+
* This is done substituting (portions of) `curValue` when some rule is violated.
|
|
82
|
+
*/
|
|
83
|
+
function cleanup(node, curValue, newValue, applies) {
|
|
84
|
+
if (
|
|
85
|
+
!node.hasWP ||
|
|
86
|
+
(!isData(curValue) && !isData(newValue)) ||
|
|
87
|
+
deepEqual(curValue, newValue)
|
|
88
|
+
) {
|
|
89
|
+
return newValue;
|
|
90
|
+
}
|
|
91
|
+
const rule = getWPRule(node);
|
|
92
|
+
if (rule && rule.check(applies)) {
|
|
93
|
+
return curValue;
|
|
94
|
+
}
|
|
95
|
+
if (node.children) {
|
|
96
|
+
for (const [prop, child] of Object.entries(node.children)) {
|
|
97
|
+
const propValue = cleanup(child, curValue?.[prop], newValue?.[prop], applies);
|
|
98
|
+
if (newValue != null && typeof newValue === 'object') {
|
|
99
|
+
if (!isData(propValue) && !curValue?.hasOwnProperty(prop)) {
|
|
100
|
+
delete newValue[prop];
|
|
101
|
+
} else {
|
|
102
|
+
newValue[prop] = propValue;
|
|
103
|
+
}
|
|
104
|
+
} else {
|
|
105
|
+
logWarn(`Invalid value set for '${node.path}', expected an object`, newValue);
|
|
106
|
+
return curValue;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return newValue;
|
|
111
|
+
}
|
|
45
112
|
|
|
46
|
-
function
|
|
113
|
+
function isDeleteAllowed(node, curValue, applies) {
|
|
114
|
+
if (!node.hasWP || !isData(curValue)) {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
const rule = getWPRule(node);
|
|
118
|
+
if (rule && rule.check(applies)) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
if (node.children) {
|
|
122
|
+
for (const [prop, child] of Object.entries(node.children)) {
|
|
123
|
+
if (!isDeleteAllowed(child, curValue?.[prop], applies)) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function mkGuard(obj, tree, final, applies) {
|
|
47
132
|
return new Proxy(obj, {
|
|
48
133
|
get(target, prop, receiver) {
|
|
49
134
|
const val = Reflect.get(target, prop, receiver);
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
135
|
+
if (final && val != null && typeof val === 'object') {
|
|
136
|
+
// a parent property has write protect rules, keep guarding
|
|
137
|
+
return mkGuard(val, tree, final, applies)
|
|
138
|
+
} else if (tree.children?.hasOwnProperty(prop)) {
|
|
139
|
+
const {children, hasWP} = tree.children[prop];
|
|
140
|
+
if ((children || hasWP) && val != null && typeof val === 'object') {
|
|
141
|
+
// some nested properties have rules, return a guard for the branch
|
|
142
|
+
return mkGuard(val, tree.children?.[prop] || tree, final || children == null, applies);
|
|
143
|
+
} else if (isData(val)) {
|
|
144
|
+
// if this property has redact rules, apply them
|
|
145
|
+
const rule = getRedactRule(tree.children[prop]);
|
|
146
|
+
if (rule && rule.check(applies)) {
|
|
147
|
+
return rule.get(val);
|
|
148
|
+
}
|
|
56
149
|
}
|
|
57
150
|
}
|
|
58
151
|
return val;
|
|
59
152
|
},
|
|
153
|
+
set(target, prop, newValue, receiver) {
|
|
154
|
+
if (final) {
|
|
155
|
+
// a parent property has rules, apply them
|
|
156
|
+
const rule = getWPRule(tree);
|
|
157
|
+
if (rule && rule.check(applies)) {
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (tree.children?.hasOwnProperty(prop)) {
|
|
162
|
+
// apply all (possibly nested) write protect rules
|
|
163
|
+
const curValue = Reflect.get(target, prop, receiver);
|
|
164
|
+
newValue = cleanup(tree.children[prop], curValue, newValue, applies);
|
|
165
|
+
if (!isData(newValue) && !target.hasOwnProperty(prop)) {
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return Reflect.set(target, prop, newValue, receiver);
|
|
170
|
+
},
|
|
171
|
+
deleteProperty(target, prop) {
|
|
172
|
+
if (final) {
|
|
173
|
+
// a parent property has rules, apply them
|
|
174
|
+
const rule = getWPRule(tree);
|
|
175
|
+
if (rule && rule.check(applies)) {
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (tree.children?.hasOwnProperty(prop) && !isDeleteAllowed(tree.children[prop], target[prop], applies)) {
|
|
180
|
+
// some nested properties should not be deleted
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
return Reflect.deleteProperty(target, prop);
|
|
184
|
+
}
|
|
60
185
|
});
|
|
61
186
|
}
|
|
62
187
|
|
|
63
|
-
function mkVerify(transformResult) {
|
|
64
|
-
return function () {
|
|
65
|
-
transformResult.forEach(fn => fn());
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
188
|
return function guard(obj, ...args) {
|
|
70
189
|
const session = {};
|
|
71
|
-
return
|
|
72
|
-
obj: mkGuard(obj, root.children || {}, sessionedApplies(session, ...args)),
|
|
73
|
-
verify: mkVerify(wpTransformer(session, obj, ...args))
|
|
74
|
-
}
|
|
190
|
+
return mkGuard(obj, root, false, sessionedApplies(session, ...args))
|
|
75
191
|
};
|
|
76
192
|
}
|
|
77
193
|
|
|
@@ -82,20 +198,5 @@ export function objectGuard(rules) {
|
|
|
82
198
|
export function writeProtectRule(ruleDef) {
|
|
83
199
|
return Object.assign({
|
|
84
200
|
wp: true,
|
|
85
|
-
run(root, path, object, property, applies) {
|
|
86
|
-
const origHasProp = object && object.hasOwnProperty(property);
|
|
87
|
-
const original = origHasProp ? object[property] : undefined;
|
|
88
|
-
const origCopy = origHasProp && original != null && typeof original === 'object' ? deepClone(original) : original;
|
|
89
|
-
return function () {
|
|
90
|
-
const object = path == null ? root : deepAccess(root, path);
|
|
91
|
-
const finalHasProp = object && isData(object[property]);
|
|
92
|
-
const finalValue = finalHasProp ? object[property] : undefined;
|
|
93
|
-
if (!origHasProp && finalHasProp && applies()) {
|
|
94
|
-
delete object[property];
|
|
95
|
-
} else if ((origHasProp !== finalHasProp || finalValue !== original || !deepEqual(finalValue, origCopy)) && applies()) {
|
|
96
|
-
deepSetValue(root, (path == null ? [] : [path]).concat(property).join('.'), origCopy);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
201
|
}, ruleDef)
|
|
101
202
|
}
|
|
@@ -7,11 +7,7 @@ import {
|
|
|
7
7
|
ORTB_UFPD_PATHS
|
|
8
8
|
} from '../../src/activities/redactor.js';
|
|
9
9
|
import {objectGuard, writeProtectRule} from './objectGuard.js';
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @typedef {import('./objectGuard.js').ObjectGuard} ObjectGuard
|
|
14
|
-
*/
|
|
10
|
+
import {logError} from '../../src/utils.js';
|
|
15
11
|
|
|
16
12
|
function ortb2EnrichRules(isAllowed = isActivityAllowed) {
|
|
17
13
|
return [
|
|
@@ -32,20 +28,10 @@ export function ortb2GuardFactory(isAllowed = isActivityAllowed) {
|
|
|
32
28
|
return objectGuard(ortb2TransmitRules(isAllowed).concat(ortb2EnrichRules(isAllowed)));
|
|
33
29
|
}
|
|
34
30
|
|
|
35
|
-
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* @typedef {Function} ortb2Guard
|
|
39
|
-
* @param {{}} ortb2 ORTB object to guard
|
|
40
|
-
* @param {{}} params activity params to use for activity checks
|
|
41
|
-
* @returns {ObjectGuard}
|
|
42
|
-
*/
|
|
43
|
-
|
|
44
31
|
/*
|
|
45
32
|
* Get a guard for an ORTB object. Read access is restricted in the same way it'd be redacted (see activites/redactor.js);
|
|
46
33
|
* and writes are checked against the enrich* activites.
|
|
47
34
|
*
|
|
48
|
-
* @type ortb2Guard
|
|
49
35
|
*/
|
|
50
36
|
export const ortb2Guard = ortb2GuardFactory();
|
|
51
37
|
|
|
@@ -53,40 +39,44 @@ export function ortb2FragmentsGuardFactory(guardOrtb2 = ortb2Guard) {
|
|
|
53
39
|
return function guardOrtb2Fragments(fragments, params) {
|
|
54
40
|
fragments.global = fragments.global || {};
|
|
55
41
|
fragments.bidder = fragments.bidder || {};
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
42
|
+
const guard = {
|
|
43
|
+
global: guardOrtb2(fragments.global, params),
|
|
44
|
+
bidder: new Proxy(fragments.bidder, {
|
|
45
|
+
get(target, prop, receiver) {
|
|
46
|
+
let bidderData = Reflect.get(target, prop, receiver);
|
|
47
|
+
if (bidderData != null) {
|
|
48
|
+
bidderData = guardOrtb2(bidderData, params)
|
|
49
|
+
}
|
|
50
|
+
return bidderData;
|
|
51
|
+
},
|
|
52
|
+
set(target, prop, newValue, receiver) {
|
|
53
|
+
if (newValue == null || typeof newValue !== 'object') {
|
|
54
|
+
logError(`ortb2Fragments.bidder[bidderCode] must be an object`);
|
|
55
|
+
}
|
|
56
|
+
let bidderData = Reflect.get(target, prop, receiver);
|
|
57
|
+
if (bidderData == null) {
|
|
58
|
+
bidderData = target[prop] = {};
|
|
59
|
+
}
|
|
60
|
+
bidderData = guardOrtb2(bidderData, params);
|
|
61
|
+
Object.entries(newValue).forEach(([prop, value]) => {
|
|
62
|
+
bidderData[prop] = value;
|
|
63
|
+
})
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
})
|
|
68
67
|
};
|
|
69
68
|
|
|
70
|
-
return
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const guard = guardOrtb2(repl, params);
|
|
78
|
-
mergeDeep(guard.obj, ortb2);
|
|
79
|
-
guard.verify();
|
|
80
|
-
fragments.bidder[bidder] = repl;
|
|
81
|
-
})
|
|
82
|
-
verifiers.forEach(fn => fn());
|
|
83
|
-
}
|
|
84
|
-
}
|
|
69
|
+
return Object.defineProperties(
|
|
70
|
+
{},
|
|
71
|
+
Object.fromEntries(
|
|
72
|
+
// disallow overwriting of the top level `global` / `bidder`
|
|
73
|
+
Object.entries(guard).map(([prop, obj]) => [prop, {get: () => obj}])
|
|
74
|
+
)
|
|
75
|
+
)
|
|
85
76
|
}
|
|
86
77
|
}
|
|
87
78
|
|
|
88
79
|
/**
|
|
89
80
|
* Get a guard for an ortb2Fragments object.
|
|
90
|
-
* @type {function(*, *): ObjectGuard}
|
|
91
81
|
*/
|
|
92
82
|
export const guardOrtb2Fragments = ortb2FragmentsGuardFactory();
|
|
@@ -267,7 +267,7 @@ function handlerAuctionInit(event) {
|
|
|
267
267
|
ban_szs: bannerSizes.join(','),
|
|
268
268
|
bdrs: sortedBidderNames.join(','),
|
|
269
269
|
pgtyp: deepAccess(event.bidderRequests[0], 'ortb2.site.ext.data.pagetype', null),
|
|
270
|
-
plcmt: deepAccess(adUnits[0], 'ortb2Imp.ext.data.placement', null),
|
|
270
|
+
plcmt: deepAccess(adUnits[0], 'ortb2Imp.ext.data.adg_rtd.placement', null), // adg_rtd.placement is set by AdagioRtdProvider.
|
|
271
271
|
t_n: adgRtdSession.testName || null,
|
|
272
272
|
t_v: adgRtdSession.testVersion || null,
|
|
273
273
|
s_id: adgRtdSession.id || null,
|
|
@@ -289,6 +289,11 @@ function handlerAuctionInit(event) {
|
|
|
289
289
|
// for backward compatibility: if we didn't find organizationId & site but we have a bid from adagio we might still find it in params
|
|
290
290
|
qp.org_id = qp.org_id || adagioAdUnitBids[0].params.organizationId;
|
|
291
291
|
qp.site = qp.site || adagioAdUnitBids[0].params.site;
|
|
292
|
+
|
|
293
|
+
// `qp.plcmt` uses the value set by the AdagioRtdProvider. If not present, we fallback on the value set at the adUnit.params level.
|
|
294
|
+
if (!qp.plcmt) {
|
|
295
|
+
qp.plcmt = deepAccess(adagioAdUnitBids[0], 'params.placement', null);
|
|
296
|
+
}
|
|
292
297
|
}
|
|
293
298
|
}
|
|
294
299
|
|
|
@@ -399,11 +399,18 @@ function autoFillParams(bid) {
|
|
|
399
399
|
bid.params.site = adgGlobalConf.siteId.split(':')[1];
|
|
400
400
|
}
|
|
401
401
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
402
|
+
if (!bid.params.placement) {
|
|
403
|
+
let p = deepAccess(bid, 'ortb2Imp.ext.data.adg_rtd.placement', '');
|
|
404
|
+
if (!p) {
|
|
405
|
+
// Use ortb2Imp.ext.data.placement for backward compatibility.
|
|
406
|
+
p = deepAccess(bid, 'ortb2Imp.ext.data.placement', '');
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// `useAdUnitCodeAsPlacement` is an edge case. Useful when a Prebid Manager cannot handle properly params setting.
|
|
410
|
+
if (!p && bid.params.useAdUnitCodeAsPlacement === true) {
|
|
411
|
+
p = bid.adUnitCode;
|
|
412
|
+
}
|
|
413
|
+
bid.params.placement = p;
|
|
407
414
|
}
|
|
408
415
|
|
|
409
416
|
bid.params.adUnitElementId = deepAccess(bid, 'ortb2Imp.ext.data.divId', bid.params.adUnitElementId);
|
|
@@ -47,7 +47,7 @@ export const PLACEMENT_SOURCES = {
|
|
|
47
47
|
};
|
|
48
48
|
export const storage = getStorageManager({ moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME });
|
|
49
49
|
|
|
50
|
-
const { logError, logWarn } = prefixLog('AdagioRtdProvider:');
|
|
50
|
+
const { logError, logInfo, logWarn } = prefixLog('AdagioRtdProvider:');
|
|
51
51
|
|
|
52
52
|
// Guard to avoid storing the same bid data several times.
|
|
53
53
|
const guard = new Set();
|
|
@@ -238,6 +238,25 @@ export const _internal = {
|
|
|
238
238
|
return value;
|
|
239
239
|
}
|
|
240
240
|
});
|
|
241
|
+
},
|
|
242
|
+
|
|
243
|
+
// Compute the placement from the legacy RTD config params or ortb2Imp.ext.data.placement key.
|
|
244
|
+
computePlacementFromLegacy: function(rtdConfig, adUnit) {
|
|
245
|
+
const placementSource = deepAccess(rtdConfig, 'params.placementSource', '');
|
|
246
|
+
let placementFromSource = '';
|
|
247
|
+
|
|
248
|
+
switch (placementSource.toLowerCase()) {
|
|
249
|
+
case PLACEMENT_SOURCES.ADUNITCODE:
|
|
250
|
+
placementFromSource = adUnit.code;
|
|
251
|
+
break;
|
|
252
|
+
case PLACEMENT_SOURCES.GPID:
|
|
253
|
+
placementFromSource = deepAccess(adUnit, 'ortb2Imp.ext.gpid')
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const placementLegacy = deepAccess(adUnit, 'ortb2Imp.ext.data.placement', '');
|
|
258
|
+
|
|
259
|
+
return placementFromSource || placementLegacy;
|
|
241
260
|
}
|
|
242
261
|
};
|
|
243
262
|
|
|
@@ -317,7 +336,6 @@ function onBidRequest(bidderRequest, config, _userConsent) {
|
|
|
317
336
|
* @param {*} config
|
|
318
337
|
*/
|
|
319
338
|
function onGetBidRequestData(bidReqConfig, callback, config) {
|
|
320
|
-
const configParams = deepAccess(config, 'params', {});
|
|
321
339
|
const { site: ortb2Site } = bidReqConfig.ortb2Fragments.global;
|
|
322
340
|
const features = _internal.getFeatures().get();
|
|
323
341
|
const ext = {
|
|
@@ -345,30 +363,11 @@ function onGetBidRequestData(bidReqConfig, callback, config) {
|
|
|
345
363
|
const slotPosition = getSlotPosition(divId);
|
|
346
364
|
deepSetValue(ortb2Imp, `ext.data.adg_rtd.adunit_position`, slotPosition);
|
|
347
365
|
|
|
348
|
-
// It is expected that the publisher set a `adUnits[].ortb2Imp.ext.data.placement` value.
|
|
349
|
-
// Btw, We allow fallback sources to programmatically set this value.
|
|
350
|
-
// The source is defined in the `config.params.placementSource` and the possible values are `code` or `gpid`.
|
|
351
|
-
// (Please note that this `placement` is not related to the oRTB video property.)
|
|
352
|
-
if (!deepAccess(ortb2Imp, 'ext.data.placement')) {
|
|
353
|
-
const { placementSource = '' } = configParams;
|
|
354
|
-
|
|
355
|
-
switch (placementSource.toLowerCase()) {
|
|
356
|
-
case PLACEMENT_SOURCES.ADUNITCODE:
|
|
357
|
-
deepSetValue(ortb2Imp, 'ext.data.placement', adUnit.code);
|
|
358
|
-
break;
|
|
359
|
-
case PLACEMENT_SOURCES.GPID:
|
|
360
|
-
deepSetValue(ortb2Imp, 'ext.data.placement', deepAccess(ortb2Imp, 'ext.gpid'));
|
|
361
|
-
break;
|
|
362
|
-
default:
|
|
363
|
-
logWarn('`ortb2Imp.ext.data.placement` is missing and `params.definePlacement` is not set in the config.');
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// We expect that `pagetype`, `category`, `placement` are defined in FPD `ortb2.site.ext.data` and `adUnits[].ortb2Imp.ext.data` objects.
|
|
368
|
-
// Btw, we have to ensure compatibility with publishers that use the "legacy" adagio params at the adUnit.params level.
|
|
369
366
|
const adagioBid = adUnit.bids.find(bid => _internal.isAdagioBidder(bid.bidder));
|
|
370
367
|
if (adagioBid) {
|
|
371
368
|
// ortb2 level
|
|
369
|
+
// We expect that `pagetype`, `category` are defined in FPD `ortb2.site.ext.data` object.
|
|
370
|
+
// Btw, we still ensure compatibility with publishers that use the adagio params at the adUnit.params level.
|
|
372
371
|
let mustWarnOrtb2 = false;
|
|
373
372
|
if (!deepAccess(ortb2Site, 'ext.data.pagetype') && adagioBid.params.pagetype) {
|
|
374
373
|
deepSetValue(ortb2Site, 'ext.data.pagetype', adagioBid.params.pagetype);
|
|
@@ -378,21 +377,28 @@ function onGetBidRequestData(bidReqConfig, callback, config) {
|
|
|
378
377
|
deepSetValue(ortb2Site, 'ext.data.category', adagioBid.params.category);
|
|
379
378
|
mustWarnOrtb2 = true;
|
|
380
379
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
let mustWarnOrtb2Imp = false;
|
|
384
|
-
if (!deepAccess(ortb2Imp, 'ext.data.placement')) {
|
|
385
|
-
if (adagioBid.params.placement) {
|
|
386
|
-
deepSetValue(ortb2Imp, 'ext.data.placement', adagioBid.params.placement);
|
|
387
|
-
mustWarnOrtb2Imp = true;
|
|
388
|
-
}
|
|
380
|
+
if (mustWarnOrtb2) {
|
|
381
|
+
logInfo('`pagetype` and/or `category` have been set in the FPD `ortb2.site.ext.data` object from `adUnits[].bids.adagio.params`.');
|
|
389
382
|
}
|
|
390
383
|
|
|
391
|
-
|
|
392
|
-
|
|
384
|
+
// ortb2Imp level to handle legacy.
|
|
385
|
+
// The `placement` is finally set at the adUnit.params level (see https://github.com/prebid/Prebid.js/issues/12845)
|
|
386
|
+
// but we still need to set it at the ortb2Imp level for our internal use.
|
|
387
|
+
const placementParam = adagioBid.params.placement;
|
|
388
|
+
const adgRtdPlacement = deepAccess(ortb2Imp, 'ext.data.adg_rtd.placement', '');
|
|
389
|
+
|
|
390
|
+
if (placementParam) {
|
|
391
|
+
// Always overwrite the ortb2Imp value with the one from the adagio adUnit.params.placement if defined.
|
|
392
|
+
// This is the common case.
|
|
393
|
+
deepSetValue(ortb2Imp, 'ext.data.adg_rtd.placement', placementParam);
|
|
393
394
|
}
|
|
394
|
-
|
|
395
|
-
|
|
395
|
+
|
|
396
|
+
if (!placementParam && !adgRtdPlacement) {
|
|
397
|
+
const p = _internal.computePlacementFromLegacy(config, adUnit);
|
|
398
|
+
if (p) {
|
|
399
|
+
deepSetValue(ortb2Imp, 'ext.data.adg_rtd.placement', p);
|
|
400
|
+
logWarn('`ortb2Imp.ext.data.adg_rtd.placement` has been set from a legacy source. Please set `bids[].adagio.params.placement` or `ortb2Imp.ext.data.adg_rtd.placement` value.');
|
|
401
|
+
}
|
|
396
402
|
}
|
|
397
403
|
}
|
|
398
404
|
});
|