Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync with master #8

Merged
merged 88 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
f74a4b3
Automatad Analytics Adapter: Initial Release (#10181)
shashankatd Jul 31, 2023
2b422f9
Connatix bid adapter (#10186)
rares-mihai-preda Aug 2, 2023
b2ca20e
Undertone Bid Adapter : documentation update (#10293)
tamarm-undertone Aug 2, 2023
f41c26a
convert bidwon attributes to string (#10307)
matthieularere-msq Aug 2, 2023
234cc6f
AdsInteractive Bid Adapter : added gvlid (#10301)
balintvargha Aug 2, 2023
5eb2bab
Criteo Bid Adapter: do not call API when dataDeletionRequest has no i…
dzhang-criteo Aug 2, 2023
5c7dab5
Update eids.md (#10295)
jdwieland8282 Aug 2, 2023
9d8dc18
Update AdGenerationAdapter: fix userSync (#10310)
banakemi Aug 2, 2023
c2cf122
Grid Bid Adapter: Fix GPID priorities (#10315)
dzhang-criteo Aug 3, 2023
74d03dd
FreepassBidAdaptor. add publisher param, also set site,source (#10303)
aplio Aug 3, 2023
bad831e
added trustedstack bidder alias (#10302)
adish1997 Aug 3, 2023
827c3d5
Adagio Bid Adapter : embed gpp standard (#10190)
soupape34 Aug 3, 2023
2162fda
Optidigital Bid Adapter : update usersync (#10279)
optidigital-prebid Aug 3, 2023
e98c386
Alkimi Bid Adapter : support new parameters (#10296)
pro-nsk Aug 3, 2023
0809dd2
Tappx Refactor: Optimizing and adding more checkers and tests (#10317)
prebidtappx Aug 3, 2023
c6c3254
Prebid 8.7.0 release
prebidjs-release Aug 3, 2023
01348fb
Increment version to 8.8.0-pre
prebidjs-release Aug 3, 2023
5360a1b
update Snigel bid adapter (#10243)
snigelweb Aug 3, 2023
ad2ea1f
bid won and error functions (#10316)
vrishko Aug 4, 2023
b420011
A1Media RTD Module: fix cookie name (#10322)
ChangsikChoi Aug 7, 2023
1b8cd38
Nativo Bid Adapter : changed request method to POST and added OpenRTB…
jsfledd Aug 7, 2023
5249b47
í°› fix bug for interpreting bid response without zone id provided in…
vraybaud Aug 8, 2023
8df5e93
Update adrelevantisBidAdapter.js (#10294)
ghguo Aug 8, 2023
49418b1
Operaads: add ID System sbumodule (#10270)
duduchristian Aug 8, 2023
6318fc9
Set default result of consent check to undefined (#10327)
johanbrandmetrics Aug 9, 2023
8d1c8be
CriteoBidAdapter : Bump fast bid current version to 139 (#10333)
vraybaud Aug 9, 2023
3d41276
Rubicon Bid Adapter: fix saving state of single request option (#10332)
robertrmartinez Aug 9, 2023
865a3db
Onetag Bid Adapter: add support for FPD (ortb2 field) (#10329)
onetag-dev Aug 9, 2023
509deaa
Add index id support (#10334)
3link Aug 9, 2023
3fba6bd
Topics Module: Support for Fetch Header Functionality (#10124)
jlquaccia Aug 9, 2023
c553226
Adquery Bid Adapter : changes in adqueryIdSystem, fix auctionId leak …
adquery Aug 9, 2023
543544c
VIS.X: add first-party id (#10162)
vfedoseev Aug 9, 2023
4e0a780
Prebid core: fix ortb native to legacy to use imptrackers (#10284)
JulieLorin Aug 9, 2023
b534649
Geoedge RTD module: support monitoring all GPT ad slots (#10291)
GeoEdge-r-and-d Aug 9, 2023
b84b6b6
AdMatic Bid Adapter: added ortb2Imp params (#10292)
fatihkaya84 Aug 9, 2023
f2fbcbe
Oxxion Analytics Adapter : support new attributes (#10304)
matthieularere-msq Aug 9, 2023
55df5c9
Criteo Bid Adapter : Pass bid id through criteo bid adapter (#10336)
vraybaud Aug 9, 2023
5142865
Bid Viewability Module: Support Core's Billing Deferral Logic (#10326)
jlquaccia Aug 9, 2023
df7e863
CM-896 (#10335)
peixunzhang Aug 9, 2023
5dd512f
liveIntent Id System: fix ix eid mismatch with ix adapter (#10341)
patmmccann Aug 9, 2023
b3f0ccb
Prebid 8.8.0 release
prebidjs-release Aug 9, 2023
7a8c6f4
Increment version to 8.9.0-pre
prebidjs-release Aug 9, 2023
80c7220
ad added (#10344)
gchicoye Aug 10, 2023
3bbe63b
enrich adagio bid params (#10346)
rotta-f Aug 10, 2023
04c7570
PubMatic Analytics Adapter : log floor values only when floor file is…
kapil-tuptewar Aug 10, 2023
34846c7
Native: privacyLink is now converted to ortb.privacy (#10271)
musikele Aug 10, 2023
52996a6
fledgeForGpt: consolidate publisher configuration (#10136)
laurb9 Aug 10, 2023
e1acefe
Core: enable `Sec-Browsing-Topics` header on outgoing bidder requests…
dgirardi Aug 11, 2023
934f5a9
Revert "fledgeForGpt: consolidate publisher configuration (#10136)" (…
patmmccann Aug 11, 2023
1678443
Activity Controls GPP: invalidate covered = 0 in mspa (#10354)
patmmccann Aug 11, 2023
a4218f1
GrowthCode Analytics: Updates/BugFixes (#10339)
southern-growthcode Aug 14, 2023
d63c627
ConcertBidAdapter: Add `browserLanguage` to request `meta` object (#1…
Skitelman Aug 14, 2023
64615dc
fledgeForGpt: consolidate publisher configuration (#10360)
dgirardi Aug 14, 2023
c3839db
Prebid 8.9.0 release
prebidjs-release Aug 15, 2023
59eac50
Increment version to 8.10.0-pre
prebidjs-release Aug 15, 2023
3cc9175
fluct Bid Adapter: add gpid to bid requests (#10361)
yowcow Aug 15, 2023
507b5a0
identityLinkSubmodule: add additional check on retrieving the envelop…
mamatic Aug 15, 2023
309f979
Cadent Aperture MX Bid Adapter: support GPP and GPP Section Ids (#10342)
EMXDigital Aug 15, 2023
1f6abf6
Yieldmo Bid Adapter : adding 4.x VAST protocol support (#10363)
desidiver Aug 16, 2023
62c9d29
Relay Bid Adapter : Initial Release (#10197)
jcswart Aug 16, 2023
7fc315f
consentManagementGpp: support GPP 1.1 (#10282)
dgirardi Aug 16, 2023
0525202
fix: consolidate banner format array (#10365)
ccorbo Aug 16, 2023
57f2ac8
Prebid Server adapter: improve cookie_sync tests, check GPP fields ar…
dgirardi Aug 16, 2023
8d6ca3e
fluct Bid Adapter: add user.data to bid requests (#10318)
yowcow Aug 17, 2023
06ae917
UserID: check for all consent (not just GDPR) to check if an ID needs…
dgirardi Aug 17, 2023
a23e5f0
gppControl_usstates: activity controls for US state consent (#10283)
dgirardi Aug 17, 2023
b9e0efd
add privacyIcon to not native asset list (#10259)
jsnellbaker Aug 17, 2023
7daae65
Prebid 8.10.0 release
prebidjs-release Aug 17, 2023
f075b1b
Increment version to 8.11.0-pre
prebidjs-release Aug 17, 2023
3263e6e
PubMatic Bid Adapter : Support geo (lat & lon) using ortb2.(device|us…
kapil-tuptewar Aug 20, 2023
78555aa
Jixie adapter changes: adding sendingi of gpid, and send several ids …
jxdeveloper1 Aug 21, 2023
f4f850b
KueezRtb Bid Adapter: pass gpp consent to userSync server. (#10306)
saar120 Aug 21, 2023
6cab521
MinuteMediaPlusBidAdapter: pass gpp consent to userSync server. (#10376)
saar120 Aug 22, 2023
18183f0
3.0 bidder version (#10381)
gchicoye Aug 22, 2023
ddd6a3b
NoBid Bid Adapter: Support for GPP 1.1 (#10287)
redaguermas Aug 22, 2023
3b6c64c
Yandex Bid Adapter: (#10372)
Saveliev Aug 22, 2023
0d2bed6
gdprEnforcement: check for vendor LI in addition to purpose LI (#10367)
dgirardi Aug 23, 2023
7edfdff
Adkernel: headbidder alias (#10380)
ckbo3hrk Aug 23, 2023
59338f3
Preciso Bid adapter : Initial release (#10138)
PrecisoSRL Aug 23, 2023
a094e35
Adquery Bid Adapter : fix getId and decode method (#10312)
adquery Aug 23, 2023
c0048a9
Triplelift Bid Adapter: PAAPI bid response support (#10385)
patrickloughrey Aug 23, 2023
e804885
geolocationRtdProvider: fix `geo.lastfix` (#10383)
dgirardi Aug 23, 2023
487c0ed
teadsBidAdapter: Send pageTitle + pageDescription (#10384)
github-mickael-leclerc Aug 23, 2023
ef8188e
PubMatic Analytics Adapter: Handled bid rejection in case of "Floor n…
pm-azhar-mulla Aug 24, 2023
6495105
Prebid 8.11.0 release
prebidjs-release Aug 24, 2023
936a883
Increment version to 8.12.0-pre
prebidjs-release Aug 24, 2023
f49a4b6
AlkimiBidAdapter: add GVL_ID (#10389)
pro-nsk Aug 24, 2023
3c70ac7
Sharethrough Bid Adapter: add GDPR and GPP support (#10388)
jefftmahoney Aug 24, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions integrationExamples/gpt/growthcode.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,11 @@
provider: 'growthCodeAnalytics',
options: {
pid: 'TEST01',
//url: 'http://localhost:8080/v3/pb/analytics',
trackEvents: [
'auctionInit',
'auctionEnd',
'bidAdjustment',
'bidTimeout',
'bidTimeout',
'bidRequested',
'bidResponse',
'setTargeting',
'requestBids',
'addAdUnits',
'noBid',
'bidWon',
'bidderDone']
]
}
});
pbjs.setConfig({
Expand All @@ -80,7 +71,7 @@
auctionDelay: 1000,
dataProviders: [{
name: 'growthCodeRtd',
waitForIt: true,
waitForIt: false,
params: {
pid: 'TEST01',
}
Expand Down
72 changes: 72 additions & 0 deletions integrationExamples/topics/topics-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// This is an example of a server-side endpoint that is utilizing the Topics API header functionality.
// Note: This test endpoint requires the following to run: node.js, npm, express, cors, body-parser

const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');

const port = process.env.PORT || 3000;

const app = express();
app.use(cors());
app.use(
bodyParser.urlencoded({
extended: true,
})
);
app.use(bodyParser.json());
app.use(express.static('public'));
app.set('port', port);

const listener = app.listen(port, () => {
const host =
listener.address().address === '::'
? 'http://localhost'
: 'http://' + listener.address().address;
// eslint-disable-next-line no-console
console.log(
`${__filename} is listening on ${host}:${listener.address().port}\n`
);
});

app.get('*', (req, res) => {
res.setHeader('Observe-Browsing-Topics', '?1');

const resData = {
segment: {
domain: req.hostname,
topics: generateTopicArrayFromHeader(req.headers['sec-browsing-topics']),
bidder: req.query['bidder'],
},
date: Date.now(),
};

res.json(resData);
});

const generateTopicArrayFromHeader = (topicString) => {
const result = [];
const topicArray = topicString.split(', ');
if (topicArray.length > 1) {
topicArray.pop();
topicArray.map((topic) => {
const topicId = topic.split(';')[0];
const versionsString = topic.split(';')[1].split('=')[1];
const [config, taxonomy, model] = versionsString.split(':');
const numTopicsWithSameVersions = topicId
.substring(1, topicId.length - 1)
.split(' ');

numTopicsWithSameVersions.map((tpId) => {
result.push({
topic: tpId,
version: versionsString,
configVersion: config,
taxonomyVersion: taxonomy,
modelVersion: model,
});
});
});
}
return result;
};
62 changes: 46 additions & 16 deletions libraries/cmp/cmpClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,53 @@ import {GreedyPromise} from '../../src/utils/promise.js';
* @typedef {function} CMPClient
*
* @param {{}} params CMP parameters. Currently this is a subset of {command, callback, parameter, version}.
* @returns {Promise<*>} a promise that:
* - if a `callback` param was provided, resolves (with no result) just before the first time it's run;
* - if `callback` was *not* provided, resolves to the return value of the CMP command
* @param {bool} once if true, discard cross-frame event listeners once a reply message is received.
* @returns {Promise<*>} a promise to the API's "result" - see the `mode` argument to `cmpClient` on how that's determined.
* @property {boolean} isDirect true if the CMP is directly accessible (no postMessage required)
* @property {() => void} close close the client; currently, this just stops listening for cross-frame messages.
*/

/**
* Returns a function that can interface with a CMP regardless of where it's located.
* Returns a client function that can interface with a CMP regardless of where it's located.
*
* @param apiName name of the CMP api, e.g. "__gpp"
* @param apiVersion? CMP API version
* @param apiArgs? names of the arguments taken by the api function, in order.
* @param callbackArgs? names of the cross-frame response payload properties that should be passed as callback arguments, in order
* @param mode? controls the callbacks passed to the underlying API, and how the promises returned by the client are resolved.
*
* The client behaves differently when it's provided a `callback` argument vs when it's not - for short, let's name these
* cases "subscriptions" and "one-shot calls" respectively:
*
* With `mode: MODE_MIXED` (the default), promises returned on subscriptions are resolved to undefined when the callback
* is first run (that is, the promise resolves when the CMP replies, but what it replies with is discarded and
* left for the callback to deal with). For one-shot calls, the returned promise is resolved to the API's
* return value when it's directly accessible, or with the result from the first (and, presumably, the only)
* cross-frame reply when it's not;
*
* With `mode: MODE_RETURN`, the returned promise always resolves to the API's return value - which is taken to be undefined
* when cross-frame;
*
* With `mode: MODE_CALLBACK`, the underlying API is expected to never directly return anything significant; instead,
* it should always accept a callback and - for one-shot calls - invoke it only once with the result. The client will
* automatically generate an appropriate callback for one-shot calls and use the result it's given to resolve
* the returned promise. Subscriptions are treated in the same way as MODE_MIXED.
*
* @param win
* @returns {CMPClient} CMP invocation function (or null if no CMP was found).
*/

export const MODE_MIXED = 0;
export const MODE_RETURN = 1;
export const MODE_CALLBACK = 2;

export function cmpClient(
{
apiName,
apiVersion,
apiArgs = ['command', 'callback', 'parameter', 'version'],
callbackArgs = ['returnValue', 'success'],
mode = MODE_MIXED,
},
win = window
) {
Expand Down Expand Up @@ -89,15 +114,15 @@ export function cmpClient(
}

function wrapCallback(callback, resolve, reject, preamble) {
const haveCb = typeof callback === 'function';

return function (result, success) {
preamble && preamble();
const resolver = success == null || success ? resolve : reject;
if (typeof callback === 'function') {
resolver();
return callback.apply(this, arguments);
} else {
resolver(result);
if (mode !== MODE_RETURN) {
const resolver = success == null || success ? resolve : reject;
resolver(haveCb ? undefined : result);
}
haveCb && callback.apply(this, arguments);
}
}

Expand All @@ -108,17 +133,17 @@ export function cmpClient(
return new GreedyPromise((resolve, reject) => {
const ret = cmpFrame[apiName](...resolveParams({
...params,
callback: params.callback && wrapCallback(params.callback, resolve, reject)
callback: (params.callback || mode === MODE_CALLBACK) ? wrapCallback(params.callback, resolve, reject) : undefined,
}).map(([_, val]) => val));
if (params.callback == null) {
if (mode === MODE_RETURN || (params.callback == null && mode === MODE_MIXED)) {
resolve(ret);
}
});
};
} else {
win.addEventListener('message', handleMessage, false);

client = function invokeCMPFrame(params) {
client = function invokeCMPFrame(params, once = false) {
return new GreedyPromise((resolve, reject) => {
// call CMP via postMessage
const callId = Math.random().toString();
Expand All @@ -129,11 +154,16 @@ export function cmpClient(
}
};

cmpCallbacks[callId] = wrapCallback(params?.callback, resolve, reject, params?.callback == null && (() => { delete cmpCallbacks[callId] }));
cmpCallbacks[callId] = wrapCallback(params?.callback, resolve, reject, (once || params?.callback == null) && (() => { delete cmpCallbacks[callId] }));
cmpFrame.postMessage(msg, '*');
if (mode === MODE_RETURN) resolve();
});
};
}
client.isDirect = isDirect;
return client;
return Object.assign(client, {
isDirect,
close() {
!isDirect && win.removeEventListener('message', handleMessage);
}
})
}
33 changes: 25 additions & 8 deletions libraries/mspa/activityControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ACTIVITY_TRANSMIT_PRECISE_GEO
} from '../../src/activities/activities.js';
import {gppDataHandler} from '../../src/adapterManager.js';
import {logInfo} from '../../src/utils.js';

// default interpretation for MSPA consent(s):
// https://docs.prebid.org/features/mspa-usnat.html
Expand All @@ -24,7 +25,9 @@ export function isBasicConsentDenied(cd) {
// minors 13+ who have not given consent
cd.KnownChildSensitiveDataConsents[0] === 1 ||
// minors under 13 cannot consent
isApplicable(cd.KnownChildSensitiveDataConsents[1]);
isApplicable(cd.KnownChildSensitiveDataConsents[1]) ||
// covered cannot be zero
cd.MspaCoveredTransaction === 0;
}

export function sensitiveNoticeIs(cd, value) {
Expand Down Expand Up @@ -85,26 +88,40 @@ const CONSENT_RULES = {
[ACTIVITY_ENRICH_EIDS]: isConsentDenied,
[ACTIVITY_ENRICH_UFPD]: isTransmitUfpdConsentDenied,
[ACTIVITY_TRANSMIT_PRECISE_GEO]: isTransmitGeoConsentDenied
}
};

export function mspaRule(sids, getConsent, denies, applicableSids = () => gppDataHandler.getConsentData()?.applicableSections) {
return function() {
return function () {
if (applicableSids().some(sid => sids.includes(sid))) {
const consent = getConsent();
if (consent == null) {
return {allow: false, reason: 'consent data not available'};
}
if (denies(consent)) {
return {allow: false}
return {allow: false};
}
}
}
};
}

function flatSection(subsections) {
if (subsections == null) return subsections;
return subsections.reduceRight((subsection, consent) => {
return Object.assign(consent, subsection);
}, {});
}

export function setupRules(api, sids, normalizeConsent = (c) => c, rules = CONSENT_RULES, registerRule = registerActivityControl, getConsentData = () => gppDataHandler.getConsentData()) {
const unreg = [];
const ruleName = `MSPA (GPP '${api}' for section${sids.length > 1 ? 's' : ''} ${sids.join(', ')})`;
logInfo(`Enabling activity controls for ${ruleName}`)
Object.entries(rules).forEach(([activity, denies]) => {
unreg.push(registerRule(activity, `MSPA (${api})`, mspaRule(sids, () => normalizeConsent(getConsentData()?.sectionData?.[api]), denies, () => getConsentData()?.applicableSections || [])))
})
return () => unreg.forEach(ur => ur())
unreg.push(registerRule(activity, ruleName, mspaRule(
sids,
() => normalizeConsent(flatSection(getConsentData()?.parsedSections?.[api])),
denies,
() => getConsentData()?.applicableSections || []
)));
});
return () => unreg.forEach(ur => ur());
}
3 changes: 2 additions & 1 deletion modules/.submodules.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
"zeotapIdPlusIdSystem",
"adqueryIdSystem",
"gravitoIdSystem",
"freepassIdSystem"
"freepassIdSystem",
"operaadsIdSystem"
],
"adpod": [
"freeWheelAdserverVideo",
Expand Down
2 changes: 1 addition & 1 deletion modules/a1MediaRtdProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const REAL_TIME_MODULE = 'realTimeData';
const MODULE_NAME = 'a1Media';
const SCRIPT_URL = 'https://linkback.contentsfeed.com/src';
export const A1_SEG_KEY = '__a1tg';
export const A1_AUD_KEY = 'a1gid';
export const A1_AUD_KEY = 'a1_gid';

export const storage = getStorageManager({moduleType: MODULE_TYPE_RTD, moduleName: MODULE_NAME});

Expand Down
30 changes: 26 additions & 4 deletions modules/adagioBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,17 @@ function _getUspConsent(bidderRequest) {
return (deepAccess(bidderRequest, 'uspConsent')) ? { uspConsent: bidderRequest.uspConsent } : false;
}

function _getGppConsent(bidderRequest) {
let gpp = deepAccess(bidderRequest, 'gppConsent.gppString')
let gppSid = deepAccess(bidderRequest, 'gppConsent.applicableSections')

if (!gpp || !gppSid) {
gpp = deepAccess(bidderRequest, 'ortb2.regs.gpp', '')
gppSid = deepAccess(bidderRequest, 'ortb2.regs.gpp_sid', [])
}
return { gpp, gppSid }
}

function _getSchain(bidRequest) {
return deepAccess(bidRequest, 'schain');
}
Expand Down Expand Up @@ -976,6 +987,7 @@ export const spec = {
const gdprConsent = _getGdprConsent(bidderRequest) || {};
const uspConsent = _getUspConsent(bidderRequest) || {};
const coppa = _getCoppa();
const gppConsent = _getGppConsent(bidderRequest)
const schain = _getSchain(validBidRequests[0]);
const eids = _getEids(validBidRequests[0]) || [];
const syncEnabled = deepAccess(config.getConfig('userSync'), 'syncEnabled')
Expand All @@ -984,7 +996,7 @@ export const spec = {
const aucId = generateUUID()

const adUnits = _map(validBidRequests, (rawBidRequest) => {
const bidRequest = {...rawBidRequest}
const bidRequest = deepClone(rawBidRequest);

// Fix https://github.com/prebid/Prebid.js/issues/9781
bidRequest.auctionId = aucId
Expand Down Expand Up @@ -1118,15 +1130,23 @@ export const spec = {
// remove useless props
delete adUnitCopy.floorData;
delete adUnitCopy.params.siteId;
delete adUnitCopy.userId
delete adUnitCopy.userIdAsEids
delete adUnitCopy.userId;
delete adUnitCopy.userIdAsEids;

groupedAdUnits[adUnitCopy.params.organizationId] = groupedAdUnits[adUnitCopy.params.organizationId] || [];
groupedAdUnits[adUnitCopy.params.organizationId].push(adUnitCopy);

return groupedAdUnits;
}, {});

// Adding more params on the original bid object.
// Those params are not sent to the server.
// They are used for further operations on analytics adapter.
validBidRequests.forEach(rawBidRequest => {
rawBidRequest.params.adagioAuctionId = aucId
rawBidRequest.params.pageviewId = pageviewId
});

// Build one request per organizationId
const requests = _map(Object.keys(groupedAdUnits), organizationId => {
return {
Expand All @@ -1143,7 +1163,9 @@ export const spec = {
regs: {
gdpr: gdprConsent,
coppa: coppa,
ccpa: uspConsent
ccpa: uspConsent,
gpp: gppConsent.gpp,
gppSid: gppConsent.gppSid
},
schain: schain,
user: {
Expand Down
Loading