/** * Copyright since 2002 Creabilis * * NOTICE OF LICENSE crea cookie * * This source file is subject to the Academic Free License 3.0 (AFL-3.0) * that is bundled with this package in the file LICENSE.txt. * It is also available through the world-wide-web at this URL: * https://opensource.org/licenses/AFL-3.0 * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to contact@creabilis.com so we can send you a copy immediately. * * @author Creabilis * @copyright Since 2002 Creabilis * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) * International Registered Trademark & Property of Creabilis */ /** * Tracker consent storage in a cookie */ class TrackerConsentStorage { static cookieDuration() { return 365 } /* launch consented trackers with function like launchcc_[tracker] i.e. launchcc_myanalytics. Lauch custom javascript event cconsent_myanalytics */ launchTracking() { if (this.consentRegistered() && !this.newTrackersDetected()) { let consentedTrackers = this.getConsentedTrackers(); let toUpdateGGconsentModeTypes = {}; consentedTrackers.forEach(acceptedCookie => { // trackers has to be in managed tracker list crea_cookiesconsent_trackers if (crea_cookiesconsent_trackers.indexOf(acceptedCookie) === -1) { return; } // if tracker is a Google consent mode type, lauch gtag consent update if (crea_cookiesconsent_GGconsentModeTypes instanceof Array && crea_cookiesconsent_GGconsentModeTypes.indexOf(acceptedCookie) !== -1) { toUpdateGGconsentModeTypes[acceptedCookie] = 'granted'; // exit loop here, do no launch function or event return; } // construct function name: launchcc_[tracker], i.e. launchcc_myanalytics let trakingFunctionName = 'launchcc_' + acceptedCookie; if (eval('typeof ' + trakingFunctionName + ' === \'function\'')) { eval(trakingFunctionName + '();') } // trigger a javascript event cconsent_[tracker] let ccevent = new Event('cconsent_' + acceptedCookie); // Dispatch the event to the element document.dispatchEvent(ccevent); }) // Google Consent mode : lauch gtag consent update if (Object.keys(toUpdateGGconsentModeTypes).length > 0 && eval('typeof gtag === \'function\'')) { gtag('consent', 'update', toUpdateGGconsentModeTypes); } } } /* launch consented trackers in Tag Manager with custom event like cconsent_[tracker] i.e. cconsent_myanalytics */ launchTMTracking() { if (this.consentRegistered() && !this.newTrackersDetected()) { let consentedTrackers = this.getConsentedTrackers(); // init gtm dataLayer window.dataLayer = window.dataLayer || []; let cconsents = {}; consentedTrackers.forEach(acceptedCookie => { // trackers has to be in managed tracker list crea_cookiesconsent_trackers if (crea_cookiesconsent_trackers.indexOf(acceptedCookie) === -1) { return; } // if tracker is a Google consent mode type, do not lauch tag manager event if (crea_cookiesconsent_GGconsentModeTypes instanceof Array && crea_cookiesconsent_GGconsentModeTypes.indexOf(acceptedCookie) !== -1) { return; } // construct event name: cconsent_[tracker], i.e. cconsent_myanalytics let trakingEventName = 'cconsent_' + acceptedCookie; window.dataLayer.push({ 'event': trakingEventName }); cconsents[acceptedCookie]= true; }); window.dataLayer.push({'cconsents': cconsents}); } } /** * Check if since the user has consented, new trackers have been added, * if yes we ask again to consent otherwise we do nothing */ newTrackersDetected() { let newTrackerDetected = false; let allTrackers = this.getAllTrackers(); crea_cookiesconsent_trackers.forEach(managedTracker => { if (allTrackers.indexOf(managedTracker) === -1) { newTrackerDetected = true; } }) return newTrackerDetected; } /** * Check if a consent has already been registered by checking if the 'crea_cookieconsents' is already there */ consentRegistered() { return (this.getCookieValue('crea_cookieconsents') != ""); } /** * Register the tracker choices. * It sets a cookie called `crea_cookieconsents` with the value of `trackerChoices` :Y or :N * @param acceptedCookies - an array of the consented trackers * @param deniedCookies - an array of the declined trackers */ registerConsents(acceptedCookies, deniedCookies) { let trackerChoices = []; acceptedCookies.forEach((value, index) => { acceptedCookies[index] = value + ':Y'; }); deniedCookies.forEach((value, index) => { deniedCookies[index] = value + ':N'; }); trackerChoices = [].concat(acceptedCookies, deniedCookies); this.setCookie('crea_cookieconsents', trackerChoices, TrackerConsentStorage.cookieDuration()); } /** * Get all trackers registered: consented or not. */ getAllTrackers() { let allTrackers = []; let consentCookie = this.getCookieValue('crea_cookieconsents'); let allTrackersWithChoice = consentCookie.split(','); allTrackersWithChoice.forEach(tracker => { // Format to delete the :Y or :N extension tracker = tracker.slice(0, -2); allTrackers.push(tracker); }) return allTrackers; } /** * return consented trackers from consent cookie */ getConsentedTrackers() { let consentedTrackers = []; let consentCookie = this.getCookieValue('crea_cookieconsents'); let allTrackersWithChoice = consentCookie.split(','); allTrackersWithChoice.forEach(tracker => { if (tracker.indexOf(':Y') !== -1) { // Format to delete the :Y or :N extension tracker = tracker.slice(0, -2); consentedTrackers.push(tracker); } }) return consentedTrackers; } /** * Sets the cookie with the key and value specified in the parameters * @param key - The name of the cookie * @param value - The value of the cookie you want to set. * @param expiry - The number of days you want the cookie to last. */ setCookie(key, value, expiry) { let expires = new Date(); expires.setTime(expires.getTime() + (expiry * 24 * 60 * 60 * 1000)); document.cookie = key + '=' + value + '; path=/; expires=' + expires.toUTCString(); } /** * It returns the value of a cookie, given its name in the document.cookie string * @param cookieName - The name of the cookie * @returns The value of the cookie. */ getCookieValue(cookieName) { let cookieAssignation = cookieName + "="; let decodedCookie = decodeURIComponent(document.cookie); let cookieList = decodedCookie.split(';'); for (let i = 0; i < cookieList.length; i++) { let currentCookie = cookieList[i]; while (currentCookie.charAt(0) == ' ') { currentCookie = currentCookie.substring(1); } if (currentCookie.indexOf(cookieAssignation) == 0) { return currentCookie.substring(cookieAssignation.length, currentCookie.length); } } return ""; } }