Git Product home page Git Product logo

cmp's Introduction

Build Status

WARNING: This demo CMP code is absolutely not production-ready without additional time investment, and is not compatible with TCF 2.0.

AppNexus CMP

This sample CMP was designed to facilitate support for the initial adoption of TCF 1.0, and is not being actively maintained, and will not be updated to support TCF 2.0. We strongly recommend that you either adopt a commercial CMP or another open source alternative, then register the CMP with the IAB Europe to be recognized as sending valid signals in the advertising ecosystem. AppNexus requires the use of a CMP registered with the IAB Europe if using the TCF for GDPR/ePrivacy.

Installation

git clone https://github.com/appnexus/cmp.git
cd cmp
yarn install

Build for Production

yarn build

This produces a production build of the cmp script and the docs application:

  • ./build/cmp.bundle.js - CMP script to include on your site
  • ./build/docs/ - Application hosting the documentation

Documentation

Instructions to install the CMP as well as API docs and examples are available in the docs application included with the repo.

yarn start

The documentation can be viewed at: http://localhost:5000/docs/

Development

You can start a development server that will monitor changes to all CMP and docs files with:

yarn dev

Development server can be accessed at: http://localhost:8080/

Testing

yarn test

cmp's People

Contributors

alanstocco avatar asweeney86 avatar broutard avatar grantimus9 avatar hanson-tapatalk avatar krishoyt avatar logeen avatar pedroventura avatar potench avatar skoklowski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cmp's Issues

Allow/Reject all button issue

If I reject all vendors in a purpose that doesn't contain them all, they are all rejected.

Step to reproduce :

  • go to purpose "Personalisation" (2)
  • double click "accept all" to reject all vendors in this purpose

=> getVendorConsents returns false for each vendors (even vendor 12 which is not in this purpose).

handleAcceptAll = () => {
	this.props.selectAllVendors(true);
};

handleRejectAll = () => {
	this.props.selectAllVendors(false);
};

seems to be not relative to purpose.

Global Consent Location

hello,
I am looking through the code and I cannot figure out what the globalConsentLocation is (as below) in complete.js - I am interested in the purpose of this location.

const configUpdates = {
	globalConsentLocation: '//acdn.adnxs.com/cmp/docs/portal.html',
	...config
};

Thanks in advance.
Dennis

CMP UI not showing automatically

The API specs for the getVendorConsents, getConsentData and getPublisherConsents specifies that "The callback is called only after consent is obtained from the UI or existing cookies".
But it doesnt include any method to show the UI "manually", so looks like showing or not the UI, is the CMP responsability.
This is something i find very difficult (there are many possible scenarios), so i don't really mind breaking the specs about this. But, if it's my responsability to show the UI, i'd need to get more information from the CMP (like if the user already has a cookie or not), specially if using global cookies.
I've seen in other issues some patches to the CMP code to bring back the "autoshow" functionality, but if the showConsentTool is part of the API, it's because it should be called from user code, so i'd prefer to also keep the show-or-not logic in user code.
Are there plans to add additional commands to the API to know if the cookie exists or not?

the script blocks all google ads

A very strange behaviour happen with the script in page.
When the script is on the page with or without accepting the cookie all the advertising from google network doesn't appear.

If I remove the script from the page everything works as expected.

what can be the cause?

Global cookie with custom vendorlists

Hi, we want to use CMP for a network of websites of our clients, so I set up global cookie. Every client has it's own vendorlist defined where the version is increased every time the client makes changes to it. I set up CMP to use global cookie:

cmp.config = { globalVendorListLocation:"https://vendorlist.consensu.org/vendorlist.json", globalConsentLocation: 'http://cookie-domain.abc/portal.html', storeConsentGlobally: true, }
For each client the CMP tool is compiled with the client's individual vendor list, I set PUB_VENDOR_LOCATION in vendor.js to fetch the vendor list from the client's domain.

If a user opens a website the first time, the CMP displays the dialog. If the user confirms and opens another website, with different vendors defined the dialog isn't displayed. It should be displayed if there are vendors defined the user has never agreed to.

