prebid.js 7.52.0 → 7.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/1plusXRtdProvider.js +1 -1
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/33acrossIdSystem.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adkernelBidAdapter.js +1 -1
- package/dist/adqueryBidAdapter.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/adyoulikeBidAdapter.js +1 -1
- package/dist/airgridRtdProvider.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/beopBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/conceptxBidAdapter.js +1 -0
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantAnalyticsAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/cwireBidAdapter.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/eskimiBidAdapter.js +1 -1
- package/dist/euidIdSystem.js +1 -0
- package/dist/feedadBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/freepassIdSystem.js +1 -0
- package/dist/freewheel-sspBidAdapter.js +1 -1
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/greenbidsAnalyticsAdapter.js +1 -1
- package/dist/greenbidsRtdProvider.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/inmarBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/kargoBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.js +1 -1
- package/dist/kulturemediaBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/limelightDigitalBidAdapter.js +1 -1
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/magniteAnalyticsAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/minutemediaplusBidAdapter.js +1 -1
- package/dist/nexx360BidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +146 -142
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/optidigitalBidAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/pairIdSystem.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/proxistoreBidAdapter.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/retailspotBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/richaudienceBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rubiconAnalyticsAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/schain.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/shinezBidAdapter.js +1 -1
- package/dist/sirdataRtdProvider.js +1 -1
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/stroeerCoreBidAdapter.js +1 -1
- package/dist/stvBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/uid2IdSystem.js +1 -1
- package/dist/uid2IdSystem_shared.js +1 -0
- 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/viouslyBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/weboramaRtdProvider.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yieldlabBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/dist/zeta_global_sspBidAdapter.js +1 -1
- package/integrationExamples/gpt/userId_example.html +20 -6
- package/modules/.submodules.json +3 -1
- package/modules/1plusXRtdProvider.js +31 -60
- package/modules/adagioBidAdapter.js +86 -24
- package/modules/adkernelBidAdapter.js +2 -2
- package/modules/airgridRtdProvider.js +11 -12
- package/modules/asoBidAdapter.js +2 -1
- package/modules/beopBidAdapter.js +6 -0
- package/modules/conceptxBidAdapter.js +70 -0
- package/modules/conceptxBidAdapter.md +36 -0
- package/modules/criteoBidAdapter.js +9 -2
- package/modules/eskimiBidAdapter.js +171 -41
- package/modules/eskimiBidAdapter.md +35 -16
- package/modules/euidIdSystem.js +121 -0
- package/modules/euidIdSystem.md +131 -0
- package/modules/freepassIdSystem.js +61 -0
- package/modules/freepassIdSystem.md +47 -0
- package/modules/greenbidsAnalyticsAdapter.js +1 -1
- package/modules/id5IdSystem.js +3 -5
- package/modules/ixBidAdapter.js +12 -1
- package/modules/limelightDigitalBidAdapter.js +1 -1
- package/modules/logicadBidAdapter.js +14 -1
- package/modules/mediasquareBidAdapter.js +13 -5
- package/modules/nexx360BidAdapter.js +1 -0
- package/modules/pairIdSystem.js +10 -5
- package/modules/proxistoreBidAdapter.js +11 -14
- package/modules/richaudienceBidAdapter.js +10 -1
- package/modules/riseBidAdapter.js +1 -1
- package/modules/schain.js +2 -2
- package/modules/sirdataRtdProvider.js +73 -146
- package/modules/sovrnBidAdapter.js +4 -1
- package/modules/stroeerCoreBidAdapter.js +55 -6
- package/modules/uid2IdSystem.js +27 -210
- package/modules/uid2IdSystem.md +104 -23
- package/modules/uid2IdSystem_shared.js +232 -0
- package/modules/userId/eids.js +8 -0
- package/modules/userId/userId.md +2 -1
- package/modules/viouslyBidAdapter.js +2 -2
- package/modules/weboramaRtdProvider.js +25 -95
- package/modules/weboramaRtdProvider.md +4 -4
- package/modules/yieldlabBidAdapter.js +23 -14
- package/modules/zeta_global_sspBidAdapter.js +27 -22
- package/package.json +1 -1
- package/src/adloader.js +1 -0
- package/test/spec/modules/1plusXRtdProvider_spec.js +98 -149
- package/test/spec/modules/adagioBidAdapter_spec.js +46 -17
- package/test/spec/modules/airgridRtdProvider_spec.js +2 -0
- package/test/spec/modules/beopBidAdapter_spec.js +24 -0
- package/test/spec/modules/conceptxBidAdapter_spec.js +136 -0
- package/test/spec/modules/criteoBidAdapter_spec.js +1 -1
- package/test/spec/modules/eids_spec.js +15 -0
- package/test/spec/modules/eskimiBidAdapter_spec.js +264 -112
- package/test/spec/modules/euidIdSystem_spec.js +130 -0
- package/test/spec/modules/freepassIdSystem_spec.js +186 -0
- package/test/spec/modules/id5IdSystem_spec.js +10 -3
- package/test/spec/modules/ixBidAdapter_spec.js +30 -0
- package/test/spec/modules/logicadBidAdapter_spec.js +122 -2
- package/test/spec/modules/mediasquareBidAdapter_spec.js +4 -0
- package/test/spec/modules/richaudienceBidAdapter_spec.js +44 -0
- package/test/spec/modules/schain_spec.js +9 -0
- package/test/spec/modules/sirdataRtdProvider_spec.js +110 -17
- package/test/spec/modules/sovrnBidAdapter_spec.js +13 -0
- package/test/spec/modules/stroeerCoreBidAdapter_spec.js +151 -6
- package/test/spec/modules/uid2IdSystem_helpers.js +70 -0
- package/test/spec/modules/uid2IdSystem_spec.js +131 -86
- package/test/spec/modules/userId_spec.js +16 -12
- package/test/spec/modules/weboramaRtdProvider_spec.js +331 -205
- package/test/spec/modules/yieldlabBidAdapter_spec.js +42 -2
- package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +200 -4
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
export const Uid2CodeVersion = '1.1';
|
|
3
|
+
|
|
4
|
+
function isValidIdentity(identity) {
|
|
5
|
+
return !!(typeof identity === 'object' && identity !== null && identity.advertising_token && identity.identity_expires && identity.refresh_from && identity.refresh_token && identity.refresh_expires);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// This is extracted from an in-progress API client. Once it's available via NPM, this class should be replaced with the NPM package.
|
|
9
|
+
export class Uid2ApiClient {
|
|
10
|
+
constructor(opts, clientId, logInfo, logWarn) {
|
|
11
|
+
this._baseUrl = opts.baseUrl;
|
|
12
|
+
this._clientVersion = clientId;
|
|
13
|
+
this._logInfo = logInfo;
|
|
14
|
+
this._logWarn = logWarn;
|
|
15
|
+
}
|
|
16
|
+
createArrayBuffer(text) {
|
|
17
|
+
const arrayBuffer = new Uint8Array(text.length);
|
|
18
|
+
for (let i = 0; i < text.length; i++) {
|
|
19
|
+
arrayBuffer[i] = text.charCodeAt(i);
|
|
20
|
+
}
|
|
21
|
+
return arrayBuffer;
|
|
22
|
+
}
|
|
23
|
+
hasStatusResponse(response) {
|
|
24
|
+
return typeof (response) === 'object' && response && response.status;
|
|
25
|
+
}
|
|
26
|
+
isValidRefreshResponse(response) {
|
|
27
|
+
return this.hasStatusResponse(response) && (
|
|
28
|
+
response.status === 'optout' || response.status === 'expired_token' || (response.status === 'success' && response.body && isValidIdentity(response.body))
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
ResponseToRefreshResult(response) {
|
|
32
|
+
if (this.isValidRefreshResponse(response)) {
|
|
33
|
+
if (response.status === 'success') { return { status: response.status, identity: response.body }; }
|
|
34
|
+
return response;
|
|
35
|
+
} else { return `Response didn't contain a valid status`; }
|
|
36
|
+
}
|
|
37
|
+
callRefreshApi(refreshDetails) {
|
|
38
|
+
const url = this._baseUrl + '/v2/token/refresh';
|
|
39
|
+
const req = new XMLHttpRequest();
|
|
40
|
+
req.overrideMimeType('text/plain');
|
|
41
|
+
req.open('POST', url, true);
|
|
42
|
+
req.setRequestHeader('X-UID2-Client-Version', this._clientVersion);
|
|
43
|
+
let resolvePromise;
|
|
44
|
+
let rejectPromise;
|
|
45
|
+
const promise = new Promise((resolve, reject) => {
|
|
46
|
+
resolvePromise = resolve;
|
|
47
|
+
rejectPromise = reject;
|
|
48
|
+
});
|
|
49
|
+
req.onreadystatechange = () => {
|
|
50
|
+
if (req.readyState !== req.DONE) { return; }
|
|
51
|
+
try {
|
|
52
|
+
if (!refreshDetails.refresh_response_key || req.status !== 200) {
|
|
53
|
+
this._logInfo('Error status OR no response decryption key available, assuming unencrypted JSON');
|
|
54
|
+
const response = JSON.parse(req.responseText);
|
|
55
|
+
const result = this.ResponseToRefreshResult(response);
|
|
56
|
+
if (typeof result === 'string') { rejectPromise(result); } else { resolvePromise(result); }
|
|
57
|
+
} else {
|
|
58
|
+
this._logInfo('Decrypting refresh API response');
|
|
59
|
+
const encodeResp = this.createArrayBuffer(atob(req.responseText));
|
|
60
|
+
window.crypto.subtle.importKey('raw', this.createArrayBuffer(atob(refreshDetails.refresh_response_key)), { name: 'AES-GCM' }, false, ['decrypt']).then((key) => {
|
|
61
|
+
this._logInfo('Imported decryption key')
|
|
62
|
+
// returns the symmetric key
|
|
63
|
+
window.crypto.subtle.decrypt({
|
|
64
|
+
name: 'AES-GCM',
|
|
65
|
+
iv: encodeResp.slice(0, 12),
|
|
66
|
+
tagLength: 128, // The tagLength you used to encrypt (if any)
|
|
67
|
+
}, key, encodeResp.slice(12)).then((decrypted) => {
|
|
68
|
+
const decryptedResponse = String.fromCharCode(...new Uint8Array(decrypted));
|
|
69
|
+
this._logInfo('Decrypted to:', decryptedResponse);
|
|
70
|
+
const response = JSON.parse(decryptedResponse);
|
|
71
|
+
const result = this.ResponseToRefreshResult(response);
|
|
72
|
+
if (typeof result === 'string') { rejectPromise(result); } else { resolvePromise(result); }
|
|
73
|
+
}, (reason) => this._logWarn(`Call to UID2 API failed`, reason));
|
|
74
|
+
}, (reason) => this._logWarn(`Call to UID2 API failed`, reason));
|
|
75
|
+
}
|
|
76
|
+
} catch (err) {
|
|
77
|
+
rejectPromise(err);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
this._logInfo('Sending refresh request', refreshDetails);
|
|
81
|
+
req.send(refreshDetails.refresh_token);
|
|
82
|
+
return promise;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export class Uid2StorageManager {
|
|
86
|
+
constructor(storage, preferLocalStorage, storageName, logInfo) {
|
|
87
|
+
this._storage = storage;
|
|
88
|
+
this._preferLocalStorage = preferLocalStorage;
|
|
89
|
+
this._storageName = storageName;
|
|
90
|
+
this._logInfo = logInfo;
|
|
91
|
+
}
|
|
92
|
+
readCookie(cookieName) {
|
|
93
|
+
return this._storage.cookiesAreEnabled() ? this._storage.getCookie(cookieName) : null;
|
|
94
|
+
}
|
|
95
|
+
readLocalStorage(key) {
|
|
96
|
+
return this._storage.localStorageIsEnabled() ? this._storage.getDataFromLocalStorage(key) : null;
|
|
97
|
+
}
|
|
98
|
+
readModuleCookie() {
|
|
99
|
+
return this.parseIfContainsBraces(this.readCookie(this._storageName));
|
|
100
|
+
}
|
|
101
|
+
writeModuleCookie(value) {
|
|
102
|
+
this._storage.setCookie(this._storageName, JSON.stringify(value), Date.now() + 60 * 60 * 24 * 1000);
|
|
103
|
+
}
|
|
104
|
+
readModuleStorage() {
|
|
105
|
+
return this.parseIfContainsBraces(this.readLocalStorage(this._storageName));
|
|
106
|
+
}
|
|
107
|
+
writeModuleStorage(value) {
|
|
108
|
+
this._storage.setDataInLocalStorage(this._storageName, JSON.stringify(value));
|
|
109
|
+
}
|
|
110
|
+
readProvidedCookie(cookieName) {
|
|
111
|
+
return JSON.parse(this.readCookie(cookieName));
|
|
112
|
+
}
|
|
113
|
+
parseIfContainsBraces(value) {
|
|
114
|
+
return (value?.includes('{')) ? JSON.parse(value) : value;
|
|
115
|
+
}
|
|
116
|
+
storeValue(value) {
|
|
117
|
+
if (this._preferLocalStorage) {
|
|
118
|
+
this.writeModuleStorage(value);
|
|
119
|
+
} else {
|
|
120
|
+
this.writeModuleCookie(value);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
getStoredValueWithFallback() {
|
|
125
|
+
const preferredStorageLabel = this._preferLocalStorage ? 'local storage' : 'cookie';
|
|
126
|
+
const preferredStorageGet = (this._preferLocalStorage ? this.readModuleStorage : this.readModuleCookie).bind(this);
|
|
127
|
+
const preferredStorageSet = (this._preferLocalStorage ? this.writeModuleStorage : this.writeModuleCookie).bind(this);
|
|
128
|
+
const fallbackStorageGet = (this._preferLocalStorage ? this.readModuleCookie : this.readModuleStorage).bind(this);
|
|
129
|
+
|
|
130
|
+
const storedValue = preferredStorageGet();
|
|
131
|
+
|
|
132
|
+
if (!storedValue) {
|
|
133
|
+
const fallbackValue = fallbackStorageGet();
|
|
134
|
+
if (fallbackValue) {
|
|
135
|
+
this._logInfo(`${preferredStorageLabel} was empty, but found a fallback value.`)
|
|
136
|
+
if (typeof fallbackValue === 'object') {
|
|
137
|
+
this._logInfo(`Copying the fallback value to ${preferredStorageLabel}.`);
|
|
138
|
+
preferredStorageSet(fallbackValue);
|
|
139
|
+
}
|
|
140
|
+
return fallbackValue;
|
|
141
|
+
}
|
|
142
|
+
} else if (typeof storedValue === 'string') {
|
|
143
|
+
const fallbackValue = fallbackStorageGet();
|
|
144
|
+
if (fallbackValue && typeof fallbackValue === 'object') {
|
|
145
|
+
this._logInfo(`${preferredStorageLabel} contained a basic token, but found a refreshable token fallback. Copying the fallback value to ${preferredStorageLabel}.`);
|
|
146
|
+
preferredStorageSet(fallbackValue);
|
|
147
|
+
return fallbackValue;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return storedValue;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function refreshTokenAndStore(baseUrl, token, clientId, storageManager, _logInfo, _logWarn) {
|
|
155
|
+
_logInfo('UID2 base url provided: ', baseUrl);
|
|
156
|
+
const client = new Uid2ApiClient({baseUrl}, clientId, _logInfo, _logWarn);
|
|
157
|
+
return client.callRefreshApi(token).then((response) => {
|
|
158
|
+
_logInfo('Refresh endpoint responded with:', response);
|
|
159
|
+
const tokens = {
|
|
160
|
+
originalToken: token,
|
|
161
|
+
latestToken: response.identity,
|
|
162
|
+
};
|
|
163
|
+
storageManager.storeValue(tokens);
|
|
164
|
+
return tokens;
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function Uid2GetId(config, prebidStorageManager, _logInfo, _logWarn) {
|
|
169
|
+
let suppliedToken = null;
|
|
170
|
+
const preferLocalStorage = (config.storage !== 'cookie');
|
|
171
|
+
const storageManager = new Uid2StorageManager(prebidStorageManager, preferLocalStorage, config.internalStorage, _logInfo);
|
|
172
|
+
_logInfo(`Module is using ${preferLocalStorage ? 'local storage' : 'cookies'} for internal storage.`);
|
|
173
|
+
|
|
174
|
+
if (config.paramToken) {
|
|
175
|
+
suppliedToken = config.paramToken;
|
|
176
|
+
_logInfo('Read token from params', suppliedToken);
|
|
177
|
+
} else if (config.serverCookieName) {
|
|
178
|
+
suppliedToken = storageManager.readProvidedCookie(config.serverCookieName);
|
|
179
|
+
_logInfo('Read token from server-supplied cookie', suppliedToken);
|
|
180
|
+
}
|
|
181
|
+
let storedTokens = storageManager.getStoredValueWithFallback();
|
|
182
|
+
_logInfo('Loaded module-stored tokens:', storedTokens);
|
|
183
|
+
|
|
184
|
+
if (storedTokens && typeof storedTokens === 'string') {
|
|
185
|
+
// Stored value is a plain token - if no token is supplied, just use the stored value.
|
|
186
|
+
|
|
187
|
+
if (!suppliedToken) {
|
|
188
|
+
_logInfo('Returning legacy cookie value.');
|
|
189
|
+
return { id: storedTokens };
|
|
190
|
+
}
|
|
191
|
+
// Otherwise, ignore the legacy value - it should get over-written later anyway.
|
|
192
|
+
_logInfo('Discarding superseded legacy cookie.');
|
|
193
|
+
storedTokens = null;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (suppliedToken && storedTokens) {
|
|
197
|
+
if (storedTokens.originalToken?.advertising_token !== suppliedToken.advertising_token) {
|
|
198
|
+
_logInfo('Server supplied new token - ignoring stored value.', storedTokens.originalToken?.advertising_token, suppliedToken.advertising_token);
|
|
199
|
+
// Stored token wasn't originally sourced from the provided token - ignore the stored value. A new user has logged in?
|
|
200
|
+
storedTokens = null;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// At this point, any legacy values or superseded stored tokens have been nulled out.
|
|
204
|
+
const useSuppliedToken = !(storedTokens?.latestToken) || (suppliedToken && suppliedToken.identity_expires > storedTokens.latestToken.identity_expires);
|
|
205
|
+
const newestAvailableToken = useSuppliedToken ? suppliedToken : storedTokens.latestToken;
|
|
206
|
+
_logInfo('UID2 module selected latest token', useSuppliedToken, newestAvailableToken);
|
|
207
|
+
if (!newestAvailableToken || Date.now() > newestAvailableToken.refresh_expires) {
|
|
208
|
+
_logInfo('Newest available token is expired and not refreshable.');
|
|
209
|
+
return { id: null };
|
|
210
|
+
}
|
|
211
|
+
if (Date.now() > newestAvailableToken.identity_expires) {
|
|
212
|
+
const promise = refreshTokenAndStore(config.apiBaseUrl, newestAvailableToken, config.clientId, storageManager, _logInfo, _logWarn);
|
|
213
|
+
_logInfo('Token is expired but can be refreshed, attempting refresh.');
|
|
214
|
+
return { callback: (cb) => {
|
|
215
|
+
promise.then((result) => {
|
|
216
|
+
_logInfo('Refresh reponded, passing the updated token on.', result);
|
|
217
|
+
cb(result);
|
|
218
|
+
});
|
|
219
|
+
} };
|
|
220
|
+
}
|
|
221
|
+
// If should refresh (but don't need to), refresh in the background.
|
|
222
|
+
if (Date.now() > newestAvailableToken.refresh_from) {
|
|
223
|
+
_logInfo(`Refreshing token in background with low priority.`);
|
|
224
|
+
refreshTokenAndStore(config.apiBaseUrl, newestAvailableToken, config.clientId, storageManager, _logInfo, _logWarn);
|
|
225
|
+
}
|
|
226
|
+
const tokens = {
|
|
227
|
+
originalToken: suppliedToken ?? storedTokens?.originalToken,
|
|
228
|
+
latestToken: newestAvailableToken,
|
|
229
|
+
};
|
|
230
|
+
storageManager.storeValue(tokens);
|
|
231
|
+
return { id: tokens };
|
|
232
|
+
}
|
package/modules/userId/eids.js
CHANGED
package/modules/userId/userId.md
CHANGED
|
@@ -5,7 +5,7 @@ import { BANNER, VIDEO } from '../src/mediaTypes.js';
|
|
|
5
5
|
import find from 'core-js-pure/features/array/find.js'; // eslint-disable-line prebid/validate-imports
|
|
6
6
|
|
|
7
7
|
const BIDDER_CODE = 'viously';
|
|
8
|
-
|
|
8
|
+
const GVLID = 1028;
|
|
9
9
|
const CURRENCY = 'EUR';
|
|
10
10
|
const TTL = 60;
|
|
11
11
|
const HTTP_METHOD = 'POST';
|
|
@@ -15,7 +15,7 @@ const REQUIRED_VIOUSLY_PARAMS = ['pid'];
|
|
|
15
15
|
|
|
16
16
|
export const spec = {
|
|
17
17
|
code: BIDDER_CODE,
|
|
18
|
-
|
|
18
|
+
gvlid: GVLID,
|
|
19
19
|
supportedMediaTypes: [BANNER, VIDEO],
|
|
20
20
|
|
|
21
21
|
/**
|
|
@@ -689,19 +689,8 @@ class WeboramaRtdProvider {
|
|
|
689
689
|
/** @type {string} */
|
|
690
690
|
const bidder = bidderAliasRegistry[bid.bidder] || bid.bidder;
|
|
691
691
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
this.#handleAppnexusBid(bid, profile);
|
|
695
|
-
break;
|
|
696
|
-
case 'pubmatic':
|
|
697
|
-
this.#handlePubmaticBid(bid, profile);
|
|
698
|
-
break;
|
|
699
|
-
case 'smartadserver':
|
|
700
|
-
this.#handleSmartadserverBid(bid, profile);
|
|
701
|
-
break;
|
|
702
|
-
case 'rubicon':
|
|
703
|
-
this.#handleRubiconBid(bid, profile, metadata);
|
|
704
|
-
break;
|
|
692
|
+
if (bidder == 'appnexus') {
|
|
693
|
+
this.#handleAppnexusBid(reqBidsConfigObj, bid, profile);
|
|
705
694
|
}
|
|
706
695
|
}
|
|
707
696
|
|
|
@@ -719,92 +708,19 @@ class WeboramaRtdProvider {
|
|
|
719
708
|
/** handle appnexus/xandr bid
|
|
720
709
|
* @method
|
|
721
710
|
* @private
|
|
711
|
+
* @param {Object} reqBidsConfigObj
|
|
712
|
+
* @param {Object} reqBidsConfigObj.ortb2Fragments
|
|
713
|
+
* @param {Object} reqBidsConfigObj.ortb2Fragments.bidder
|
|
722
714
|
* @param {Object} bid
|
|
723
|
-
* @param {Object} bid.
|
|
724
|
-
* @param {Object} bid.params.keyword
|
|
715
|
+
* @param {Object} bid.parameters
|
|
725
716
|
* @param {Profile} profile
|
|
726
717
|
* @returns {void}
|
|
727
718
|
*/
|
|
728
719
|
// eslint-disable-next-line no-dupe-class-members
|
|
729
|
-
#handleAppnexusBid(bid, profile) {
|
|
720
|
+
#handleAppnexusBid(reqBidsConfigObj, bid, profile) {
|
|
730
721
|
const base = 'params.keywords';
|
|
731
722
|
this.#assignProfileToObject(bid, base, profile);
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
/** handle pubmatic bid
|
|
735
|
-
* @method
|
|
736
|
-
* @private
|
|
737
|
-
* @param {Object} bid
|
|
738
|
-
* @param {Object} bid.params
|
|
739
|
-
* @param {string} bid.params.dctr
|
|
740
|
-
* @param {Profile} profile
|
|
741
|
-
* @returns {void}
|
|
742
|
-
*/
|
|
743
|
-
// eslint-disable-next-line no-dupe-class-members
|
|
744
|
-
#handlePubmaticBid(bid, profile) {
|
|
745
|
-
const sep = '|';
|
|
746
|
-
const subsep = ',';
|
|
747
|
-
|
|
748
|
-
bid.params ||= {};
|
|
749
|
-
|
|
750
|
-
const data = bid.params.dctr || '';
|
|
751
|
-
const target = new Set(data.split(sep).filter((x) => x.length > 0));
|
|
752
|
-
|
|
753
|
-
Object.entries(profile).forEach(([key, values]) => {
|
|
754
|
-
const value = values.join(subsep);
|
|
755
|
-
const keyword = `${key}=${value}`;
|
|
756
|
-
target.add(keyword);
|
|
757
|
-
});
|
|
758
|
-
|
|
759
|
-
bid.params.dctr = Array.from(target).join(sep);
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
/** handle smartadserver bid
|
|
763
|
-
* @method
|
|
764
|
-
* @private
|
|
765
|
-
* @param {Object} bid
|
|
766
|
-
* @param {Object} bid.params
|
|
767
|
-
* @param {string} bid.params.target
|
|
768
|
-
* @param {Profile} profile
|
|
769
|
-
* @returns {void}
|
|
770
|
-
*/
|
|
771
|
-
// eslint-disable-next-line no-dupe-class-members
|
|
772
|
-
#handleSmartadserverBid(bid, profile) {
|
|
773
|
-
const sep = ';';
|
|
774
|
-
|
|
775
|
-
bid.params ||= {};
|
|
776
|
-
|
|
777
|
-
const data = bid.params.target || '';
|
|
778
|
-
const target = new Set(data.split(sep).filter((x) => x.length > 0));
|
|
779
|
-
|
|
780
|
-
Object.entries(profile).forEach(([key, values]) => {
|
|
781
|
-
values.forEach(value => {
|
|
782
|
-
const keyword = `${key}=${value}`;
|
|
783
|
-
target.add(keyword);
|
|
784
|
-
})
|
|
785
|
-
});
|
|
786
|
-
|
|
787
|
-
bid.params.target = Array.from(target).join(sep);
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
/** handle rubicon bid
|
|
791
|
-
* @method
|
|
792
|
-
* @private
|
|
793
|
-
* @param {Object} bid
|
|
794
|
-
* @param {string} bid.bidder
|
|
795
|
-
* @param {Profile} profile
|
|
796
|
-
* @param {dataCallbackMetadata} metadata
|
|
797
|
-
* @returns {void}
|
|
798
|
-
*/
|
|
799
|
-
// eslint-disable-next-line no-dupe-class-members
|
|
800
|
-
#handleRubiconBid(bid, profile, metadata) {
|
|
801
|
-
if (isBoolean(metadata.user)) {
|
|
802
|
-
const section = metadata.user ? 'visitor' : 'inventory';
|
|
803
|
-
const base = `params.${section}`;
|
|
804
|
-
this.#assignProfileToObject(bid, base, profile);
|
|
805
|
-
} else {
|
|
806
|
-
logMessage(`SKIP bidder '${bid.bidder}', data from '${metadata.source}' is not defined as user or site-centric`);
|
|
807
|
-
}
|
|
723
|
+
// this.#setBidderOrtb2(reqBidsConfigObj.ortb2Fragments?.bidder, bid.bidder, base, profile);
|
|
808
724
|
}
|
|
809
725
|
|
|
810
726
|
/** handle generic bid via ortb2 arbitrary data
|
|
@@ -823,14 +739,28 @@ class WeboramaRtdProvider {
|
|
|
823
739
|
if (isBoolean(metadata.user)) {
|
|
824
740
|
logMessage(`bidder '${bidder}' is not directly supported, trying set data via bidder ortb2 fpd`);
|
|
825
741
|
const section = metadata.user ? 'user' : 'site';
|
|
826
|
-
const
|
|
742
|
+
const path = `${section}.ext.data`;
|
|
827
743
|
|
|
828
|
-
this.#
|
|
744
|
+
this.#setBidderOrtb2(reqBidsConfigObj.ortb2Fragments?.bidder, bidder, path, profile)
|
|
829
745
|
} else {
|
|
830
746
|
logMessage(`SKIP unsupported bidder '${bidder}', data from '${metadata.source}' is not defined as user or site-centric`);
|
|
831
747
|
}
|
|
832
748
|
}
|
|
833
|
-
|
|
749
|
+
/**
|
|
750
|
+
* set bidder ortb2 data
|
|
751
|
+
* @method
|
|
752
|
+
* @private
|
|
753
|
+
* @param {Object} bidderOrtb2Fragments
|
|
754
|
+
* @param {string} bidder
|
|
755
|
+
* @param {string} path
|
|
756
|
+
* @param {Profile} profile
|
|
757
|
+
* @returns {void}
|
|
758
|
+
*/
|
|
759
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
760
|
+
#setBidderOrtb2(bidderOrtb2Fragments, bidder, path, profile) {
|
|
761
|
+
const base = `${bidder}.${path}`;
|
|
762
|
+
this.#assignProfileToObject(bidderOrtb2Fragments, base, profile)
|
|
763
|
+
}
|
|
834
764
|
/**
|
|
835
765
|
* assign profile to object
|
|
836
766
|
* @method
|
|
@@ -575,12 +575,9 @@ pbjs.que.push(function () {
|
|
|
575
575
|
|
|
576
576
|
### Supported Bidders
|
|
577
577
|
|
|
578
|
-
We currently support the following bidder adapters:
|
|
578
|
+
We currently support the following bidder adapters with dedicated code:
|
|
579
579
|
|
|
580
|
-
* SmartADServer SSP
|
|
581
|
-
* PubMatic SSP
|
|
582
580
|
* AppNexus SSP
|
|
583
|
-
* Rubicon SSP
|
|
584
581
|
|
|
585
582
|
We also set the bidder (and global, if no specific bidders are set on `sendToBidders`) ortb2 `site.ext.data` and `user.ext.data` sections (as arbitrary data). The following bidders may support it, to be sure, check the `First Party Data Support` on the feature list for the particular bidder from [here](https://docs.prebid.org/dev-docs/bidders).
|
|
586
583
|
|
|
@@ -605,8 +602,11 @@ We also set the bidder (and global, if no specific bidders are set on `sendToBid
|
|
|
605
602
|
* Opt Out Advertising
|
|
606
603
|
* Ozone Project
|
|
607
604
|
* Proxistore
|
|
605
|
+
* PubMatic SSP
|
|
608
606
|
* Rise
|
|
607
|
+
* Rubicon SSP
|
|
609
608
|
* Smaato
|
|
609
|
+
* Smart ADServer SSP
|
|
610
610
|
* Sonobi
|
|
611
611
|
* TheMediaGrid
|
|
612
612
|
* TripleLift
|
|
@@ -12,6 +12,8 @@ const CURRENCY_CODE = 'EUR';
|
|
|
12
12
|
const OUTSTREAMPLAYER_URL = 'https://ad.adition.com/dynamic.ad?a=o193092&ma_loadEvent=ma-start-event';
|
|
13
13
|
const GVLID = 70;
|
|
14
14
|
const DIMENSION_SIGN = 'x';
|
|
15
|
+
const IMG_TYPE_ICON = 1;
|
|
16
|
+
const IMG_TYPE_MAIN = 3;
|
|
15
17
|
|
|
16
18
|
export const spec = {
|
|
17
19
|
code: BIDDER_CODE,
|
|
@@ -183,24 +185,33 @@ export const spec = {
|
|
|
183
185
|
}
|
|
184
186
|
|
|
185
187
|
if (isNative(bidRequest, adType)) {
|
|
186
|
-
|
|
188
|
+
const { native } = matchedBid;
|
|
189
|
+
const { assets } = native;
|
|
187
190
|
bidResponse.adUrl = `${ENDPOINT}/d/${matchedBid.id}/${bidRequest.params.supplyId}/?ts=${timestamp}${extId}${gdprApplies}${gdprConsent}${pvId}`;
|
|
188
191
|
bidResponse.mediaType = NATIVE;
|
|
189
|
-
const
|
|
192
|
+
const nativeIconAssetObj = find(assets, isImageAssetOfType(IMG_TYPE_ICON));
|
|
193
|
+
const nativeImageAssetObj = find(assets, isImageAssetOfType(IMG_TYPE_MAIN));
|
|
190
194
|
const nativeImageAsset = nativeImageAssetObj ? nativeImageAssetObj.img : { url: '', w: 0, h: 0 };
|
|
191
|
-
const nativeTitleAsset = find(
|
|
192
|
-
const nativeBodyAsset = find(
|
|
195
|
+
const nativeTitleAsset = find(assets, asset => hasValidProperty(asset, 'title'));
|
|
196
|
+
const nativeBodyAsset = find(assets, asset => hasValidProperty(asset, 'data'));
|
|
193
197
|
bidResponse.native = {
|
|
194
198
|
title: nativeTitleAsset ? nativeTitleAsset.title.text : '',
|
|
195
199
|
body: nativeBodyAsset ? nativeBodyAsset.data.value : '',
|
|
200
|
+
...nativeIconAssetObj?.img && {
|
|
201
|
+
icon: {
|
|
202
|
+
url: nativeIconAssetObj.img.url,
|
|
203
|
+
width: nativeIconAssetObj.img.w,
|
|
204
|
+
height: nativeIconAssetObj.img.h,
|
|
205
|
+
},
|
|
206
|
+
},
|
|
196
207
|
image: {
|
|
197
208
|
url: nativeImageAsset.url,
|
|
198
209
|
width: nativeImageAsset.w,
|
|
199
210
|
height: nativeImageAsset.h,
|
|
200
211
|
},
|
|
201
|
-
clickUrl:
|
|
202
|
-
impressionTrackers:
|
|
203
|
-
assets:
|
|
212
|
+
clickUrl: native.link.url,
|
|
213
|
+
impressionTrackers: native.imptrackers,
|
|
214
|
+
assets: assets,
|
|
204
215
|
};
|
|
205
216
|
}
|
|
206
217
|
|
|
@@ -517,14 +528,12 @@ function hasValidProperty(obj, propName) {
|
|
|
517
528
|
}
|
|
518
529
|
|
|
519
530
|
/**
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
*
|
|
523
|
-
* @param {Object} asset - The asset object to check.
|
|
524
|
-
* @returns {boolean} Returns true if the object has a property img.type with a value of 3, otherwise false.
|
|
531
|
+
* Returns a filtering function for image assets based on type.
|
|
532
|
+
* @param {number} type - The desired asset type to filter for i.e. IMG_TYPE_ICON = 1, IMG_TYPE_MAIN = 3
|
|
533
|
+
* @returns {function} - A filtering function that accepts an asset and checks if its img.type matches the desired type.
|
|
525
534
|
*/
|
|
526
|
-
function
|
|
527
|
-
return asset?.img?.type ===
|
|
535
|
+
function isImageAssetOfType(type) {
|
|
536
|
+
return asset => asset?.img?.type === type;
|
|
528
537
|
}
|
|
529
538
|
|
|
530
539
|
registerBidder(spec);
|
|
@@ -11,11 +11,9 @@ const TIMEOUT_URL = 'https://ssp.disqus.com/timeout/prebid';
|
|
|
11
11
|
const USER_SYNC_URL_IFRAME = 'https://ssp.disqus.com/sync?type=iframe';
|
|
12
12
|
const USER_SYNC_URL_IMAGE = 'https://ssp.disqus.com/sync?type=image';
|
|
13
13
|
const DEFAULT_CUR = 'USD';
|
|
14
|
-
const TTL =
|
|
14
|
+
const TTL = 300;
|
|
15
15
|
const NET_REV = true;
|
|
16
16
|
|
|
17
|
-
const VIDEO_REGEX = new RegExp(/VAST\s+version/);
|
|
18
|
-
|
|
19
17
|
const DATA_TYPES = {
|
|
20
18
|
'NUMBER': 'number',
|
|
21
19
|
'STRING': 'string',
|
|
@@ -201,7 +199,10 @@ export const spec = {
|
|
|
201
199
|
advertiserDomains: zetaBid.adomain
|
|
202
200
|
};
|
|
203
201
|
}
|
|
204
|
-
provideMediaType(zetaBid, bid);
|
|
202
|
+
provideMediaType(zetaBid, bid, bidRequest.data);
|
|
203
|
+
if (bid.mediaType === VIDEO) {
|
|
204
|
+
bid.vastXml = bid.ad;
|
|
205
|
+
}
|
|
205
206
|
bidResponses.push(bid);
|
|
206
207
|
})
|
|
207
208
|
})
|
|
@@ -264,10 +265,24 @@ function buildBanner(request) {
|
|
|
264
265
|
request.mediaTypes.banner.sizes) {
|
|
265
266
|
sizes = request.mediaTypes.banner.sizes;
|
|
266
267
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
268
|
+
if (sizes.length > 1) {
|
|
269
|
+
const format = sizes.map(s => {
|
|
270
|
+
return {
|
|
271
|
+
w: s[0],
|
|
272
|
+
h: s[1]
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
return {
|
|
276
|
+
w: sizes[0][0],
|
|
277
|
+
h: sizes[0][1],
|
|
278
|
+
format: format
|
|
279
|
+
}
|
|
280
|
+
} else {
|
|
281
|
+
return {
|
|
282
|
+
w: sizes[0][0],
|
|
283
|
+
h: sizes[0][1]
|
|
284
|
+
}
|
|
285
|
+
}
|
|
271
286
|
}
|
|
272
287
|
|
|
273
288
|
function buildVideo(request) {
|
|
@@ -319,21 +334,11 @@ function provideEids(request, payload) {
|
|
|
319
334
|
}
|
|
320
335
|
}
|
|
321
336
|
|
|
322
|
-
function provideMediaType(zetaBid, bid) {
|
|
323
|
-
if (zetaBid.ext && zetaBid.ext.
|
|
324
|
-
|
|
325
|
-
bid.mediaType = VIDEO;
|
|
326
|
-
bid.vastXml = bid.ad;
|
|
327
|
-
} else {
|
|
328
|
-
bid.mediaType = BANNER;
|
|
329
|
-
}
|
|
337
|
+
function provideMediaType(zetaBid, bid, bidRequest) {
|
|
338
|
+
if (zetaBid.ext && zetaBid.ext.prebid && zetaBid.ext.prebid.type) {
|
|
339
|
+
bid.mediaType = zetaBid.ext.prebid.type === VIDEO ? VIDEO : BANNER;
|
|
330
340
|
} else {
|
|
331
|
-
|
|
332
|
-
bid.mediaType = VIDEO;
|
|
333
|
-
bid.vastXml = bid.ad;
|
|
334
|
-
} else {
|
|
335
|
-
bid.mediaType = BANNER;
|
|
336
|
-
}
|
|
341
|
+
bid.mediaType = bidRequest.imp[0].video ? VIDEO : BANNER;
|
|
337
342
|
}
|
|
338
343
|
}
|
|
339
344
|
|
package/package.json
CHANGED