@bx80 opened this Pull Request on July 14th 2022 Contributor

Description:

Fixes #17452

This is PR contains the UI changes to allow a choice between the tracker opt-out and the self-contained opt-out.

The self-contained code is ~85 lines and this contains a small 'MatomoConsent' class to handle basic checking, reading and writing of the consent cookie. All settings, including single language translations, are passed in as an object so they are easily editable at the top of the code block.

The 'MatomoConsent' class is reused the fallback method for the tracker opt out JavaScript to set cookies directly should the Matomo tracker be unavailable.

The tracker opt-out supports the following URL parameters and is compatible with the existing iFrame opt-out URL (just change optOut to optOutJS and add the div) :

backgroundColor
fontColor
fontSize
fontFamily
language              default "auto"            Language code for translations ("auto" for browser language)
showIntro             default 1                 Should the opt-out intro text be shown?
divId                 default "matomo-opt-out"  The id of the div which will contain the opt-out form
useCookiesIfNoTracker default 1                 Directly read/written consent cookies if no tracker found?
useCookiesTimeout     default 10                How long to wait for the tracker to be detected?
useSecureCookies      default 1                 Set secure cookies?

Review

@bx80 commented on July 22nd 2022 Contributor

@sgiehl I've haven't implemented the requirement that if the tracker cannot be found then detect if the user is logged into the Matomo dashboard and show an error on the webpage and log an application error. I'm not seeing a straightforward way to do this without trying to read Matomo session cookies and add new API calls to log errors, which seems like an overkill. Any suggestions?

@bx80 commented on July 25th 2022 Contributor

In case it's helpful for testing, this is the tracking page I used during development, it can load the tracker after a random delay (or not at all) and includes a URL string with all the parameters.

<html>
  <head>
    <meta charset="utf-8">
    <title>OptOutJS</title>

    <!-- Matomo -->
    <script>

    // Test variables
    let loadTracker = true;
    let maxRandomDelay = 10;
    let minRandomDelay = 5;
    // ---

    function loadMatomoTracker() {
      console.log('.. now loading Matomo tracker');
      var _paq = window._paq = window._paq || [];
      _paq.push(['trackPageView']);
      _paq.push(['enableLinkTracking']);
      (function() {
        var u="//matomo/";
        _paq.push(['setTrackerUrl', u+'matomo.php']);
        _paq.push(['setSiteId', '3']);
        var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
        g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
      })();
    }

    if (loadTracker === true)  {
      let randomInterval = (Math.floor((Math.floor(Math.random() * ((maxRandomDelay * 1000) - (minRandomDelay * 1000)) ) + (minRandomDelay * 1000)) / 1000) * 1000);
      setTimeout(function() { loadMatomoTracker() }, randomInterval);
      console.log('delaying Matomo tracker load for '+randomInterval / 1000+' seconds...');
    } else {
      console.log('tracker loading disabled');
    }
    </script>
    <!-- End Matomo Code -->

  </head>
  <body>
  OptOutJS
  <br><br>

  <div id="matomo-opt-out" style="text-align:center;width:350px;padding:10px">...opt-out loading...</div>
  <script src="https://matomo//index.php?module=CoreAdminHome&action=optOutJS&useCookiesTimeout=10&div=m-opt-out&language=auto&backgroundColor=BBBBFF&fontColor=444444&fontSize=16px&fontFamily=TimesNewRoman&showIntro=1&useCookiesIfNoTracker=1"></script>

  </body>
</html>
@sgiehl commented on July 25th 2022 Member

I've haven't implemented the requirement that if the tracker cannot be found then detect if the user is logged into the Matomo dashboard and show an error on the webpage and log an application error. I'm not seeing a straightforward way to do this without trying to read Matomo session cookies and add new API calls to log errors, which seems like an overkill. Any suggestions?

I guess I would have tried to solve that using the opt out code. The page, that includes the optout, fetches some javascript from Matomo, so in case the user is logged in you could simply add some more javascript code, that if matomo.js can't be loaded displays a warning and/or sends back a request to matomo, to log an error. But that for sure would only work if the javascript returned for the optout wasn't cached.
Maybe @tsteur has a better idea.

@bx80 commented on July 26th 2022 Contributor

The page, that includes the optout, fetches some javascript from Matomo, so in case the user is logged in you could simply add some more javascript code, that if matomo.js can't be loaded displays a warning and/or sends back a request to matomo, to log an error.

That was my plan, but the optOutJS request in many cases is likely to be cross-site and therefore doesn't pass any Matomo session cookies (which are Same-site:Lax and httpOnly by default), so when processing the optOutJS request Matomo doesn't know about the current session and is unaware that the user is logged in. For the similar reasons there's not going to be a secure way for the optOutJS code running on domain a to access the Matomo session for domain b at runtime either.

