hr-design-system-handlebars 1.114.89 → 1.114.91

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ # v1.114.91 (Thu Feb 13 2025)
2
+
3
+ #### 🐛 Bug Fix
4
+
5
+ - Dpe 3535 js protection v2 [#1240](https://github.com/mumprod/hr-design-system-handlebars/pull/1240) ([@vascoeduardo](https://github.com/vascoeduardo) [@eduardo-hr](https://github.com/eduardo-hr))
6
+
7
+ #### Authors: 2
8
+
9
+ - [@eduardo-hr](https://github.com/eduardo-hr)
10
+ - Vasco ([@vascoeduardo](https://github.com/vascoeduardo))
11
+
12
+ ---
13
+
14
+ # v1.114.90 (Thu Feb 13 2025)
15
+
16
+ #### 🐛 Bug Fix
17
+
18
+ - Add spam protection feature to contact form [#1239](https://github.com/mumprod/hr-design-system-handlebars/pull/1239) ([@vascoeduardo](https://github.com/vascoeduardo) [@eduardo-hr](https://github.com/eduardo-hr))
19
+
20
+ #### Authors: 2
21
+
22
+ - [@eduardo-hr](https://github.com/eduardo-hr)
23
+ - Vasco ([@vascoeduardo](https://github.com/vascoeduardo))
24
+
25
+ ---
26
+
1
27
  # v1.114.89 (Thu Feb 13 2025)
2
28
 
3
29
  #### 🐛 Bug Fix
@@ -2503,6 +2503,9 @@ article #commentList {
2503
2503
  .border-l-2 {
2504
2504
  border-left-width: 2px;
2505
2505
  }
2506
+ .border-l-4 {
2507
+ border-left-width: 4px;
2508
+ }
2506
2509
  .border-l-\[3px\] {
2507
2510
  border-left-width: 3px;
2508
2511
  }
@@ -2616,6 +2619,11 @@ article #commentList {
2616
2619
  border-color: #fff;
2617
2620
  border-color: var(--color-navigation-border-color);
2618
2621
  }
2622
+ .border-orange-500 {
2623
+ --tw-border-opacity: 1;
2624
+ border-color: rgba(249, 115, 22, 1);
2625
+ border-color: rgba(249, 115, 22, var(--tw-border-opacity));
2626
+ }
2619
2627
  .border-primary {
2620
2628
  border-color: #005293;
2621
2629
  border-color: var(--color-primary-ds);
@@ -2814,6 +2822,11 @@ article #commentList {
2814
2822
  background-color: rgba(229, 229, 229, 1);
2815
2823
  background-color: rgba(229, 229, 229, var(--tw-bg-opacity));
2816
2824
  }
2825
+ .bg-orange-100 {
2826
+ --tw-bg-opacity: 1;
2827
+ background-color: rgba(255, 237, 213, 1);
2828
+ background-color: rgba(255, 237, 213, var(--tw-bg-opacity));
2829
+ }
2817
2830
  .bg-orange-500 {
2818
2831
  --tw-bg-opacity: 1;
2819
2832
  background-color: rgba(249, 115, 22, 1);
@@ -3524,6 +3537,11 @@ article #commentList {
3524
3537
  color: #000000;
3525
3538
  color: var(--color-navigation-text);
3526
3539
  }
3540
+ .text-orange-700 {
3541
+ --tw-text-opacity: 1;
3542
+ color: rgba(194, 65, 12, 1);
3543
+ color: rgba(194, 65, 12, var(--tw-text-opacity));
3544
+ }
3527
3545
  .text-orange-spicyCarrot-hex {
3528
3546
  --tw-text-opacity: 1;
3529
3547
  color: rgba(211, 70, 0, 1);
@@ -3828,7 +3846,7 @@ article #commentList {
3828
3846
  border-bottom-color: var(--color-secondary-ds);
3829
3847
  }
3830
3848
  .counter-reset {
3831
- counter-reset: cnt1739469830196;
3849
+ counter-reset: cnt1739486962195;
3832
3850
  }
3833
3851
  .animate-delay-100 {
3834
3852
  --tw-animate-delay: 100ms;
@@ -4273,7 +4291,7 @@ html { scroll-behavior: smooth; }
4273
4291
  --tw-ring-color: rgba(255, 255, 255, 0.5);
4274
4292
  }
4275
4293
  .-ordered {
4276
- counter-increment: cnt1739469830196 1;
4294
+ counter-increment: cnt1739486962195 1;
4277
4295
  }
4278
4296
  .-ordered::before {
4279
4297
  position: absolute;
@@ -4291,7 +4309,7 @@ html { scroll-behavior: smooth; }
4291
4309
  --tw-text-opacity: 1;
4292
4310
  color: rgba(0, 0, 0, 1);
4293
4311
  color: rgba(0, 0, 0, var(--tw-text-opacity));
4294
- content: counter(cnt1739469830196);
4312
+ content: counter(cnt1739486962195);
4295
4313
  }
4296
4314
  /*! ****************************/
4297
4315
  /*! DataPolicy stuff */
@@ -1,6 +1,6 @@
1
1
  import { uxAction } from 'base/tracking/pianoHelper.subfeature'
2
2
 
3
- export default function contactForm(formId, jsonUrl, errorMessages, multipart, trackingInformations, jsonp = false) {
3
+ export default function contactForm(formId, jsonUrl, errorMessages, multipart, trackingInformations, hasSpamProtection, jsonp = false) {
4
4
  return {
5
5
  isPosting: false,
6
6
  wasPosted: false,
@@ -12,15 +12,29 @@ export default function contactForm(formId, jsonUrl, errorMessages, multipart, t
12
12
  formWrapper: this.$refs[formId].closest("#formWrapper"),
13
13
  honeypot: this.$refs[formId].querySelector('input[data-name="x-message"]'),
14
14
  actionUrl: this.form && this.form.getAttribute('action'),
15
+ interacted: true,
16
+
15
17
  checkForJsonURL () {
16
18
  if (jsonUrl) {
17
19
  this.actionUrl = jsonUrl
18
20
  }
19
21
  },
20
22
  formInit(){
23
+
21
24
  this.checkForJsonURL()
22
25
  this.$store.forms.submissionAttempted[formId] = false;
23
26
  this.$store.forms.errorMessages = JSON.parse(errorMessages.replace(/"/g,'"'))
27
+ console.log('hasSpamProtection:', hasSpamProtection);
28
+ if(hasSpamProtection){
29
+ console.log('Spam Protection');
30
+ this.initSpamProtection();
31
+ }
32
+
33
+ },
34
+ initSpamProtection(){
35
+ this.interacted = false;
36
+ addEventListener('mousemove', () => this.interacted = true );
37
+ addEventListener('keypress', () => this.interacted = true );
24
38
  },
25
39
  scrollToElementAndCenterWithTimeout(element, timeout){
26
40
  setTimeout(() => {
@@ -35,8 +49,8 @@ export default function contactForm(formId, jsonUrl, errorMessages, multipart, t
35
49
  if (this.honeypot) {
36
50
  this.honeypot.removeAttribute('required');
37
51
  }
38
- if(this.form.reportValidity()){
39
- this.handleSubmit(event,this.form)
52
+ if(this.form.reportValidity() && this.interacted){
53
+ this.handleSubmit(event,this.form)
40
54
  } else {
41
55
  this.scrollToElementAndCenterWithTimeout(document.activeElement, 50)
42
56
  if (this.honeypot) {
@@ -95,7 +109,7 @@ export default function contactForm(formId, jsonUrl, errorMessages, multipart, t
95
109
  } else {
96
110
  ajaxOptions.url = `${this.actionUrl}?${responseFormatParam}`;
97
111
  }
98
-
112
+ console.log('ajaxOptions:', ajaxOptions);
99
113
  fetch(ajaxOptions.url, ajaxOptions)
100
114
  .then(async (response) => {
101
115
  const data = await response.text();
@@ -7,14 +7,14 @@
7
7
  <form
8
8
  x-ref="form{{nextRandom}}"
9
9
  ax-load
10
- x-data="contactForm('form{{getRandom}}','{{this.jsonUrl}}','{{this.errorMessages}}','{{this.isMultipart}}','{{this.trackingInformations}}')"
10
+ x-data="contactForm('form{{getRandom}}','{{this.jsonUrl}}','{{this.errorMessages}}','{{this.isMultipart}}','{{this.trackingInformations}}','{{this.hasSpamProtection}}')"
11
11
  x-init="formInit()"
12
12
  x-ignore
13
13
 
14
14
  @submit.prevent
15
15
  id="form{{getRandom}}"
16
16
  class="relative flex flex-col justify-center overflow-hidden group"
17
- action="{{this.url}}"
17
+ action="{{if this.hasSpamProtection '#' this.url}}"
18
18
  method="post"
19
19
  enctype="{{if this.isMultipart 'multipart/form-data' 'application/x-www-form-urlencoded'}}"
20
20
  accept-charset="utf-8"
@@ -29,8 +29,16 @@
29
29
  x-transition:leave-end="opacity-0 transform scale-90"
30
30
  >
31
31
  {{> components/forms/components/fields _formId=(joinStrings 'form' (getRandom)) }}
32
-
33
- {{> components/forms/components/controls }}
32
+ {{#if this.hasSpamProtection }}
33
+ <noscript>
34
+ <div class="p-4 mb-3 text-orange-700 bg-orange-100 border-l-4 border-orange-500" role="alert">
35
+ <p class="font-bold">Hinweis</p>
36
+ <p>Bitte Aktivieren Sie JavaScript um dieses Formular Absenden zu können.</p>
37
+ </div>
38
+ </noscript>
39
+ {{/if}}
40
+ {{> components/forms/components/controls }}
41
+
34
42
  </div>
35
43
  <div class="flex flex-col gap-6 md:gap-10" id="successMessage" x-show="wasPostedWithSuccess"
36
44
  x-transition:enter="transition ease-out duration-300 delay-75"
@@ -7,14 +7,14 @@
7
7
  <form
8
8
  x-ref="form{{nextRandom}}"
9
9
  ax-load
10
- x-data="contactForm('form{{getRandom}}','{{this.jsonUrl}}','{{this.errorMessages}}','{{this.isMultipart}}','{{this.trackingInformations}}')"
10
+ x-data="contactForm('form{{getRandom}}','{{this.jsonUrl}}','{{this.errorMessages}}','{{this.isMultipart}}','{{this.trackingInformations}}','{{this.hasSpamProtection}}')"
11
11
  x-init="formInit()"
12
12
  x-ignore
13
13
 
14
14
  @submit.prevent
15
15
  id="form{{getRandom}}"
16
16
  class="relative flex flex-col justify-center overflow-hidden group"
17
- action="{{this.url}}"
17
+ action="{{if this.hasSpamProtection '#' this.url}}"
18
18
  method="post"
19
19
  enctype="{{if this.isMultipart 'multipart/form-data' 'application/x-www-form-urlencoded'}}"
20
20
  accept-charset="utf-8"
@@ -29,8 +29,16 @@
29
29
  x-transition:leave-end="opacity-0 transform scale-90"
30
30
  >
31
31
  {{> components/forms/components/fields _formId=(joinStrings 'form' (getRandom)) }}
32
-
33
- {{> components/forms/components/controls }}
32
+ {{#if this.hasSpamProtection }}
33
+ <noscript>
34
+ <div class="p-4 mb-3 text-orange-700 bg-orange-100 border-l-4 border-orange-500" role="alert">
35
+ <p class="font-bold">Hinweis</p>
36
+ <p>Bitte Aktivieren Sie JavaScript um dieses Formular Absenden zu können.</p>
37
+ </div>
38
+ </noscript>
39
+ {{/if}}
40
+ {{> components/forms/components/controls }}
41
+
34
42
  </div>
35
43
  <div class="flex flex-col gap-6 md:gap-10" id="successMessage" x-show="wasPostedWithSuccess"
36
44
  x-transition:enter="transition ease-out duration-300 delay-75"
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "license": "MIT",
7
7
  "main": "dist/index.js",
8
8
  "repository": "https://github.com/szuelch/hr-design-system-handlebars",
9
- "version": "1.114.89",
9
+ "version": "1.114.91",
10
10
  "scripts": {
11
11
  "test": "echo \"Error: no test specified\" && exit 1",
12
12
  "storybook": "storybook dev -p 6006 public",
@@ -14,6 +14,8 @@
14
14
  "richtext":"Liebe Nutzerin, lieber Nutzer,<br><br>ich werde mich so schnell wie möglich um Ihr Anliegen kümmern. Hier geht's zur <a class='' href='https://www.hessenschau.de/index.html'>hessenschau.de-Startseite</a> mit aktuellen Nachrichten aus Hessen.<br><br>Viele Grüße, <br><br>Karsten Hufer"
15
15
  },
16
16
  "jsonUrl": "https://ugc-hessenschau.dev-ext.hrcms.gcp.cloud.hr.de",
17
+ "url": "https://ugc-hessenschau.dev-ext.hrcms.gcp.cloud.hr.de/action",
18
+ "hasSpamProtection": true,
17
19
  "errorMessages":
18
20
  {
19
21
  "@->jsoninclude": "forms/error_messages.inc.json",
@@ -1 +1 @@
1
- {"copytextParagraph":[{"isHeadline":true,"text":"Copytext mit Formular"},{"paragraphBoxItem":{"isWebForm":true,"hasNewWebForm":true,"title":"Kontaktformular","successText":{"richtext":"Liebe Nutzerin, lieber Nutzer,<br><br>ich werde mich so schnell wie möglich um Ihr Anliegen kümmern. Hier geht's zur <a class='' href='https://www.hessenschau.de/index.html'>hessenschau.de-Startseite</a> mit aktuellen Nachrichten aus Hessen.<br><br>Viele Grüße, <br><br>Karsten Hufer"},"jsonUrl":"https://ugc-hessenschau.dev-ext.hrcms.gcp.cloud.hr.de","errorMessages":"{&quot;form_error_required&quot;:&quot;Server: Pflichtfeld&quot;,&quot;form_error_max&quot;:&quot;Server: Zu viele Zeichen&quot;,&quot;form_error_validurl&quot;:&quot;Server: Ungültige URL&quot;,&quot;form_error_empty&quot;:&quot;Server: Darf nicht ausgefüllt werden&quot;,&quot;form_error_constants_or_null&quot;:&quot;Server: Ungültiger Wert&quot;,&quot;form_error_constants&quot;:&quot;Server: Ungültiger Wert&quot;,&quot;form_error_max_multivalue&quot;:&quot;Server: Die maximale Anzahl an Antwortmöglichkeiten wurde überschritten&quot;,&quot;vote_error_identity_already_used&quot;:&quot;Server: Unter dieser E-Mail-Adresse wurde bereits abgestimmt. Eine weitere Abstimmung ist nicht möglich.&quot;,&quot;vote_error_token_request_count_exceeded&quot;:&quot;Server: Die maximale Anzahl an Bestätigungs-E-Mails wurde bereits verschickt.&quot;,&quot;form_error_email&quot;:&quot;Server: Ungültige E-Mail-Adresse&quot;}","isMultipart":"isMultipart","trackingInformations":"trackingInformations","fields":[{"type":{"isText":true,"asString":"text"},"name":"vorname","label":"Vorname","description":"Das ist der Beschreibungstext von Vorname","defaultValue":"","isHidden":false,"isRequired":false},{"type":{"isText":true,"asString":"text"},"name":"message","label":"message","description":"message","defaultValue":"","isHidden":true,"hasSpamProtection":true,"isRequired":false,"maxLength":"140"}]}}]}
1
+ {"copytextParagraph":[{"isHeadline":true,"text":"Copytext mit Formular"},{"paragraphBoxItem":{"isWebForm":true,"hasNewWebForm":true,"title":"Kontaktformular","successText":{"richtext":"Liebe Nutzerin, lieber Nutzer,<br><br>ich werde mich so schnell wie möglich um Ihr Anliegen kümmern. Hier geht's zur <a class='' href='https://www.hessenschau.de/index.html'>hessenschau.de-Startseite</a> mit aktuellen Nachrichten aus Hessen.<br><br>Viele Grüße, <br><br>Karsten Hufer"},"jsonUrl":"https://ugc-hessenschau.dev-ext.hrcms.gcp.cloud.hr.de","url":"https://ugc-hessenschau.dev-ext.hrcms.gcp.cloud.hr.de/action","hasSpamProtection":true,"errorMessages":"{&quot;form_error_required&quot;:&quot;Server: Pflichtfeld&quot;,&quot;form_error_max&quot;:&quot;Server: Zu viele Zeichen&quot;,&quot;form_error_validurl&quot;:&quot;Server: Ungültige URL&quot;,&quot;form_error_empty&quot;:&quot;Server: Darf nicht ausgefüllt werden&quot;,&quot;form_error_constants_or_null&quot;:&quot;Server: Ungültiger Wert&quot;,&quot;form_error_constants&quot;:&quot;Server: Ungültiger Wert&quot;,&quot;form_error_max_multivalue&quot;:&quot;Server: Die maximale Anzahl an Antwortmöglichkeiten wurde überschritten&quot;,&quot;vote_error_identity_already_used&quot;:&quot;Server: Unter dieser E-Mail-Adresse wurde bereits abgestimmt. Eine weitere Abstimmung ist nicht möglich.&quot;,&quot;vote_error_token_request_count_exceeded&quot;:&quot;Server: Die maximale Anzahl an Bestätigungs-E-Mails wurde bereits verschickt.&quot;,&quot;form_error_email&quot;:&quot;Server: Ungültige E-Mail-Adresse&quot;}","isMultipart":"isMultipart","trackingInformations":"trackingInformations","fields":[{"type":{"isText":true,"asString":"text"},"name":"vorname","label":"Vorname","description":"Das ist der Beschreibungstext von Vorname","defaultValue":"","isHidden":false,"isRequired":false},{"type":{"isText":true,"asString":"text"},"name":"message","label":"message","description":"message","defaultValue":"","isHidden":true,"hasSpamProtection":true,"isRequired":false,"maxLength":"140"}]}}]}
@@ -1,6 +1,6 @@
1
1
  import { uxAction } from 'base/tracking/pianoHelper.subfeature'
2
2
 
3
- export default function contactForm(formId, jsonUrl, errorMessages, multipart, trackingInformations, jsonp = false) {
3
+ export default function contactForm(formId, jsonUrl, errorMessages, multipart, trackingInformations, hasSpamProtection, jsonp = false) {
4
4
  return {
5
5
  isPosting: false,
6
6
  wasPosted: false,
@@ -12,15 +12,29 @@ export default function contactForm(formId, jsonUrl, errorMessages, multipart, t
12
12
  formWrapper: this.$refs[formId].closest("#formWrapper"),
13
13
  honeypot: this.$refs[formId].querySelector('input[data-name="x-message"]'),
14
14
  actionUrl: this.form && this.form.getAttribute('action'),
15
+ interacted: true,
16
+
15
17
  checkForJsonURL () {
16
18
  if (jsonUrl) {
17
19
  this.actionUrl = jsonUrl
18
20
  }
19
21
  },
20
22
  formInit(){
23
+
21
24
  this.checkForJsonURL()
22
25
  this.$store.forms.submissionAttempted[formId] = false;
23
26
  this.$store.forms.errorMessages = JSON.parse(errorMessages.replace(/&quot;/g,'"'))
27
+ console.log('hasSpamProtection:', hasSpamProtection);
28
+ if(hasSpamProtection){
29
+ console.log('Spam Protection');
30
+ this.initSpamProtection();
31
+ }
32
+
33
+ },
34
+ initSpamProtection(){
35
+ this.interacted = false;
36
+ addEventListener('mousemove', () => this.interacted = true );
37
+ addEventListener('keypress', () => this.interacted = true );
24
38
  },
25
39
  scrollToElementAndCenterWithTimeout(element, timeout){
26
40
  setTimeout(() => {
@@ -35,8 +49,8 @@ export default function contactForm(formId, jsonUrl, errorMessages, multipart, t
35
49
  if (this.honeypot) {
36
50
  this.honeypot.removeAttribute('required');
37
51
  }
38
- if(this.form.reportValidity()){
39
- this.handleSubmit(event,this.form)
52
+ if(this.form.reportValidity() && this.interacted){
53
+ this.handleSubmit(event,this.form)
40
54
  } else {
41
55
  this.scrollToElementAndCenterWithTimeout(document.activeElement, 50)
42
56
  if (this.honeypot) {
@@ -95,7 +109,7 @@ export default function contactForm(formId, jsonUrl, errorMessages, multipart, t
95
109
  } else {
96
110
  ajaxOptions.url = `${this.actionUrl}?${responseFormatParam}`;
97
111
  }
98
-
112
+ console.log('ajaxOptions:', ajaxOptions);
99
113
  fetch(ajaxOptions.url, ajaxOptions)
100
114
  .then(async (response) => {
101
115
  const data = await response.text();
@@ -7,14 +7,14 @@
7
7
  <form
8
8
  x-ref="form{{nextRandom}}"
9
9
  ax-load
10
- x-data="contactForm('form{{getRandom}}','{{this.jsonUrl}}','{{this.errorMessages}}','{{this.isMultipart}}','{{this.trackingInformations}}')"
10
+ x-data="contactForm('form{{getRandom}}','{{this.jsonUrl}}','{{this.errorMessages}}','{{this.isMultipart}}','{{this.trackingInformations}}','{{this.hasSpamProtection}}')"
11
11
  x-init="formInit()"
12
12
  x-ignore
13
13
 
14
14
  @submit.prevent
15
15
  id="form{{getRandom}}"
16
16
  class="relative flex flex-col justify-center overflow-hidden group"
17
- action="{{this.url}}"
17
+ action="{{if this.hasSpamProtection '#' this.url}}"
18
18
  method="post"
19
19
  enctype="{{if this.isMultipart 'multipart/form-data' 'application/x-www-form-urlencoded'}}"
20
20
  accept-charset="utf-8"
@@ -29,8 +29,16 @@
29
29
  x-transition:leave-end="opacity-0 transform scale-90"
30
30
  >
31
31
  {{> components/forms/components/fields _formId=(joinStrings 'form' (getRandom)) }}
32
-
33
- {{> components/forms/components/controls }}
32
+ {{#if this.hasSpamProtection }}
33
+ <noscript>
34
+ <div class="p-4 mb-3 text-orange-700 bg-orange-100 border-l-4 border-orange-500" role="alert">
35
+ <p class="font-bold">Hinweis</p>
36
+ <p>Bitte Aktivieren Sie JavaScript um dieses Formular Absenden zu können.</p>
37
+ </div>
38
+ </noscript>
39
+ {{/if}}
40
+ {{> components/forms/components/controls }}
41
+
34
42
  </div>
35
43
  <div class="flex flex-col gap-6 md:gap-10" id="successMessage" x-show="wasPostedWithSuccess"
36
44
  x-transition:enter="transition ease-out duration-300 delay-75"