1/****************************************************************************** 2// Firma: Hehner Reus Systems GmbH 3// Projekt: com.cerno.basis 4// Datei: consentManager.js 5// Erstellung: 05.02.2020 6// Verwendung: Sammlung von Funktionen rund um den Consent-Manager. 7// Achtung: Manche Funktionen benötigen die Basis- und Ajax-Libs! 8******************************************************************************/ 9 10/** 11 * Ermittelt den Schlüssel des Consent-Manager-Eintrages im LocalStorage. 12 * 13 * @return Schlüssel des Consent-Manager-Eintrages im LocalStorage. 14 */ 15function getLocalStorageObjKey() 16{ 17 try 18 { 19 if (localStorage && localStorage.length > 0) 20 { 21 var consentKey = ''; 22 var i; 23 var l = localStorage.length; 24 for (i = 0; i < l; i++) 25 { 26 var key = localStorage.key(i); 27 if (key && (key.lastIndexOf('GIPS-Consent-', 0) === 0)) 28 { 29 return key; 30 } 31 } 32 } 33 } 34 catch (e) 35 { 36 } 37} 38 39/** 40 * Ermittelt das im Local Storage befindliche GIPS-Consent-JSON-Objekt mit den getroffenen Cookie-Einstellungen. 41 * 42 * @return das JSON-Objekt mit den getroffenen Cookie-Einstellungen. 43 */ 44function getLocalStorageObj() 45{ 46 try 47 { 48 if (localStorage && localStorage.length > 0) 49 { 50 // 51 // Special-Hack für alte Cookie-Banner: Aufgrund analoger Namensvergebung bei einigen 52 // alten Cookie-Bannern, müssen diese Einträge aus dem Storage entfernt werden. 53 // 54 localStorage.removeItem('GIPS-Consent'); 55 localStorage.removeItem('GIPS-Consent-Time'); 56 57 var jsonStr = localStorage.getItem(getLocalStorageObjKey()); 58 if (jsonStr) 59 { 60 return JSON.parse(jsonStr); 61 } 62 } 63 } 64 catch (e) 65 { 66 } 67 68 return null; 69} 70 71/** 72 * Entfernt alle abgelaufenen Consent-Banner-Einträge des Local Storage. 73 * 74 * @param parent Die ID des Parent-WPE 75 * @param days Tage, die die Einstellungen des Nutzers Gültigkeit haben 76 * @return {boolean} true, falls die Einstellungen des Nutzers noch gültig sind 77 */ 78function removeAllExpiredStorageEntries(days) 79{ 80 try 81 { 82 if (localStorage && localStorage.length > 0) 83 { 84 var i; 85 var l = localStorage.length; 86 for (i = 0; i < l; i++) 87 { 88 var key = localStorage.key(i); 89 if (key && (key.lastIndexOf('GIPS-Consent-', 0) === 0)) 90 { 91 var jsonStr = localStorage.getItem(key); 92 if (jsonStr) 93 { 94 var consentObj = JSON.parse(jsonStr); 95 if(isExpired(consentObj, days)) 96 { 97 localStorage.removeItem(key); 98 } 99 } 100 } 101 } 102 } 103 } 104 catch (e) 105 { 106 } 107} 108 109/** 110 * Expired-Steuerung für den Local Storage. 111 * 112 * @param storageObj Der zu prüfende LocalStorage-Eintrag 113 * @param days Tage, die die Einstellungen des Nutzers Gültigkeit haben 114 * @return {boolean} true, falls die Einstellungen des Nutzers noch gültig sind 115 */ 116function isExpired(storageObj, days) 117{ 118 var erg = false; 119 120 if (storageObj) 121 { 122 if (storageObj.Datum) 123 { 124 var now = new Date().getTime(); 125 126 if(now - storageObj.Datum > days * 24 * 60 * 60 * 1000) 127 { 128 erg = true; 129 } 130 } 131 else 132 { 133 erg = true; 134 } 135 } 136 else 137 { 138 erg = true; 139 } 140 141 return erg; 142} 143 144/** 145 * Prüft, ob der Nutzer die Consent-Einstellungen des Banners bereits gesehen hat. 146 * 147 * @param cookieVerfallsdatum Das Cookie-Verfallsdatum 148 * @return {boolean} true, falls der Nutzer den Banner bereits gesehen hat. 149 */ 150function showBanner(cookieVerfallsdatum) 151{ 152 // 153 // Local Storage aufräumen: Alle abgelaufenen Einträge entfernen. 154 // 155 removeAllExpiredStorageEntries(cookieVerfallsdatum); 156 157 // 158 // Wir halten im Local Storage nach dem "GIPS-Consent"-Eintrag Ausschau. 159 // 160 var i; 161 var l = localStorage.length; 162 for (i = 0; i < l; i++) 163 { 164 var key = localStorage.key(i); 165 166 if (key && (key.lastIndexOf('GIPS-Consent-', 0) === 0)) 167 { 168 return false; 169 } 170 } 171 172 return true; 173} 174 175/** 176 * Prüft, ob die DNT-Einstellungen ignoriert werden sollen. 177 * 178 * @param consentArten Array, bestehend aus den Art-IDs der zur Website gehörenden Consent-Items. 179 */ 180function isIgnoreDNT(consentArten) 181{ 182 if (consentArten) 183 { 184 var i; 185 var l = consentArten.length; 186 for (i = 0; i < l; i++) 187 { 188 var ignoreDNTElement = document.getElementById('trIgnoreDNT_' + consentArten[i]); 189 if (ignoreDNTElement && ignoreDNTElement.value == 'J') 190 { 191 return true; 192 } 193 } 194 } 195 196 return false; 197} 198 199/** 200 * Do-Not-Track-Einstellung aktiv: Hinweistext ausgeben + Tracking & Statistik blockieren 201 * 202 * @param parent Die ID des Parent-WPE 203 */ 204function handleDNT(parent) 205{ 206 // 207 // Kategorie Tracking 208 // 209 var consentBoxTracking = document.getElementById('ConsentCategory_' + parent + '_PGMHDL_Tracking'); 210 var consentBoxTrackingDescription = document.getElementById('ConsentCategory_' + parent + '_PGMHDL_Tracking_description'); 211 if (consentBoxTracking) 212 { 213 if (consentBoxTrackingDescription) 214 { 215 consentBoxTrackingDescription.innerHTML = '<acronym title="Die Do-Not-Track-Einstellungen Ihres Browsers sind aktiv. Um das Tracking zu erlauben, müssen diese zunächst deaktiviert und die Seite neu geladen werden.">Tracking</acronym>'; 216 } 217 consentBoxTracking.disabled = 'disabled'; 218 consentBoxTracking.checked = false; 219 consentBoxTracking.onclick = function(){return false;}; 220 } 221 222 // 223 // Kategorie Statistik 224 // 225 var consentBoxStatistik = document.getElementById('ConsentCategory_' + parent + '_PGMHDL_Statistik'); 226 var consentBoxStatistikDescription = document.getElementById('ConsentCategory_' + parent + '_PGMHDL_Statistik_description'); 227 if (consentBoxStatistik) 228 { 229 if (consentBoxStatistikDescription) 230 { 231 consentBoxStatistikDescription.innerHTML = '<acronym title="Die Do-Not-Track-Einstellungen Ihres Browsers sind aktiv. Um die Statistik zu erlauben, müssen diese zunächst deaktiviert und die Seite neu geladen werden.">Statistik</acronym>'; 232 } 233 consentBoxStatistik.disabled = 'disabled'; 234 consentBoxStatistik.checked = false; 235 consentBoxStatistik.onclick = function(){return false;}; 236 } 237} 238 239/** 240 * Initialisierung: Entsprechend den vom Nutzer getroffenen Consent-Einstellungen, werden die Checkboxen vorbefüllt. 241 * 242 * @param parent Die ID des Parent-WPE 243 * @param consentCategories Array, bestehend aus den Consent-Kategorien der zur Website gehörenden Consent-Items. 244 * @param consentPGMHDLs Array, bestehend aus den Consent-PGMHDLs der zur Website gehörenden Consent-Items. 245 */ 246function initCheckboxValues(parent, consentCategories, consentPGMHDLs) 247{ 248 // 249 // Welche Einstellungen hat der Nutzer aktuell gewählt? (Cookie auslesen) 250 // 251 var consentEinstellungen = HRGetCookie('HRCookieManager'); 252 if (consentEinstellungen) 253 { 254 var consentArray = consentEinstellungen.split('|'); 255 var i; 256 var l = consentArray.length; 257 for (i = 0; i < l; i++) 258 { 259 if (consentArray[i]) 260 { 261 var idxValue = consentArray[i].indexOf('-'); 262 if (idxValue >= 0) 263 { 264 var pgmhdl = consentArray[i].substring(0, idxValue).trim(); 265 var consentGiven = (consentArray[i].substring(idxValue + 1).trim() === 'J') ? true : false; 266 if (pgmhdl) 267 { 268 // Ermitteln der Checkbox 269 var j; 270 var l2 = consentPGMHDLs.length; 271 for (j = 0; j < l2; j++) 272 { 273 if (consentPGMHDLs[j] && consentPGMHDLs[j] === pgmhdl) 274 { 275 var checkbox = document.getElementById('ConsentCategory_' + parent + '_' + consentCategories[j]); 276 if (checkbox && consentGiven) 277 checkbox.checked = true; 278 279 break; 280 } 281 } 282 } 283 } 284 } 285 } 286 } 287} 288 289/** 290 * Einstellungen speichern: Die vom Nutzer getroffene Auswahl wird im Local Storage 291 * des Browsers (Schlüssel: "GIPS-Consent") und einem Cookie (Name: "HRCookieManager") gespeichert. 292 * 293 * @param parent Die ID des Parent-WPE 294 * @param acceptAll Alle Einstellungen akzeptieren. 295 * @param denyAll Alle nicht-notwendigen Cookies werden abgelehnt. 296 * @param consentCategoriesIds Array, bestehend aus den IDs der Consent-Kategorien der zur Website gehörenden Consent-Items. 297 * @param consentCategories Array, bestehend aus den Consent-Kategorien der zur Website gehörenden Consent-Items. 298 * @param consentArten Array, bestehend aus den Art-IDs der zur Website gehörenden Consent-Items. 299 * @param consentPGMHDLs Array, bestehend aus den Consent-PGMHDLs der zur Website gehörenden Consent-Items. 300 * @param cookieVerfallsdatum [optional] Das Verfallsdatum des zu setzenden Cookies mit den getroffenen Einstellungen. 301 * @param baseUrl Die Basis-Url. 302 * @param domainName Der Domain-Name 303 */ 304function saveConfig(parent, websiteId, acceptAll, denyAll, consentCategoriesIds, consentCategories, consentArten, consentPGMHDLs, domainName, cookieVerfallsdatum, baseUrl, removeCookies) 305{ 306 try 307 { 308 var checkboxes = document.querySelectorAll('*[id^=ConsentCategory_' + parent + '_]'); 309 if (checkboxes && checkboxes.length > 0) 310 { 311 var gipsConsent = '{"Kategorien" : {'; 312 313 // 314 // Abweichender Inhalt für das Cookie, um Performance zu optimieren und Größe zu reduzieren. 315 // 316 var gipsCookieConsent = ''; 317 318 var prefix = ''; 319 var prefixCookie = ''; 320 var i; 321 var l = checkboxes.length; 322 for (i = 0; i < l; i++) 323 { 324 var checkbox = checkboxes[i];
325 if (checkbox && checkbox.type === 'checkbox') 326 { 327 var category = checkbox.value; 328 if (category) 329 { 330 if (consentArten && consentPGMHDLs) 331 { 332 // Die ID der Kategorie ermitteln. 333 var j; 334 var consentArtenLength = consentArten.length; 335 var categoryId = 0; 336 for (j = 0; j < consentArtenLength; j++) 337 { 338 if (consentCategories[j] === category) 339 categoryId = consentCategoriesIds[j]; 340 } 341 342 gipsConsent += prefix + '"' + category + '" : {"id": ' + categoryId + ', "items": ['; 343 var prefix = ''; 344 for (j = 0; j < consentArtenLength; j++) 345 { 346 if (consentCategories[j] === category) 347 { 348 var consentItemAccepted = acceptAll || (checkbox.value && checkbox.checked); 349 350 // 351 // Ablehnen, wenn 352 // - DNT-Einstellung: Tracking auslassen oder 353 // - Alle-Ablehnen-Button: Alle Consent-Einstellungen außer den notwendigen. 354 // 355 if ((category === 'PGMHDL_Tracking' && HRBrowser.isDoNotTrackActive() && !isIgnoreDNT(consentArten)) 356 || (denyAll && category !== 'PGMHDL_Notwendige')) 357 consentItemAccepted = false; 358 359 gipsConsent += prefix + '{"id" : ' + consentArten[j] + ', "pgmhdl" : "' + consentPGMHDLs[j] + '", "consent" : ' + (consentItemAccepted ? 'true' : 'false') + '}'; 360 gipsCookieConsent += prefixCookie + consentPGMHDLs[j] + '-' + (consentItemAccepted ? 'J' : 'N'); 361 var prefix = ', '; 362 var prefixCookie = '|'; 363 } 364 } 365 gipsConsent += ']}'; 366 var prefix = ', '; 367 } 368 369 // Tracken der Entscheidung des Nutzers (natürlich ohne Nutzerdaten und ohne die Nutzung eines Cookies!). 370 if (baseUrl) 371 HRSendRequest(baseUrl + '&Anwendung=StatistikConsentBannerTracker&Methode=Init&WebsiteID=' + websiteId + '&ConsentCategoryID=' + categoryId + '&Akzeptiert=' + (consentItemAccepted ? 'J' : 'N'), null, null); 372 } 373 } 374 } 375 gipsConsent += '}, "Datum" : "' + Date.now() + '"}'; 376 377 if (removeCookies) 378 { 379 // Zur Sicherheit müssen alle relevanten Cookies zunächst entfernt werden. 380 HRRemoveAllCookies(domainName, '/'); 381 382 // Das Statistik-Cookie darf nur serverseitig gelöscht werden und wird daher per Ajax-Call entfernt. 383 if (baseUrl) 384 HRSendRequest(baseUrl + '&Anwendung=StatistikTracker&Methode=RemoveCookie', null, null); 385 } 386 localStorage.setItem('GIPS-Consent-' + parent, gipsConsent); 387 HRSetCookie('HRCookieManager', gipsCookieConsent, {expires: cookieVerfallsdatum, expiresUnit: 'days', domain: domainName, path: '/', secure: true}); 388 } 389 } 390 catch(e) 391 { 392 } 393} 394 395/** 396 * Prüft, ob das ausgewählte Tracking vom Nutzer akzeptiert wurde. 397 * 398 * @param itemArt Das Programhandle für die auszuwertende Consent-Item-Art. 399 * @param ignoreDNT true, falls die DNT-Einstellungen des Browsers missachtet werden sollen. 400 * @return true, falls der Nutzer die Art akzeptiert hat und false, wenn nicht. 401 */ 402function isTrackingActive(itemArt, ignoreDNT) 403{ 404 try 405 { 406 if (!ignoreDNT || !HRBrowser.isDoNotTrackActive()) 407 return isConsentGiven('PGMHDL_Tracking', itemArt); 408 } 409 catch (e) 410 { 411 } 412 413 return false; 414} 415 416/** 417 * Prüft, ob die Statistik vom Nutzer akzeptiert wurde. 418 * 419 * @param itemArt Die Art des Statistik-Consent-Items. 420 * @return true, falls der Nutzer die Art akzeptiert hat und false, wenn nicht. 421 */ 422function isStatistikActive(itemArt) 423{ 424 return isConsentGiven('PGMHDL_Statistik', itemArt); 425} 426 427/** 428 * Prüft, ob die Anzeige von externen Medien vom Nutzer akzeptiert wurde. 429 * 430 * @param itemArt Das Programhandle für die auszuwertende Consent-Item-Art. 431 * @return true, falls der Nutzer die Art akzeptiert hat und false, wenn nicht. 432 */ 433function isExternalMediaActive(itemArt) 434{ 435 return isConsentGiven('PGMHDL_ExterneMedien', itemArt); 436} 437 438/** 439 * Prüft, ob die übergebene Kategorie aktiviert wurde. Falls sogar genauer ein konkreter Consent-Eintrag 440 * angegeben wurde, wird dieser geprüft. Der letzte Fall ist aktuell freilich nicht sonderlich sinnvoll, 441 * da ein Akzeptieren einer Kategorie automatisch das Akzeptieren der darin untergeordneten Consent-Einträge 442 * zur Folge hat, aber vllt. werden wir später einmal einzelne Einträge getrennt aktivierbar machen. 443 * 444 * @param category Die zu prüfende Kategorie als Programhandle. 445 * @param itemArt [optional] Die zu prüfende Art des Consent-Items als Programhandle. 446 * @returns true, falls die Kategorie / der Eintrag der Kategorie aktiviert wurde. 447 */ 448function isConsentGiven(category, itemArt) 449{ 450 try 451 { 452 var item = null; 453 454 if (itemArt) 455 { 456 // Es wurde eine konkrete Itemart übergeben.
457 item = getConsentItem(itemArt, category); 458 } 459 else 460 { 461 // 462 // Es wurde keine konkrete Itemart übergeben. 463 // Prüfe also den ersten Eintrag, den wir finden. 464 // 465 var items = getConsentItems(category); 466 if (items && items.length > 0) 467 item = items[0]; 468 } 469 470 if (item) return (item.consent) ? true : false; 471 } 472 catch (e) 473 { 474 } 475 476 return false; 477} 478 479/** 480 * Setzt das Einverständnis einer Kategorie / eines einzelnen Consent-Eintrages oder entzieht es wieder. 481 * 482 * @param itemArt Der Consent-Eintrag. 483 * @param consent true, falls der Eintrag akzeptiert werden soll. 484 */ 485function updateConsentGiven(category, itemArt, consent) 486{ 487 try 488 { 489 if (category) 490 { 491 var consentObj = getLocalStorageObj(); 492 if (consentObj) 493 { 494 var categoryObj = consentObj.Kategorien[category]; 495 496 // 497 // Abwärtskompatibilität alte Version des localStorage-Eintrags. 498 // Die Kategorie wurde als ENUM-Feld unterhalb der Tabelle ConsentItemArt 499 // administriert. 500 // 501 if (!categoryObj) 502 categoryObj = consentObj.Kategorien[category.replace('PGMHDL_', '')]; 503 504 var items = categoryObj.items; 505 if (!items) 506 items = categoryObj; 507 508 var i; 509 var l = items.length; 510 for (i = 0; i < l; i++) 511 { 512 if (!itemArt || items[i].pgmhdl === itemArt) 513 { 514 items[i].consent = consent; 515 break; 516 } 517 } 518 519 localStorage.setItem(getLocalStorageObjKey(), JSON.stringify(consentObj)); 520 } 521 } 522 } 523 catch (e) 524 { 525 } 526} 527 528/** 529 * Getter für das Consent-Item zur übergeben Art und Kategorie. 530 * 531 * @param itemArt Die Art des gesuchten Consent-Items als Programhandle. 532 * @param category Die Kategorie als Programhandle. 533 * @returns das Consent-Item zur übergebenen Kategorie oder null, falls keine Items gefunden werden konnten. 534 */ 535function getConsentItem(itemArt, category) 536{ 537 var consentItem = null; 538 539 try 540 { 541 if (itemArt) 542 { 543 var items = getConsentItems(category); 544 if (items) 545 { 546 var i; 547 var l = items.length; 548 for (i = 0; i < l; i++) 549 { 550 if (items[i].pgmhdl === itemArt) 551 return items[i]; 552 } 553 } 554 } 555 } 556 catch (e) 557 { 558 } 559 560 return consentItem; 561} 562 563/** 564 * Getter für alle Consent-Items zur übergebenen Kategorie. 565 * 566 * @param category Die Kategorie als Programhandle. 567 * @returns alle Consent-Items zur übergebenen Kategorie oder null, falls keine Items gefunden werden konnten. 568 */ 569function getConsentItems(category) 570{ 571 var items = null; 572 573 try 574 { 575 if (category) 576 { 577 var consentObj = getLocalStorageObj(); 578 if (consentObj) 579 { 580 var categoryObj = consentObj.Kategorien[category]; 581 582 // 583 // Abwärtskompatibilität alte Version des localStorage-Eintrags. 584 // Die Kategorie wurde als ENUM-Feld unterhalb der Tabelle ConsentItemArt 585 // administriert. 586 // 587 if (!categoryObj) 588 categoryObj = consentObj.Kategorien[category.replace('PGMHDL_', '')]; 589 590 if (categoryObj) 591 { 592 items = categoryObj.items; 593 if (!items) items = categoryObj; // Abwärtskompatibilität alte Version des localStorage-Eintrags. 594 } 595 } 596 } 597 } 598 catch (e) 599 { 600 } 601 602 return items; 603} 604 605/** 606 * Schließt den Consent-Manager. 607 * 608 * @param ibox Die i-Box des Consent-Managers. 609 */ 610function closeConsentManager(ibox) 611{ 612 if (ibox != null) 613 { 614 ibox.close(); 615 } 616 617 var url = window.location.href; 618 619 /* 620 * Seite nachladen und den Referrer nochmal mit übergeben, da die
620ser beim Reload 621 * für die Trackingaufrufe verloren wäre. 622 */ 623 if (document.referrer) 624 { 625 // 626 // Für die gepublishten Seiten lesen wir den Referrer aus dem LocalStorage aus. 627 // 628 if (localStorage) 629 localStorage.setItem('ConsentReferrer', document.referrer); 630 631 // 632 // Für DB-Links lesen wir den Referrer per Parameter aus. 633 // 634 if (url.indexOf('ConsentReferrer=') < 0) 635 { 636 url += (url.indexOf('?') >= 0 ? '&' : '?'); 637 url += 'ConsentReferrer='; 638 url += encodeURIComponent(document.referrer); 639 } 640 } 641 642 window.location.href = url; 643 644 // 645 // Der Welt mitteilen, dass der Nutzer seine Auswahl getroffen hat. 646 // 647 if (HREventManager && typeof(HREventManager.dispatchEvent) === 'function') 648 HREventManager.dispatchEvent(window, HREventNames.consentManagerClosed, {notifyChildren: true, bubbles: true, useStandard: false}); 649}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.