Skip to content

Commit

Permalink
Change requests
Browse files Browse the repository at this point in the history
  • Loading branch information
tjeastmond committed Nov 27, 2019
1 parent 8305e1d commit b5d918e
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 70 deletions.
88 changes: 28 additions & 60 deletions modules/consentManagement.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
import * as utils from '../src/utils';
import { config } from '../src/config';
import { gdprDataHandler, ccpaDataHandler } from '../src/adapterManager';
import { gdprDataHandler, uspDataHandler } from '../src/adapterManager';
import includes from 'core-js/library/fn/array/includes';
import strIncludes from 'core-js/library/fn/string/includes';

Expand Down Expand Up @@ -189,19 +189,19 @@ function lookupIabConsent(cmpSuccess, cmpError, hookConfig) {
}
}

function lookupUspConsent(ccpaSucess, cmpError, hookConfig) {
function lookupUspConsent(uspSucess, cmpError, hookConfig) {
function handleCmpResponseCallbacks() {
const ccpaResponse = {};
const uspResponse = {};

function afterEach() {
if (ccpaResponse.consentString) {
ccpaSucess(ccpaResponse, hookConfig);
if (uspResponse.usPrivacy) {
uspSucess(uspResponse, hookConfig);
}
}

return {
consentDataCallback: function (consentResponse) {
ccpaResponse.consentString = consentResponse.consentString;
uspResponse.usPrivacy = consentResponse.usPrivacy;
afterEach();
}
}
Expand All @@ -211,69 +211,37 @@ function lookupUspConsent(ccpaSucess, cmpError, hookConfig) {
let uspapiCallbacks = {};
let ccpaFunction;

// to collect the consent information from the user, we perform two calls to the CMP in parallel:
// first to collect the user's consent choices represented in an encoded string (via getConsentData)
// second to collect the user's full unparsed consent information (via getVendorConsents)

// the following code also determines where the CMP is located and uses the proper workflow to communicate with it:
// check to see if CMP is found on the same window level as prebid and call it directly if so
// check to see if prebid is in a safeframe (with CMP support)
// else assume prebid may be inside an iframe and use the IAB CMP locator code to see if CMP's located in a higher parent window. this works in cross domain iframes
// if the CMP is not found, the iframe function will call the cmpError exit callback to abort the rest of the CMP workflow
// the following code also determines where the USP is located and uses the proper workflow to communicate with it:
// check to see if USP is found on the same window level as prebid and call it directly if so
// check to see if prebid is in a safeframe (with USP support)
// else assume prebid may be inside an iframe and use the IAB USP locator code to see if USP's located in a higher parent window. this works in cross domain iframes
// if the USP is not found, the iframe function will call the cmpError exit callback to abort the rest of the USP workflow
try {
ccpaFunction = window.__uspapi || utils.getWindowTop().__uspapi;
} catch (e) { }

if (utils.isFn(ccpaFunction)) {
ccpaFunction('getConsentData', null, callbackHandler.consentDataCallback);
} else if (inASafeFrame() && typeof window.$sf.ext.uspapi === 'function') {
callCcpaWhileInSafeFrame('getConsentData', callbackHandler.consentDataCallback);
ccpaFunction('getUSPData', 1, callbackHandler.consentDataCallback);
} else {
// find the CMP frame
let f = window;
let ccpaFrame;
while (!ccpaFrame) {
let uspFrame;
while (!uspFrame) {
try {
if (f.frames['__uspapiLocator']) ccpaFrame = f;
if (f.frames['__uspapiLocator']) uspFrame = f;
} catch (e) { }
if (f === window.top) break;
f = f.parent;
}

if (!ccpaFrame) {
return cmpError('CCPA not found.', hookConfig);
if (!uspFrame) {
return cmpError('USP not found.', hookConfig);
}

callCcpaWhileInIframe('getConsentData', ccpaFrame, callbackHandler.consentDataCallback);
}

function inASafeFrame() {
return !!(window.$sf && window.$sf.ext);
}

function callCcpaWhileInSafeFrame(commandName, callback) {
function sfCallback(msgName, data) {
if (msgName === 'cmpReturn') {
let responseObj = (commandName === 'getConsentData') ? data.vendorConsentData : data.vendorConsents;
callback(responseObj);
}
}

// find sizes from adUnits object
let adUnits = hookConfig.adUnits;
let width = 1;
let height = 1;
if (Array.isArray(adUnits) && adUnits.length > 0) {
let sizes = utils.getAdUnitSizes(adUnits[0]);
width = sizes[0][0];
height = sizes[0][1];
}

window.$sf.ext.register(width, height, sfCallback);
window.$sf.ext.ccpa(commandName);
callCcpaWhileInIframe('getUSPData', uspFrame, callbackHandler.consentDataCallback);
}

function callCcpaWhileInIframe(commandName, ccpaFrame, moduleCallback) {
function callCcpaWhileInIframe(commandName, uspFrame, moduleCallback) {
/* Setup up a __ccpa function to do the postMessage and stash the callback.
This function behaves (from the caller's perspective identicially to the in-frame __ccpa call */
window.__uspapi = function (cmd, ver, callback) {
Expand All @@ -286,7 +254,7 @@ function lookupUspConsent(ccpaSucess, cmpError, hookConfig) {
}
};
uspapiCallbacks[callId] = callback;
ccpaFrame.postMessage(msg, '*');
uspFrame.postMessage(msg, '*');
};

/** when we get the return message, call the stashed callback */
Expand Down Expand Up @@ -400,14 +368,14 @@ function processCmpData(consentObject, hookConfig) {
}
}

function processCcpaData (consentObject, hookConfig) {
if (!(consentObject && consentObject.consentString)) {
cmpFailed(`CCPA returned unexpected value during lookup process.`, hookConfig, consentObject);
function processCcpaData(consentObject, hookConfig) {
if (!(consentObject && consentObject.usPrivacy)) {
cmpFailed(`USP returned unexpected value during lookup process.`, hookConfig, consentObject);
return;
}

clearTimeout(hookConfig.timer);
storeCcpaConsentData(consentObject);
storeUspConsentData(consentObject);
exitModule(null, hookConfig);
}

Expand Down Expand Up @@ -447,11 +415,11 @@ function storeConsentData(cmpConsentObject) {
gdprDataHandler.setConsentData(consentData);
}

function storeCcpaConsentData(consentObject) {
function storeUspConsentData(consentObject) {
consentData = {
consentString: consentObject ? consentObject.consentString : undefined
usPrivacy: consentObject ? consentObject.usPrivacy : undefined
};
ccpaDataHandler.setConsentData(consentData);
uspDataHandler.setConsentData(consentData);
}

/**
Expand Down Expand Up @@ -503,7 +471,7 @@ function exitModule(errMsg, hookConfig, extraArgs) {
export function resetConsentData() {
consentData = undefined;
gdprDataHandler.setConsentData(null);
ccpaDataHandler.setConsentData(null);
uspDataHandler.setConsentData(null);
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/adapterManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,13 @@ export let gdprDataHandler = {
}
};

export let ccpaDataHandler = {
export let uspDataHandler = {
consentData: null,
setConsentData: function(consentInfo) {
ccpaDataHandler.consentData = consentInfo;
uspDataHandler.consentData = consentInfo;
},
getConsentData: function() {
return ccpaDataHandler.consentData;
return uspDataHandler.consentData;
}
};

Expand Down
14 changes: 7 additions & 7 deletions test/spec/modules/consentManagement_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
staticConsentData,
consentTimeoutUSP
} from 'modules/consentManagement';
import {gdprDataHandler, ccpaDataHandler} from 'src/adapterManager';
import {gdprDataHandler, uspDataHandler} from 'src/adapterManager';
import * as utils from 'src/utils';
import { config } from 'src/config';

Expand Down Expand Up @@ -755,7 +755,7 @@ describe.only('consentManagement', function () {
var response = {
__uspapiReturn: {
callId,
returnValue: { consentString: '1NN' },
returnValue: { usPrivacy: '1NN' },
success: true
}
};
Expand All @@ -777,10 +777,10 @@ describe.only('consentManagement', function () {
stringifyResponse = messageFormatString;
setConsentConfig(_goodConfigWithAllowAuction, 'usp');
requestBidsHook(() => {
let consent = ccpaDataHandler.getConsentData();
let consent = uspDataHandler.getConsentData();
sinon.assert.notCalled(utils.logWarn);
sinon.assert.notCalled(utils.logError);
expect(consent.consentString).to.equal('1NN');
expect(consent.usPrivacy).to.equal('1NN');
done();
}, {}, true);
});
Expand Down Expand Up @@ -834,7 +834,7 @@ describe.only('consentManagement', function () {

it('USP: performs lookup check and stores consentData for a valid existing user', function () {
let testConsentData = {
consentString: '1YY'
usPrivacy: '1YY'
};
cmpStub = sinon.stub(window, '__uspapi').callsFake((...args) => {
args[2](testConsentData);
Expand All @@ -848,12 +848,12 @@ describe.only('consentManagement', function () {
requestBidsHook(() => {
didHookReturn = true;
}, {}, true);
let consent = ccpaDataHandler.getConsentData();
let consent = uspDataHandler.getConsentData();

sinon.assert.notCalled(utils.logWarn);
sinon.assert.notCalled(utils.logError);
expect(didHookReturn).to.be.true;
expect(consent.consentString).to.equal(testConsentData.consentString);
expect(consent.usPrivacy).to.equal(testConsentData.usPrivacy);
});

it('throws an error when processCmpData check failed while config had allowAuction set to false', function () {
Expand Down

0 comments on commit b5d918e

Please sign in to comment.