From 865bcc285ede2f0a61396562e9bc1748050fc3a2 Mon Sep 17 00:00:00 2001 From: Benjamin Clot Date: Fri, 25 May 2018 15:00:15 +0200 Subject: [PATCH 1/4] ConsentManagement: detect __cmp in window.top --- modules/consentManagement.js | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/modules/consentManagement.js b/modules/consentManagement.js index fd961eeb17f..657508bb6b0 100644 --- a/modules/consentManagement.js +++ b/modules/consentManagement.js @@ -54,6 +54,7 @@ function lookupIabConsent(cmpSuccess, cmpError, hookConfig) { } } } + let callbackHandler = handleCmpResponseCallbacks(); let cmpCallbacks = {}; @@ -66,7 +67,7 @@ function lookupIabConsent(cmpSuccess, cmpError, hookConfig) { // 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 - if (utils.isFn(window.__cmp)) { + if (utils.isFn(window.__cmp)) { window.__cmp('getConsentData', null, callbackHandler.consentDataCallback); window.__cmp('getVendorConsents', null, callbackHandler.vendorConsentsCallback); } else if (inASafeFrame() && typeof window.$sf.ext.cmp === 'function') { @@ -84,8 +85,23 @@ function lookupIabConsent(cmpSuccess, cmpError, hookConfig) { f = f.parent; } - callCmpWhileInIframe('getConsentData', cmpFrame, callbackHandler.consentDataCallback); - callCmpWhileInIframe('getVendorConsents', cmpFrame, callbackHandler.vendorConsentsCallback); + if (!!cmpFrame) { + callCmpWhileInIframe('getConsentData', cmpFrame, callbackHandler.consentDataCallback); + callCmpWhileInIframe('getVendorConsents', cmpFrame, callbackHandler.vendorConsentsCallback); + } else { + try { + // force an exception in x-domain environments. #1509 + window.top.location.toString(); + + if (utils.isFn(window.top.__cmp)) { + window.top.__cmp('getConsentData', null, callbackHandler.consentDataCallback); + window.top.__cmp('getVendorConsents', null, callbackHandler.vendorConsentsCallback); + } + } catch (e) { + let errmsg = 'CMP not found'; + return cmpError(errmsg, hookConfig); + } + } } function inASafeFrame() { @@ -118,12 +134,6 @@ function lookupIabConsent(cmpSuccess, cmpError, hookConfig) { /* Setup up a __cmp function to do the postMessage and stash the callback. This function behaves (from the caller's perspective identicially to the in-frame __cmp call */ window.__cmp = function(cmd, arg, callback) { - if (!cmpFrame) { - removePostMessageListener(); - - let errmsg = 'CMP not found'; - return cmpError(errmsg, hookConfig); - } let callId = Math.random() + ''; let msg = {__cmpCall: { command: cmd, From c1f02df2de51c93b23ded560a573c43d320eb945 Mon Sep 17 00:00:00 2001 From: Benjamin Clot Date: Fri, 25 May 2018 16:36:32 +0200 Subject: [PATCH 2/4] Lighter modification Credits to @YOzaz --- modules/consentManagement.js | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/modules/consentManagement.js b/modules/consentManagement.js index 657508bb6b0..bf7fead6189 100644 --- a/modules/consentManagement.js +++ b/modules/consentManagement.js @@ -57,6 +57,7 @@ function lookupIabConsent(cmpSuccess, cmpError, hookConfig) { let callbackHandler = handleCmpResponseCallbacks(); let cmpCallbacks = {}; + let cmpFunction; // 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) @@ -67,9 +68,13 @@ function lookupIabConsent(cmpSuccess, cmpError, hookConfig) { // 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 - if (utils.isFn(window.__cmp)) { - window.__cmp('getConsentData', null, callbackHandler.consentDataCallback); - window.__cmp('getVendorConsents', null, callbackHandler.vendorConsentsCallback); + try { + cmpFunction = window.__cmp || utils.getWindowTop().__cmp; + } catch(e) {} + + if (utils.isFn(cmpFunction)) { + cmpFunction('getConsentData', null, callbackHandler.consentDataCallback); + cmpFunction('getVendorConsents', null, callbackHandler.vendorConsentsCallback); } else if (inASafeFrame() && typeof window.$sf.ext.cmp === 'function') { callCmpWhileInSafeFrame('getConsentData', callbackHandler.consentDataCallback); callCmpWhileInSafeFrame('getVendorConsents', callbackHandler.vendorConsentsCallback); @@ -85,23 +90,8 @@ function lookupIabConsent(cmpSuccess, cmpError, hookConfig) { f = f.parent; } - if (!!cmpFrame) { - callCmpWhileInIframe('getConsentData', cmpFrame, callbackHandler.consentDataCallback); - callCmpWhileInIframe('getVendorConsents', cmpFrame, callbackHandler.vendorConsentsCallback); - } else { - try { - // force an exception in x-domain environments. #1509 - window.top.location.toString(); - - if (utils.isFn(window.top.__cmp)) { - window.top.__cmp('getConsentData', null, callbackHandler.consentDataCallback); - window.top.__cmp('getVendorConsents', null, callbackHandler.vendorConsentsCallback); - } - } catch (e) { - let errmsg = 'CMP not found'; - return cmpError(errmsg, hookConfig); - } - } + callCmpWhileInIframe('getConsentData', cmpFrame, callbackHandler.consentDataCallback); + callCmpWhileInIframe('getVendorConsents', cmpFrame, callbackHandler.vendorConsentsCallback); } function inASafeFrame() { @@ -134,6 +124,12 @@ function lookupIabConsent(cmpSuccess, cmpError, hookConfig) { /* Setup up a __cmp function to do the postMessage and stash the callback. This function behaves (from the caller's perspective identicially to the in-frame __cmp call */ window.__cmp = function(cmd, arg, callback) { + if (!cmpFrame) { + removePostMessageListener() + + let errmsg = 'CMP not found'; + return cmpError(errmsg, hookConfig); + } let callId = Math.random() + ''; let msg = {__cmpCall: { command: cmd, From c3675ad92b17a1cddad248236fccd5a2725b08f8 Mon Sep 17 00:00:00 2001 From: Benjamin Clot Date: Fri, 25 May 2018 16:37:37 +0200 Subject: [PATCH 3/4] typo --- modules/consentManagement.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/consentManagement.js b/modules/consentManagement.js index bf7fead6189..0d489b92cd1 100644 --- a/modules/consentManagement.js +++ b/modules/consentManagement.js @@ -125,7 +125,7 @@ function lookupIabConsent(cmpSuccess, cmpError, hookConfig) { This function behaves (from the caller's perspective identicially to the in-frame __cmp call */ window.__cmp = function(cmd, arg, callback) { if (!cmpFrame) { - removePostMessageListener() + removePostMessageListener(); let errmsg = 'CMP not found'; return cmpError(errmsg, hookConfig); From c7df9f35daf92b4f6e5ef76e17bd6a8a1144600a Mon Sep 17 00:00:00 2001 From: Benjamin Clot Date: Fri, 25 May 2018 16:51:06 +0200 Subject: [PATCH 4/4] fixed spaces --- modules/consentManagement.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/consentManagement.js b/modules/consentManagement.js index 0d489b92cd1..af668523fa4 100644 --- a/modules/consentManagement.js +++ b/modules/consentManagement.js @@ -70,8 +70,8 @@ function lookupIabConsent(cmpSuccess, cmpError, hookConfig) { // if the CMP is not found, the iframe function will call the cmpError exit callback to abort the rest of the CMP workflow try { cmpFunction = window.__cmp || utils.getWindowTop().__cmp; - } catch(e) {} - + } catch (e) {} + if (utils.isFn(cmpFunction)) { cmpFunction('getConsentData', null, callbackHandler.consentDataCallback); cmpFunction('getVendorConsents', null, callbackHandler.vendorConsentsCallback);