I'm not sure if this is a bug or intent behaviour. I appreciate any comment on this.

Are custom purposes being loaded?

The index.html file generated by the "build" command, includes this configuration:
cmp.config = { customPurposeListLocation: 'docs/purposes.json', globalConsentLocation: 'docs/portal.html' };
I cant see the docs/purposes.json file being loaded in the browser (so nothing is shown in the UI).
Is anything else needed to load the Custom Purpose list?

storeConsentGlobally: true - is not handling Safari failures (when 3'rd party cookies can't be set)

If I use this config setting:

storeConsentGlobally: true

..on Safari, there is no fallback to use a 1'st party cookie when writing of the 3'rd party cookie fails.

The effect is that the popup-window appears on every page load for Safari users - as the 3'rd party cookie is never written.

Would it be possible to implement this so that other browsers can still use global consent but Safari users will fallback to local consent?

TCF 2 ?

Is this project going to be updated to support TCF 2?

showConsentTool & the new banner

With the yesterday last changes, showConsentTool opens the new banner... not the consent popup :(

Is there a new way to open the popup ?

Maybe the parameter may takes 'popup' or 'banner' ...

vendorConsents's purposeConsents only works for single vendor?

Why are there no purposeConsents for each vendor in the vendorConsents?
The purposeConsents has only 1 set of purpose consents.

window.__cmp('getVendorConsents', [1, 12], function(result) {
	console.log(result);
	/*
	// result
	purposeConsents: {1: false, 2: false, 3: false, 4: false, 5: false}
	vendorConsents: {12: false, 1234: false}

	if there are multiple vendor IDs why is there only one set of
        purposeConsent for multiple vendors?
	*/
});

Should purposeConsents look something like:

	purposeConsents: {
		1: {1: false, 2: false, 3: false, 4: false, 5: false},
		12: {1: false, 2: false, 3: false, 4: false, 5: false},
	}

so you can tell which purposes are enabled for which vendor

New UI & customPurposes

It seems custom purposes are not displayed anymore in the new UI.
Right ?

purposes.json

{
  "version": 1,
  "purposes": [
	{
	  "id": 1,
	  "name": "Custom Purpose 1",
      "description": "Lorem ipsum dolor..."
	},
	{
	  "id": 2,
	  "name": "Custom Purpose 2"
	}
  ]
}

config

{
                customPurposeListLocation: '/.well-known/purposes.json',
                storePublisherData: true,
                logging: 'debug',             
            }

isLoaded callback

Hi,

The ad network I'm working with provided me with a js tag which auto fires a version of this CMP.
I want to change it a bit, and am possible to do (for example as a test):

        setTimeout(function(){
            window.__cmp('ping', null, function(result) {
                console.log('ping callback result: ' + JSON.stringify(result, null, 2));
            });
        }, 5000);

This works, but obviously I don't want to "guess" whenever the cmp is loaded. How can I detect when I can start using window.__cmp without getting: "window.__cmp is not defined" ?

Show Consent Tool only if consent not yet given

Hi, how do I check for whether consent has been given? Because once it has, the consent tool shouldn't be shown anymore to users.

I tried using

__cmp('getConsentData', null, function(result) {
  if(!result) {
    __cmp('showConsentTool');
  }
});

for this, but the callback is only run, if consent has been given already. So I cannot really use this to check whether it is or not.

When does gdprApplies flag turns to false ?

Hello team,

I am located in California, US and was checking the demo page.
http://acdn.adnxs.com/cmp/docs/#/basic/vendor

  • Is AppNexus taking responsibility for detecting Geo where GDPR applies and not and accordingly setting the gdprApplies flag?

  • I am wondering, why do I see gdprApples flag set to true considering that I am in the US it should be false, isn't it? Please help me understand this flag.

  • Moreover in a case when gdpApplies is set to false, will the CMP share user consent value in metadata field?

Ref: https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/CMP%20JS%20API%20v1.1%20Final.md

Clarification: policyUrl format

I notice in the global vendor list that Oracle/AddThis has an invalid policyUrl (it's two URLs comma separated). Since they are the only ones I assume this is an error that needs to be fixed. I found what appears to be a spec for policyUrl but it contains markdown which no vendor in the global list is actually using.

So I guess my question is to @krishoyt — how do we submit fixes to the global list? Or failing that, would you be open to a PR which makes URL handling more robust within the CMP?

Missing translations in Spanish

Hi,

The following translations entries are empty in Spanish (es):

  • es.banner.links.data.title
  • es.banner.links.data.description
  • es.banner.links.purposes.title
  • es.banner.links.purposes.description

Are there any official translations in Spanish for mentioned entries?

Thank you

Feature request: event when the consent tool is shown

We're relying on the automatic showing of the consent tool (as opposed to triggering it manually with showConsentTool). To track the rate of people who leave the consent tool open, we want to know how often it's shown (we can already track the number of submissions with the onSubmit event listener).

It would be great if a consentShown event is added.

PublisherConsents object doesn't match spec

The publisherConsents object returned by the CMP is missing the Consents suffix on standardPurposes and customPurposes, which would make them standardPurposeConsents and customPurposeConsents per the spec (copied below):

https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/CMP%20JS%20API%20v1.1%20Final.md#publisherconsents

{  
  metadata: ...
  gdprApplies:  *Boolean*,
  hasGlobalScope: *Boolean,*
  standardPurposeConsents: {
    *purposeId*: *consentBoolean*,
    ?
  },
  customPurposeConsents: {
    *customPurposeId*: *consentBoolean*,
    ?
  }
}

Custom localization doesn't work

Below configuration doesn't work now:

window.__cmp = {
    config: {
        localization: {
            pl: {
                // Polish translation here...
            }
        },
        forceLocale: 'pl-PL'
    }
};

This problem is caused by some commits that were done from April 17th because before it worked fine.

vendorListVersion set to 0 when using publisher vendor list

When the publisher list is loaded the CMP always sets the vendorListVersion to 0 and it seems that there's no way to determine if there were any changes to the list.

https://github.com/appnexus/cmp/blob/master/src/lib/store.js#L359-L361

// If a pubVendorList is applied make the vendor list version = 0
const { publisherVendorsVersion } = pubVendorsList;
vendorList.vendorListVersion = publisherVendorsVersion ? 0 : vendorList.vendorListVersion;

is this expected behaviour?
If the version is always stored as 0 how to decide when to show the consent tool after some changes have been made to the list?

Prebid ignores CMP

Without this CMP plugin on my page, I get the following error:

CMP not found Canceling auction as per consentManagement config.

After adding the CMP script the page just like in Setup Script section, the error disappears. When I click on "Continue to site" I get the following error and the banner keeps getting displayed:

Uncaught TypeError: Cannot read property 'apply' of undefined
    at y (prebid_gdpr.js:6)
    at w (prebid_gdpr.js:6)
    at e (prebid_gdpr.js:6)
    at vendorConsentsCallback (prebid_gdpr.js:6)
    at Object.getVendorConsents (cmp.complete.bundle.js:1)
    at e.processCommand (cmp.complete.bundle.js:1)
    at cmp.complete.bundle.js:1
    at Array.forEach (<anonymous>)
    at e.processCommandQueue (cmp.complete.bundle.js:1)
    at notify (cmp.complete.bundle.js:1)

If I refresh the page, the "euconsent" cookie is set and the banner is not displayed. After the timeout period, Prebid gives the error:

CMP workflow exceeded timeout threshold. Canceling auction as per consentManagement config.
Error executing bidsBackHandler

How does the CMP plugin "talk" to Prebid? How is the consent passed to the bidders?

I'll leave here the full code that I am trying to run.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Server to Server Test</title>

    <script>
        (function(window, document) {
            if (!window.__cmp) {
                window.__cmp = (function() {
                    var listen = window.attachEvent || window.addEventListener;
                    listen('message', function(event) {
                        window.__cmp.receiveMessage(event);
                    }, false);

                    function addLocatorFrame() {
                        if (!window.frames['__cmpLocator']) {
                            if (document.body) {
                                var frame = document.createElement('iframe');
                                frame.style.display = 'none';
                                frame.name = '__cmpLocator';
                                document.body.appendChild(frame);
                            } else {
                                setTimeout(addLocatorFrame, 5);
                            }
                        }
                    }
                    addLocatorFrame();

                    var commandQueue = [];
                    var cmp = function(command, parameter, callback) {
                        if (command === 'ping') {
                            if (callback) {
                                callback({
                                    gdprAppliesGlobally: !!(window.__cmp && window.__cmp.config && window.__cmp.config.storeConsentGlobally),
                                    cmpLoaded: false
                                });
                            }
                        } else {
                            commandQueue.push({
                                command: command,
                                parameter: parameter,
                                callback: callback
                            });
                        }
                    }
                    cmp.commandQueue = commandQueue;
                    cmp.receiveMessage = function(event) {
                        var data = event && event.data && event.data.__cmpCall;
                        if (data) {
                            commandQueue.push({
                                callId: data.callId,
                                command: data.command,
                                parameter: data.parameter,
                                event: event
                            });
                        }
                    };
                    cmp.config = {
                        //
                        // Modify config values here
                        //
                        globalVendorListLocation: 'https://vendorlist.consensu.org/vendorlist.json',
                        // customPurposeListLocation: './purposes.json',
                        // globalConsentLocation: './portal.html',
                        // storeConsentGlobally: false,
                        // storePublisherData: false,
                        // logging: 'debug',
                        // localization: {},
                        // forceLocale: 'en-us'
                    }
                    return cmp;
                }());
            }
        })(window, document);
    </script>
    <script src="//acdn.adnxs.com/cmp/cmp.complete.bundle.js"></script>
</head>
<body>
    <h1>Server To Server</h1>

    <script src="prebid_gdpr.js"></script>
    <script>
    var pbjs = pbjs || {};

    pbjs.que.push(function() {

        pbjs.setConfig({
          consentManagement: {
            cmpApi: 'iab',
            timeout: 5000,
            allowAuctionWithoutConsent: false
          }
        });

        var adUnits = [
            {
                "code": "RLFans-Unit1",
                "path": "/15188745/RLFans-Unit1",
                "safeFrame": true,
                "stickyAdPosition": "bc",
                "lazyLoad": false,
                "sizes": [
                    [
                        970,
                        250
                    ],
                    [
                        970,
                        90
                    ]
                ],
                "bids": [
                    {
                        "bidder": "appnexus",
                        "params": {
                            "placementId": 6381313,
                            "referrer": "rlfans.co.uk",
                            "alt_referrer": "rlfans.co.uk"
                        }
                    },
                    {
                        "bidder": "appnexus",
                        "params": {
                            "placementId": 6381314,
                            "referrer": "rlfans.co.uk",
                            "alt_referrer": "rlfans.co.uk"
                        }
                    },
                ]
            }
        ];
        pbjs.addAdUnits(adUnits);
        pbjs.requestBids();
    });
    </script>
</body>
</html>

design not responsive

Hello, from mobile device the banner and also the popup doesn't show up correctly, everything seems cropped.

Banner version

Hello,

When I go to your documentation and show the consent tool, I have the banner version but when I try the same thing with local sources from master branch, I still have the modal version.

Is this banner version a custom branch not merged to master yet? Or is this a customized version dedicated to AppNexus and not available in github?

Thanks for your help.

Question about `__cmpLocator` `addLocatorFrame()`

First, thanks for the library, it's been really helpful!

I'm curious what the __cmpLocator iframe is used for; I don't see it referenced anywhere else in the project. Is it necessary to run the addLocatorFrame() function?

Uncaught TypeError: window.__cmp.receiveMessage is not a function

I see above error in browser console. This problem is caused by some commits that were done from April 17th because before it worked fine. I suppose the source are changes in "/src/complete.js" file: premature listening on messages from iframe when receiveMessage function is not defined yet. This error occurs on specific configuration on only when you use "/cmp.complete.bundle.js" file:

<script>
__cmp = {
    config: {
        customPurposeListLocation: null,
        globalConsentLocation: 'docs/portal.html',
        storeConsentGlobally: true,
        storePublisherData: true
    }
};
</script>
<script src="./cmp.complete.bundle.js" async></script>

getPublisherConsents and getVendorConsents return the same metadata

According to the specification: https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/CMP%20JS%20API%20v1.1%20Final.md

  1. getPublisherConsents calls callback function with PublisherConsents as the parameter. PublisherConsents.metadata should contain "encoded string in the publisher consent format"

  2. getVendorConsents calls callback function with VendorConsents as the parameter. VendorConsents.metadata should contain "string (header data from the vendor consent format, as described below)"

As I understand "publisher consent format" and "vendor consent format" are different formats. Yet when I clone the latest version of appnexus/cmp and run yarn start, go through consent dialog and then call cmp api:

window.__cmp('getVendorConsents', null, function(d){console.log('concent cb', d.metadata)})
window.__cmp('getPublisherConsents', null, function(d){console.log('concent cb', d.metadata)})

In both cases I get the same result:
concent cb BOOM_WVOOM_WVABABAENAZ-AAAARF7______b933__7v9uD7Kr_K7VfxnHGUr2hPVA9LDOAqAAQ

Am I missing something?

Giving consent to purposes

Hello,
Why in the new popup there is no possibility to save consent to purposes? On each purpose detail I can only accept vendors from the list, and in saved cookie all of the purposes have value 'false'. In previous version each purpose had his own field to give an consent.

Any way to show consent window directly ?

Looking to show following policy window/popup/lightbox on click of button/link on our policy page once user have accepted the term we would like to allow them to change their preference any time

window.__cmp('showConsentTool')
opens the first window where user have option to accept the policy again as user have already accepted policy the first window which shows button to accept policy is of no help.

image
Use case scenario - User have accepted the terms and conditions but we need to show and allow to change the options any time . We are looking to show option to open this dialogue/popup/lightbox on Our polixy page .

Issues with setting HTTP Cookies

Does the framework have any suggestions/best practice/code snippets to show how third party cookies should be set in an ideal world?

The implementation I am working on is having issues cross browser.

Loading a CMP via a script tag on a publisher/advertiser site works well. As does then setting cookies from that domain.

However then making calls to the server to solicit a Set-Cookie header, does not seem to stick with all browsers.

Some help would be great, as cookies had been decided by the IAB as the storage mechanism, so guidance would be useful.

Thanks,
D

Feature request: Additional opt-out links defined by site admin

I guess my question is two-fold:

  1. Is there a technical solution to displaying additional opt-out links?
  2. If it's technically feasible, would there be legal implications that would discourage a website owner from displaying non-IAB out-out links in this fashion?

I'm implementing this CMP for a client and it was requested that I add all opt-out links to the CMP itself within the allow/disallow/opt-out tables. It is desired that the links be present even if a vendor is not IAB-approved. An example is Google Analytics opt-out.

I tried manually modifying my generated pubvendors.json file with either a negative number, 0, or extremely large number as vendor ID. But it seems that if I add any vendor which isn't in the approved list, the tool defaults to showing the entire global vendor list instead of my reduced set.

Race condition

I wonder if it is a bug or a feature ;-) Until vendorlist.json file is loaded (before "cmpReady" event is dispatched) command "getVendorConsents" and even "getPublisherConsents" returns false no matter which purposes you check.

It seems it's because CMP filters consents read from cookie according to purposes obtained from vendorlist.json file. But if this file hasn't been loaded yet CMP drops all consents read from cookie and returns false.

use https connection

hello is there a way to set up the script in order to use ssl certificates?

actually it runs only on http connection

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.