Without access to the Matomo API I suppose we could still use the tracking API to force some sort of tracking failure log (eg. GET https://matomo/matomo.php?idsite=9999998&rec=1), but I'm not sure that we'd want to create failure logs for every visitor who can't load the tracker JS.

@sgiehl commented on July 26th 2022 Member

@bx80 Good points. But I actually don't have any further ideas how to solve that requirement.
Maybe we should discuss this requirement with @tsteur again. I understand the purpose why this could be helpful. But actually I'm wondering if there might be cases where it might be on purpose that the optout might be shown without having the tracker js file loaded.
For example a consent manager could provide opt outs for certain tracking mechanisms, but might prevent loading any tracking code before it's accepted or declined maybe. Not sure if a warning would annoy a Matomo user in that case.

@tsteur commented on July 27th 2022 Member

But I actually don't have any further ideas how to solve that requirement. Maybe we should discuss this requirement with @tsteur again.

does this refer to below requirement?

I've haven't implemented the requirement that if the tracker cannot be found then detect if the user is logged into the Matomo dashboard and show an error on the webpage and log an application error. I'm not seeing a straightforward way to do this without trying to read Matomo session cookies and add new API calls to log errors, which seems like an overkill. Any suggestions?

It could be fine to not implement as long as people have a chance to notice that the opt in won't work if the JS tracker file isn't loaded on the same page. It could otherwise cause legal issues if the opt out is embedded and not working.

Note: I believe when using a consent manager then the opt out is typically handled through the consent manager and not through an extra opt out screen unless they use both (which is maybe not done normally)

@bx80 commented on July 28th 2022 Contributor

It could be fine to not implement as long as people have a chance to notice that the opt in won't work if the JS tracker file isn't loaded on the same page. It could otherwise cause legal issues if the opt out is embedded and not working.

@tsteur By default we have a fallback method included which will directly set the required consent cookies if the JS tracker isn't loaded on the page. We're not currently providing a UI option to disable this. So unless someone deliberately adds the extra URL parameter to disable the fallback method then it there doesn't seem to be a way to have the opt-out fail silently.

Tracker? Use tracker to set consent.
No tracker? Set consent cookies directly (also console log)
No cookies? Show error on page.
No https? Show error on page.
No opt out div found? (console log only)

The weak point here is if the opt out div is not found on the page. It might be better to add a div to the page and show a visible error message instead of just a console log. If I make that change then perhaps we don't need to implement logged in user detection / application logs?

@tsteur commented on July 28th 2022 Member

No tracker? Set consent cookies directly (also console log)

This would only work if they have configured cookie settings somehow? Like it may cause issues if they otherwise use different cookie settings? I suppose there's no way for us to detect this. Maybe we can give people clear instructions on how to test that the opt out works?

The weak point here is if the opt out div is not found on the page. It might be better to add a div to the page and show a visible error message instead of just a console log. If I make that change then perhaps we don't need to implement logged in user detection / application logs?

Sounds good. Note that the JS file may be loaded before the div is there depending on how the file is being loaded.

@bx80 commented on July 28th 2022 Contributor

No tracker? Set consent cookies directly (also console log)

This would only work if they have configured cookie settings somehow? Like it may cause issues if they otherwise use different cookie settings? I suppose there's no way for us to detect this. Maybe we can give people clear instructions on how to test that the opt out works?

If they have configured custom cookie settings in Matomo (cookie_path, cookie_domain, etc) then those settings will be included in the served JavaScript and will be used, otherwise the default Matomo consent cookie settings will be used. It should always be using the same cookie settings as the JS tracker,

We could add an info box on the opt-out code screen encouraging testing of the opt-out. Something like:


Remember to test your opt-out!
To ensure that your opt-out is working properly with your website it is recommended to perform the following quick test after adding the opt out code.

  • Browse to your main website page.
  • Once the page has loaded you should see the opt-out box.
  • Unchecking the checkbox to opt-out should show the opted-out message.
  • Checking the checkbox to opt-in should show the opted-in message.

The weak point here is if the opt out div is not found on the page. It might be better to add a div to the page and show a visible error message instead of just a console log. If I make that change then perhaps we don't need to implement logged in user detection / application logs?

Sounds good. Note that the JS file may be loaded before the div is there depending on how the file is being loaded.

The main opt out code initializes from a DOMContentLoaded event listener, so hopefully this will make sure the div has always had chance to be rendered before we check for it.

@tsteur commented on July 29th 2022 Member

If they have configured custom cookie settings in Matomo (cookie_path, cookie_domain, etc) then those settings will be included in the served JavaScript and will be used, otherwise the default Matomo consent cookie settings will be used. It should always be using the same cookie settings as the JS tracker,

FYI typically people don't configure cookie settings in Matomo as these settings only apply to third party cookie. The first party cookie is configured in the JS tracking code usually. Meaning the config in Matomo would likely not be of much help (unless I'm missing something which is possible).

We could add an info box on the opt-out code screen encouraging testing of the opt-out. Something like:

That be great 👍

The main opt out code initializes from a DOMContentLoaded event listener, so hopefully this will make sure the div has always had chance to be rendered before we check for it.

Awesome 👍

@github-actions[bot] commented on August 15th 2022 Contributor

This issue is in "needs review" but there has been no activity for 7 days. ping @matomo-org/core-reviewers

Powered by GitHub Issue Mirror