From 03563b778b5c8d9bb2182704f903e697394f9d2f Mon Sep 17 00:00:00 2001
From: Andrew Isherwood <andrew.isherwood@ptfs-europe.com>
Date: Fri, 5 Feb 2021 16:19:00 +0000
Subject: [PATCH] Bug 27378: Add cookie domain and path

A subtlety I missed was that some tracking services, such as Google
Analytics, specify a cookie domain and path that differ from the
default. E.g. on a site with a domain of demostaff.koha-ptfs.co.uk, the
GA cookie will have a domain of '.koha-ptfs.co.uk' and a path of '/',
even though the cookie may have been set at a different path.

Both of these things makes sense, but of course unless we also specify
both of those things when we try to delete a previously set cookie, we
cannot.

Therefore, I have added two more bits of metadata to each "consent",
Cookie Domain and Cookie Path. It is necessary for an admin creating a
"consent" entry to know and specify these values. They can be
established by looking a cookie set by the service being configured.

This adds more complexity to setting up a consent, but we cannot remove
previously set cookies without it.

Signed-ff-by: Barry Cannon <bc@interleaf.ie>
---
 .../prog/en/includes/intranet-bottom.inc        |  2 +-
 .../intranet-tmpl/prog/js/cookieconsent.js      |  4 +++-
 .../intranet-tmpl/prog/js/pages/preferences.js  | 17 +++++++++++++++++
 .../bootstrap/en/includes/opac-bottom.inc       |  2 +-
 .../opac-tmpl/bootstrap/js/cookieconsent.js     |  4 +++-
 5 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/intranet-bottom.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/intranet-bottom.inc
index 9bcca6d5b4..3cbf7f4c1f 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/intranet-bottom.inc
+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/intranet-bottom.inc
@@ -136,7 +136,7 @@
     [% IF Koha.Preference( 'CookieConsent' ) && Koha.Preference( 'ConsentJS' ).length > 0 %]
         [% consents = JSConsents.all() %]
         [% FOREACH consent IN consents %]
-            <div class="consentCode" style="display:none" aria-hidden="true" data-consent-id="[% consent.id | html %]" data-consent-code="[% consent.code | html %]" data-consent-match-pattern="[% consent.matchPattern | html %]" data-requires-consent="[% consent.staffConsent ? 'true' : 'false' | html %]"></div>
+            <div class="consentCode" style="display:none" aria-hidden="true" data-consent-id="[% consent.id | html %]" data-consent-code="[% consent.code | html %]" data-consent-match-pattern="[% consent.matchPattern | html %]" data-consent-cookie-domain="[% consent.cookieDomain | html %]" data-consent-cookie-path="[% consent.cookiePath | html %]" data-requires-consent="[% consent.staffConsent ? 'true' : 'false' | html %]"></div>
         [% END %]
     [% END %]
     [% IF Koha.Preference( 'CookieConsent' ) %]
diff --git a/koha-tmpl/intranet-tmpl/prog/js/cookieconsent.js b/koha-tmpl/intranet-tmpl/prog/js/cookieconsent.js
index ff00a738d7..b74dba1066 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/cookieconsent.js
+++ b/koha-tmpl/intranet-tmpl/prog/js/cookieconsent.js
@@ -106,13 +106,15 @@
                 // This code doesn't have consent to run, we may need to remove
                 // any cookies it has previously set
                 const matchPattern = $(this).data('consent-match-pattern');
+                const cookieDomain = $(this).data('consent-cookie-domain');
+                const cookiePath = $(this).data('consent-cookie-path');
                 if (matchPattern.length > 0) {
                     const regex = new RegExp(matchPattern);
                     const allCookies = document.cookie.split('; ');
                     allCookies.forEach(function (cookie) {
                         const name = cookie.split('=')[0];
                         if (regex.test(name)) {
-                            document.cookie = name + '=; expires=Thu, 01 Jan 1970 00: 00: 01 GMT';
+                            document.cookie = name + '=; expires=Thu, 01 Jan 1970 00: 00: 01 GMT; domain=' + cookieDomain + '; path=' + cookiePath;
                         }
                     });
 
diff --git a/koha-tmpl/intranet-tmpl/prog/js/pages/preferences.js b/koha-tmpl/intranet-tmpl/prog/js/pages/preferences.js
index 012ec96d01..91d1a34ffc 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/pages/preferences.js
+++ b/koha-tmpl/intranet-tmpl/prog/js/pages/preferences.js
@@ -356,6 +356,14 @@ $( document ).ready( function () {
                '            <label for="matchPattern_' + id + '">' + __('String used to identify cookie name') + ':</label>' +
                '            <input id="matchPattern_' + id + '" class="metaMatchPattern" type="text" value="' + item.matchPattern + '"><span class="required">' + __('Required') + '</span>' +
                '        </div >' +
+               '        <div class="consentItem">' +
+               '            <label for="cookieDomain' + id + '">' + __('Cookie domain') + ':</label>' +
+               '            <input id="cookieDomain' + id + '" class="metaCookieDomain" type="text" value="' + item.cookieDomain + '"><span class="required">' + __('Required') + '</span>' +
+               '        </div >' +
+               '        <div class="consentItem">' +
+               '            <label for="cookiePath' + id + '">' + __('Cookie path') + ':</label>' +
+               '            <input id="cookiePath' + id + '" class="metaCookiePath" type="text" value="' + item.cookiePath + '"><span class="required">' + __('Required') + '</span>' +
+               '        </div >' +
                '    </div >' +
                '    <div class="consentRow codeRow">' +
                '        <textarea style="display:none;" id="pref_' + id + '" class="preference preference-code codemirror" rows="10" cols="40">' + code + '</textarea>' +
@@ -386,6 +394,8 @@ $( document ).ready( function () {
             name: '',
             description: '',
             matchPattern: '',
+            cookieDomain: '',
+            cookiePath: '',
             code: '',
             consentInOpac: false,
             consentInStaff: false
@@ -464,6 +474,8 @@ $( document ).ready( function () {
             const name = $(this).find('.metaName').val();
             const desc = $(this).find('.metaDescription').val();
             const matchPattern = $(this).find('.metaMatchPattern').val();
+            const cookieDomain = $(this).find('.metaCookieDomain').val();
+            const cookiePath = $(this).find('.metaCookiePath').val();
             const opacConsent = $(this).find('.opacConsent').is(':checked')
             const staffConsent = $(this).find('.staffConsent').is(':checked');
             const code = $(this).find('.preference-code').val();
@@ -473,6 +485,8 @@ $( document ).ready( function () {
                 name.length === 0 &&
                 desc.length === 0 &&
                 matchPattern.length === 0 &&
+                cookieDomain.length === 0 &&
+                cookiePath.length === 0 &&
                 code.length === 0
             ) {
                 return;
@@ -482,6 +496,7 @@ $( document ).ready( function () {
                 (name.length === 0) ||
                 (desc.length === 0) ||
                 (matchPattern.length === 0) ||
+                (cookiePath.length === 0) ||
                 (code.length === 0)
             ) {
                 invalid.push(this);
@@ -491,6 +506,8 @@ $( document ).ready( function () {
                     name: name,
                     description: desc,
                     matchPattern: matchPattern,
+                    cookieDomain: cookieDomain,
+                    cookiePath: cookiePath,
                     opacConsent: opacConsent,
                     staffConsent: staffConsent,
                     code: btoa(code)
diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc
index 4f9cd2ef3a..5a289ab524 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc
@@ -124,7 +124,7 @@
 [% IF Koha.Preference( 'CookieConsent' ) && Koha.Preference( 'ConsentJS' ).length > 0 %]
     [% consents = JSConsents.all() %]
     [% FOREACH consent IN consents %]
-        <div class="consentCode" style="display:none" aria-hidden="true" data-consent-id="[% consent.id | html %]" data-consent-code="[% consent.code | html %]" data-consent-match-pattern="[% consent.matchPattern | html %]" data-requires-consent="[% consent.opacConsent ? 'true' : 'false' | html %]"></div>
+        <div class="consentCode" style="display:none" aria-hidden="true" data-consent-id="[% consent.id | html %]" data-consent-code="[% consent.code | html %]" data-consent-match-pattern="[% consent.matchPattern | html %]" data-consent-cookie-domain="[% consent.cookieDomain | html  %]" data-consent-cookie-path="[% consent.cookiePath | html %]" data-requires-consent="[% consent.opacConsent ? 'true' : 'false' | html %]"></div>
     [% END %]
 [% END %]
 
diff --git a/koha-tmpl/opac-tmpl/bootstrap/js/cookieconsent.js b/koha-tmpl/opac-tmpl/bootstrap/js/cookieconsent.js
index b0e67ed6a7..ec4372216c 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/js/cookieconsent.js
+++ b/koha-tmpl/opac-tmpl/bootstrap/js/cookieconsent.js
@@ -120,13 +120,15 @@
                 // This code doesn't have consent to run, we may need to remove
                 // any cookies it has previously set
                 const matchPattern = $(this).data('consent-match-pattern');
+                const cookieDomain = $(this).data('consent-cookie-domain');
+                const cookiePath = $(this).data('consent-cookie-path');
                 if (matchPattern.length > 0) {
                     const regex = new RegExp(matchPattern);
                     const allCookies = document.cookie.split('; ');
                     allCookies.forEach(function (cookie) {
                         const name = cookie.split('=')[0];
                         if (regex.test(name)) {
-                            document.cookie = name + '=; expires=Thu, 01 Jan 1970 00: 00: 01 GMT';
+                            document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT; domain=' + cookieDomain +'; path=' + cookiePath;
                         }
                     });
                 }
-- 
2.20.1