From 436be5830b575d7276f0e2562adb0b0882f798f7 Mon Sep 17 00:00:00 2001 From: muli Date: Sun, 29 May 2022 12:38:48 +0200 Subject: [PATCH 01/20] feat: Added dev server to project file. --- wtf-eg.lektorproject | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wtf-eg.lektorproject b/wtf-eg.lektorproject index dce195e..2d9c6fe 100644 --- a/wtf-eg.lektorproject +++ b/wtf-eg.lektorproject @@ -13,6 +13,15 @@ default = yes locale = de_DE target = rsync://wtf@www.wtf-eg.net:/srv/www/www.wtf-eg.de/ +[servers.dev] +name = dev +url = https://spielwiese.wtf-eg.de/ +url_style = absolute +enabled = yes +default = yes +locale = de_DE +target = rsync://wtf@www.wtf-eg.net:/srv/www/spielwiese.wtf-eg.de/ + [alternatives.de] name = Deutsch primary = true From aeb1ae24fa535ac0f79b37684b2e09fb06b5f6b6 Mon Sep 17 00:00:00 2001 From: muli Date: Thu, 16 Jun 2022 13:02:42 +0200 Subject: [PATCH 02/20] =?UTF-8?q?feat:=20WIP=20Kontaktformular=20hinzugef?= =?UTF-8?q?=C3=BCgt.=20(#105)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die URL ist noch hardcoded. Rückmeldung für den User fehlt noch. Die Nachricht geht noch nirgends hin. Spamprotection ohne Captcha ist nur in Ansätzen zu erkennen. --- assets/css/style.css | 37 +++++++++++++++ assets/js/contact_form.js | 31 +++++++++++++ assets/js/contact_form_toggle.js | 5 +++ assets/php/contact_form.php | 77 ++++++++++++++++++++++++++++++++ content/kontakt/contents.lr | 2 +- models/contact_page.ini | 4 ++ templates/contact_page.html | 51 +++++++++++++++++++++ templates/layout.html | 6 +++ 8 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 assets/js/contact_form.js create mode 100644 assets/js/contact_form_toggle.js create mode 100644 assets/php/contact_form.php create mode 100644 models/contact_page.ini create mode 100644 templates/contact_page.html diff --git a/assets/css/style.css b/assets/css/style.css index 3104edf..2a6d907 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -31,6 +31,9 @@ --wtf-light-grey: #edefeb; --wtf-lila: #6600ff; + /* misc colors */ + --dark-red: #dc0000; + --column-count: 3; } @@ -882,6 +885,40 @@ hr.-even { flex-direction: column; justify-content: flex-start; } + +.contact_form--required { + color: var(--dark-red) +} + +.content__contact_form { + +} + +.contact_form__textarea, +.contact_form__text_input, +.contact_form__captcha { + display: flex; + flex-direction: column; +} + +.contact_form__message { + height: 12em; +} + +.contact_form__message, +.contact_form__name, +.contact_form__email, +.contact_form__captcha { + font-family: 'Lato', sans-serif; + line-height: 1.3rem; + font-size: 1rem; +} + +/* Hide captcha field as part of spam protection. + We got no real captcha. */ +.contact_form__captcha { + display: none; +} /* main - Ende */ /* footer - Start */ diff --git a/assets/js/contact_form.js b/assets/js/contact_form.js new file mode 100644 index 0000000..2197618 --- /dev/null +++ b/assets/js/contact_form.js @@ -0,0 +1,31 @@ +const ajaxUrl = 'https://spielwiese.wtf-eg.de/php/contact_form.php'; +// const submit_button = document.getElementsByClassName('contact_form__submit_button')[0]; +const contact_form = document.getElementsByClassName('content__contact_form')[0]; +const message = document.getElementsByClassName('contact_form__message')[0]; +const name = document.getElementsByClassName('contact_form__name')[0]; +const email = document.getElementsByClassName('contact_form__email')[0]; +const captcha = document.getElementsByClassName('contact_form__captcha')[0]; + +contact_form.addEventListener('submit', function(event) { + event.preventDefault(); + let formData = new FormData(); + formData.append('message', message.value); + formData.append('name', name.value); + formData.append('email', email.value); + + // If some bot entered some value, return. + if (typeof captcha.value == 'undefined') { + formData.append('captcha', 'Nudelsuppe'); + } else { + console.log('bot detected'); + return; + } + + fetch(ajaxUrl, { + method: 'POST', + mode:'same-origin', + body: formData, + }) + .then(response => response.json()) + .then(json => {console.log(json)}); +}, false); diff --git a/assets/js/contact_form_toggle.js b/assets/js/contact_form_toggle.js new file mode 100644 index 0000000..b2dce0c --- /dev/null +++ b/assets/js/contact_form_toggle.js @@ -0,0 +1,5 @@ +/* Unhide contact form if JS is enabled */ +window.addEventListener('DOMContentLoaded', (event) => { + const contact_form_wrapper = document.getElementsByClassName('content__contact_form_wrapper')[0]; + contact_form_wrapper.style.setProperty('display', 'block'); +}); diff --git a/assets/php/contact_form.php b/assets/php/contact_form.php new file mode 100644 index 0000000..9f2d077 --- /dev/null +++ b/assets/php/contact_form.php @@ -0,0 +1,77 @@ + json_last_error_msg()]); + if ($json === false) { + // This should not happen, but … + $json = '{"jsonError":"unknown"}'; + } + // Set HTTP response status code to: 500 - Internal Server Error + http_response_code(500); + } + header('Content-type: application/json'); + echo $json; +} + +if ($_SERVER["REQUEST_METHOD"] == "POST") { + $response = array(); + + if ( + empty($_POST['message']) || + empty($_POST['email']) || + empty($_POST['name']) || + $_POST['captcha'] != 'Nudelsuppe' + ) { + if (empty($_POST['message'])) { + $response['errors'][] = 'Du hast keine Nachricht eingegeben.'; + } + if (empty($_POST['email'])) { + $response['errors'][] = 'Du hast keine E-Mail-Adresse eingegeben.'; + } + if (empty($_POST['name'])) { + $response['errors'][] = 'Du hast keinen Namen eingegeben.'; + } + if ($_POST['captcha'] != 'Nudelsuppe') { + $response['errors'][] = 'Wir glauben du bist ein Bot.'; + } + } else { + $message = sanitize_text('message'); + $name = sanitize_text('name'); + $email = sanitize_text('email'); + + if (!send_message_to_office($message, $name, $email)) { + $response['errors'][] = 'Deine Nachricht konnte nicht übermittelt werden.'; + } else { + $response['status'] = 'ok'; + } + } + send_response($response); +} else { + http_response_code(404); +} diff --git a/content/kontakt/contents.lr b/content/kontakt/contents.lr index 149dd42..9094eac 100644 --- a/content/kontakt/contents.lr +++ b/content/kontakt/contents.lr @@ -1,4 +1,4 @@ -_model: page +_model: contact_page --- title: Kontakt --- diff --git a/models/contact_page.ini b/models/contact_page.ini new file mode 100644 index 0000000..1ad4298 --- /dev/null +++ b/models/contact_page.ini @@ -0,0 +1,4 @@ +[model] +name = Contact Page +label = {{ this.title }} +inherits = page diff --git a/templates/contact_page.html b/templates/contact_page.html new file mode 100644 index 0000000..626c961 --- /dev/null +++ b/templates/contact_page.html @@ -0,0 +1,51 @@ +{% extends "header_slim.html" %} +{%- block title -%}{{ this.title }}{%- endblock -%} +{%- block meta_description -%} + {%- if this.meta_description is defined and this.meta_description != "" -%} + {{ this.meta_description }} + {%- else -%} + Werkkooperative der Technikfreundinnen eG + {%- endif -%} +{%- endblock -%} +{% block body %} +
+
+

{{ this.title }}

+
+
+
+
+
+ {{ this.body }} +
+ +
+
+{% endblock %} \ No newline at end of file diff --git a/templates/layout.html b/templates/layout.html index 6b8ead4..79dd07c 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -63,6 +63,9 @@ __ ____________________ {% if 'manifest.json'|asseturl is defined -%} {%- endif %} + {% if '/js/contact_form_toggle.js'|asseturl is defined -%} + + {%- endif %}
@@ -128,4 +131,7 @@ __ ____________________ {%- if '/js/nav_toggle.js'|asseturl is defined -%} {%- endif %} + {% if '/js/contact_form_toggle.js'|asseturl is defined -%} + + {%- endif %} From bbc1bc2b614ea1bc11620b6f7ed69b4072bd22e8 Mon Sep 17 00:00:00 2001 From: muli Date: Thu, 16 Jun 2022 13:03:02 +0200 Subject: [PATCH 03/20] chore: Updated .gitignore. --- .gitignore | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 503e096..b9e885a 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ temp/ .DS_Store .AppleDouble .LSOverride +.nova # Icon must end with two \r Icon @@ -86,8 +87,12 @@ $RECYCLE.BIN/ # Windows shortcuts *.lnk -# Python virtual enviroment -env +### Python ### +# Compiled python +*.pyc + +# Virtaul environments .env -venv .venv +env +venv From 83d4694190b48821c5367314a5440a9a83dd605d Mon Sep 17 00:00:00 2001 From: muli Date: Thu, 16 Jun 2022 13:03:29 +0200 Subject: [PATCH 04/20] fix: Fixed Syntax in manifest.json. --- assets/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/manifest.json b/assets/manifest.json index 844121f..7f70b54 100644 --- a/assets/manifest.json +++ b/assets/manifest.json @@ -6,6 +6,6 @@ "sizes": "96x96", "type": "image\/png", "density": "2.0" - }, + } ] } \ No newline at end of file From 5a089b6a2ad030cc2c51b9cfe0f9de45d75ad918 Mon Sep 17 00:00:00 2001 From: muli Date: Thu, 16 Jun 2022 16:41:24 +0200 Subject: [PATCH 05/20] feat: Bot-Detection erweitert. (#105) --- assets/js/contact_form.js | 2 ++ assets/php/contact_form.php | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/assets/js/contact_form.js b/assets/js/contact_form.js index 2197618..9f90099 100644 --- a/assets/js/contact_form.js +++ b/assets/js/contact_form.js @@ -5,6 +5,7 @@ const message = document.getElementsByClassName('contact_form__message')[0]; const name = document.getElementsByClassName('contact_form__name')[0]; const email = document.getElementsByClassName('contact_form__email')[0]; const captcha = document.getElementsByClassName('contact_form__captcha')[0]; +const now = (new Date().getTime/1000).toFixed(); contact_form.addEventListener('submit', function(event) { event.preventDefault(); @@ -12,6 +13,7 @@ contact_form.addEventListener('submit', function(event) { formData.append('message', message.value); formData.append('name', name.value); formData.append('email', email.value); + formData.append('time_sent', now); // If some bot entered some value, return. if (typeof captcha.value == 'undefined') { diff --git a/assets/php/contact_form.php b/assets/php/contact_form.php index 9f2d077..ece2992 100644 --- a/assets/php/contact_form.php +++ b/assets/php/contact_form.php @@ -57,7 +57,18 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { if (empty($_POST['name'])) { $response['errors'][] = 'Du hast keinen Namen eingegeben.'; } - if ($_POST['captcha'] != 'Nudelsuppe') { + /* + Idee zur Bot-Erkennung: + 1. Ein Bot hat das Pseudocaptcha entweder leer abgeschickt, oder sich selbst etwas ausgedacht. + 2. Ein Bot schickt die Daten in unter 5s ab. + 3. Ein Mensch braucht nicht länger als 60min. + */ + if ( + $_POST['captcha'] != 'Nudelsuppe' || + preg_match('d{10}', $_POST['time_sent']) != 1 || + (preg_match('d{10}', $_POST['time_sent']) != 1 && time() - $_POST['time_sent'] < 5) || + (preg_match('d{10}', $_POST['time_sent']) != 1 && time() - $_POST['time_sent'] > 3600) + ) { $response['errors'][] = 'Wir glauben du bist ein Bot.'; } } else { From 2af9144fcbed1f3f82d536ec6791eadceb4c04ef Mon Sep 17 00:00:00 2001 From: muli Date: Thu, 16 Jun 2022 16:52:20 +0200 Subject: [PATCH 06/20] =?UTF-8?q?feat:=20Arrow=20functions=20aufger=C3=A4u?= =?UTF-8?q?mt=20und=20Fehlerbehandlung=20erg=C3=A4nzt.=20(#105)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/js/contact_form.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/js/contact_form.js b/assets/js/contact_form.js index 9f90099..5300af3 100644 --- a/assets/js/contact_form.js +++ b/assets/js/contact_form.js @@ -29,5 +29,6 @@ contact_form.addEventListener('submit', function(event) { body: formData, }) .then(response => response.json()) - .then(json => {console.log(json)}); + .then(json => console.log(json)) + .catch(error => console.log(error)); }, false); From 487f2268b684e56e6560c007074674f5802d9780 Mon Sep 17 00:00:00 2001 From: muli Date: Thu, 16 Jun 2022 18:23:05 +0200 Subject: [PATCH 07/20] feat: Fehlermeldungen anzeigen und Botdetection anhand von Bearbeitunszeit. (#105) --- assets/css/style.css | 8 +++++- assets/js/contact_form.js | 31 +++++++++++++++++++++-- assets/php/contact_form.php | 50 ++++++++++++++++--------------------- templates/contact_page.html | 1 + 4 files changed, 59 insertions(+), 31 deletions(-) diff --git a/assets/css/style.css b/assets/css/style.css index 2a6d907..a3c0ee0 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -33,6 +33,7 @@ /* misc colors */ --dark-red: #dc0000; + --dark-green: #007000; --column-count: 3; } @@ -886,10 +887,15 @@ hr.-even { justify-content: flex-start; } -.contact_form--required { +.contact_form--required, +.--error { color: var(--dark-red) } +.--success { + color: var(--dark-green); +} + .content__contact_form { } diff --git a/assets/js/contact_form.js b/assets/js/contact_form.js index 5300af3..c4182dd 100644 --- a/assets/js/contact_form.js +++ b/assets/js/contact_form.js @@ -5,7 +5,8 @@ const message = document.getElementsByClassName('contact_form__message')[0]; const name = document.getElementsByClassName('contact_form__name')[0]; const email = document.getElementsByClassName('contact_form__email')[0]; const captcha = document.getElementsByClassName('contact_form__captcha')[0]; -const now = (new Date().getTime/1000).toFixed(); +const now = (new Date().getTime()/1000).toFixed(); +const feedback = document.getElementsByClassName('contact_form__feedback')[0]; contact_form.addEventListener('submit', function(event) { event.preventDefault(); @@ -29,6 +30,32 @@ contact_form.addEventListener('submit', function(event) { body: formData, }) .then(response => response.json()) - .then(json => console.log(json)) + .then(json => { + console.log(json) + if (json.errors) { + feedback.classList.add('--error'); + // Über errors iterieren und diese ausgeben (evtl. nur ersten Fehler ausgeben?) + let error_message = ''; + json.errors.forEach(function(error){ + /** + * Nur Zeilenumbrüche wenn mehrer Fehlermeldungen existieren, + * aber bei der letzten nicht. + */ + if (json.errors.length > 1) { + if (error == json.errors[json.errors.length - 1]) { + error_message = error_message + error; + } else { + error_message = error_message + error + '
'; + } + } else { + error_message = error_message + error; + } + }) + feedback.innerHTML = error_message; + } else if (json.status == 'ok') { + feedback.classList.add('--success'); + feedback.textContent = "Ihre Nachricht wurde erfolgreich ans Office geschickt."; + } + }) .catch(error => console.log(error)); }, false); diff --git a/assets/php/contact_form.php b/assets/php/contact_form.php index ece2992..ebc5b10 100644 --- a/assets/php/contact_form.php +++ b/assets/php/contact_form.php @@ -42,36 +42,30 @@ function send_response($response_data) { if ($_SERVER["REQUEST_METHOD"] == "POST") { $response = array(); + if (empty($_POST['message'])) { + $response['errors'][] = 'Du hast keine Nachricht eingegeben.'; + } + if (empty($_POST['email'])) { + $response['errors'][] = 'Du hast keine E-Mail-Adresse eingegeben.'; + } + if (empty($_POST['name'])) { + $response['errors'][] = 'Du hast keinen Namen eingegeben.'; + } + /** + * Idee zur Bot-Erkennung: + * 1. Ein Bot hat das Pseudocaptcha entweder leer abgeschickt, oder sich selbst etwas ausgedacht. + * 2. Ein Bot schickt die Daten in unter 5s ab. + * 3. Ein Mensch braucht nicht länger als 60min. + */ if ( - empty($_POST['message']) || - empty($_POST['email']) || - empty($_POST['name']) || - $_POST['captcha'] != 'Nudelsuppe' + $_POST['captcha'] != 'Nudelsuppe' or + preg_match('/\d{10}/', $_POST['time_sent']) != 1 or + time() - intval($_POST['time_sent']) < 5 or + time() - intval($_POST['time_sent']) > 3600 ) { - if (empty($_POST['message'])) { - $response['errors'][] = 'Du hast keine Nachricht eingegeben.'; - } - if (empty($_POST['email'])) { - $response['errors'][] = 'Du hast keine E-Mail-Adresse eingegeben.'; - } - if (empty($_POST['name'])) { - $response['errors'][] = 'Du hast keinen Namen eingegeben.'; - } - /* - Idee zur Bot-Erkennung: - 1. Ein Bot hat das Pseudocaptcha entweder leer abgeschickt, oder sich selbst etwas ausgedacht. - 2. Ein Bot schickt die Daten in unter 5s ab. - 3. Ein Mensch braucht nicht länger als 60min. - */ - if ( - $_POST['captcha'] != 'Nudelsuppe' || - preg_match('d{10}', $_POST['time_sent']) != 1 || - (preg_match('d{10}', $_POST['time_sent']) != 1 && time() - $_POST['time_sent'] < 5) || - (preg_match('d{10}', $_POST['time_sent']) != 1 && time() - $_POST['time_sent'] > 3600) - ) { - $response['errors'][] = 'Wir glauben du bist ein Bot.'; - } - } else { + $response['errors'][] = 'Wir glauben du bist ein Bot.'; + } + if (!array_key_exists('errors', $response)) { $message = sanitize_text('message'); $name = sanitize_text('name'); $email = sanitize_text('email'); diff --git a/templates/contact_page.html b/templates/contact_page.html index 626c961..0e128ce 100644 --- a/templates/contact_page.html +++ b/templates/contact_page.html @@ -43,6 +43,7 @@

+

From 88276c2e2e2f08d8d9074967ecbf932af9020814 Mon Sep 17 00:00:00 2001 From: muli Date: Wed, 3 Aug 2022 18:04:03 +0200 Subject: [PATCH 08/20] feat: Switched time based bot protection from JS to PHP sessions. --- assets/js/contact_form.js | 20 +++++++++++++++++--- assets/php/contact_form.php | 31 ++++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/assets/js/contact_form.js b/assets/js/contact_form.js index c4182dd..87e90e6 100644 --- a/assets/js/contact_form.js +++ b/assets/js/contact_form.js @@ -8,13 +8,27 @@ const captcha = document.getElementsByClassName('contact_form__captcha')[0]; const now = (new Date().getTime()/1000).toFixed(); const feedback = document.getElementsByClassName('contact_form__feedback')[0]; +window.addEventListener('DOMContentLoaded', function(event) { + let formData = new FormData(); + formData.append('action', 'start_session'); + fetch(ajaxUrl, { + method: 'POST', + mode: 'same-origin', + body: formData, + }) + .then(response => response.json()) + .then(json => { + console.log(json); + }) +}); + contact_form.addEventListener('submit', function(event) { event.preventDefault(); let formData = new FormData(); + formData.append('action', 'handle_form'); formData.append('message', message.value); formData.append('name', name.value); formData.append('email', email.value); - formData.append('time_sent', now); // If some bot entered some value, return. if (typeof captcha.value == 'undefined') { @@ -26,12 +40,12 @@ contact_form.addEventListener('submit', function(event) { fetch(ajaxUrl, { method: 'POST', - mode:'same-origin', + mode: 'same-origin', body: formData, }) .then(response => response.json()) .then(json => { - console.log(json) + console.log(json); if (json.errors) { feedback.classList.add('--error'); // Über errors iterieren und diese ausgeben (evtl. nur ersten Fehler ausgeben?) diff --git a/assets/php/contact_form.php b/assets/php/contact_form.php index ebc5b10..205c11b 100644 --- a/assets/php/contact_form.php +++ b/assets/php/contact_form.php @@ -1,7 +1,5 @@ 3600 + time() - $_SESSION['start_time'] < 5 or + time() - $_SESSION['start_time'] > 3600 ) { $response['errors'][] = 'Wir glauben du bist ein Bot.'; } @@ -76,6 +73,26 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { $response['status'] = 'ok'; } } + return $response; +} + +if ($_SERVER["REQUEST_METHOD"] == "POST") { + $response = array(); + + if (empty($_POST['action'])){ + $response['errors'][] = 'Kann eigentlich nicht passieren :/'; + } else { + if ($_POST['action'] == 'start_session') { + $_SESSION['start_time'] = time(); + // $response['session_start_time'] = $_SESSION['start_time']; + // $response['session_id_before'] = session_id(); + } elseif ($_POST['action'] == 'handle_form') { + $response = prepare_response(); + session_destroy(); + } else { + $response['errors'][] = 'Kann eigentlich auch nicht passieren :/'; + } + } send_response($response); } else { http_response_code(404); From 553bba89179510b7687b894e0400f0fda9a36fe7 Mon Sep 17 00:00:00 2001 From: muli Date: Thu, 18 Aug 2022 20:32:01 +0200 Subject: [PATCH 09/20] feat: Improved layout of contact form submit button. --- assets/css/style.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/assets/css/style.css b/assets/css/style.css index a3c0ee0..c6f6e34 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -920,6 +920,11 @@ hr.-even { font-size: 1rem; } +.contact_form__submit_button { + font-size: 1rem; + padding: 0 0.25rem; +} + /* Hide captcha field as part of spam protection. We got no real captcha. */ .contact_form__captcha { From 9b9f2b95c5392e746db624a39ef3e92aecb02bc3 Mon Sep 17 00:00:00 2001 From: muli Date: Thu, 18 Aug 2022 20:19:02 +0200 Subject: [PATCH 10/20] fix: Removed empty class definition. --- assets/css/style.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/assets/css/style.css b/assets/css/style.css index c6f6e34..7909370 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -896,10 +896,6 @@ hr.-even { color: var(--dark-green); } -.content__contact_form { - -} - .contact_form__textarea, .contact_form__text_input, .contact_form__captcha { From 4f7edc53a8512e94ac97b1b2517da90377418eb0 Mon Sep 17 00:00:00 2001 From: muli Date: Wed, 3 Aug 2022 19:30:21 +0200 Subject: [PATCH 11/20] fix: Duzen all the way. --- assets/js/contact_form.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/contact_form.js b/assets/js/contact_form.js index 87e90e6..fb0844b 100644 --- a/assets/js/contact_form.js +++ b/assets/js/contact_form.js @@ -68,7 +68,7 @@ contact_form.addEventListener('submit', function(event) { feedback.innerHTML = error_message; } else if (json.status == 'ok') { feedback.classList.add('--success'); - feedback.textContent = "Ihre Nachricht wurde erfolgreich ans Office geschickt."; + feedback.textContent = "Deine Nachricht wurde erfolgreich ans Office geschickt."; } }) .catch(error => console.log(error)); From e53449352f226023fd50ffc68a74f5cffb41851e Mon Sep 17 00:00:00 2001 From: muli Date: Wed, 3 Aug 2022 19:31:06 +0200 Subject: [PATCH 12/20] feat: Added subject to contact form. --- assets/css/style.css | 1 + assets/js/contact_form.js | 2 ++ assets/php/contact_form.php | 3 ++- templates/contact_page.html | 4 ++++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/assets/css/style.css b/assets/css/style.css index 7909370..bce2245 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -907,6 +907,7 @@ hr.-even { height: 12em; } +.contact_form__subject, .contact_form__message, .contact_form__name, .contact_form__email, diff --git a/assets/js/contact_form.js b/assets/js/contact_form.js index fb0844b..fcd7540 100644 --- a/assets/js/contact_form.js +++ b/assets/js/contact_form.js @@ -1,6 +1,7 @@ const ajaxUrl = 'https://spielwiese.wtf-eg.de/php/contact_form.php'; // const submit_button = document.getElementsByClassName('contact_form__submit_button')[0]; const contact_form = document.getElementsByClassName('content__contact_form')[0]; +const subject = document.getElementsByClassName('contact_form__subject')[0]; const message = document.getElementsByClassName('contact_form__message')[0]; const name = document.getElementsByClassName('contact_form__name')[0]; const email = document.getElementsByClassName('contact_form__email')[0]; @@ -26,6 +27,7 @@ contact_form.addEventListener('submit', function(event) { event.preventDefault(); let formData = new FormData(); formData.append('action', 'handle_form'); + formData.append('subject', subject.value); formData.append('message', message.value); formData.append('name', name.value); formData.append('email', email.value); diff --git a/assets/php/contact_form.php b/assets/php/contact_form.php index 205c11b..88d2497 100644 --- a/assets/php/contact_form.php +++ b/assets/php/contact_form.php @@ -63,11 +63,12 @@ function prepare_response() { $response['errors'][] = 'Wir glauben du bist ein Bot.'; } if (!array_key_exists('errors', $response)) { + $subject = sanitize_text('subject'); $message = sanitize_text('message'); $name = sanitize_text('name'); $email = sanitize_text('email'); - if (!send_message_to_office($message, $name, $email)) { + if (!send_message_to_office($subject, $message, $name, $email)) { $response['errors'][] = 'Deine Nachricht konnte nicht übermittelt werden.'; } else { $response['status'] = 'ok'; diff --git a/templates/contact_page.html b/templates/contact_page.html index 0e128ce..f90a682 100644 --- a/templates/contact_page.html +++ b/templates/contact_page.html @@ -25,6 +25,10 @@ Deine E-Mail-Adresse wird nicht veröffentlicht.

+

+ + +

From fa9cf1bf37ec6b5e78641d6f0ec8026f432a1800 Mon Sep 17 00:00:00 2001 From: muli Date: Wed, 3 Aug 2022 19:32:09 +0200 Subject: [PATCH 13/20] fix: Remove opposite highlight classes to just display the most recent one. --- assets/js/contact_form.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/js/contact_form.js b/assets/js/contact_form.js index fcd7540..7a48e1f 100644 --- a/assets/js/contact_form.js +++ b/assets/js/contact_form.js @@ -49,6 +49,7 @@ contact_form.addEventListener('submit', function(event) { .then(json => { console.log(json); if (json.errors) { + feedback.classList.remove('--success'); feedback.classList.add('--error'); // Über errors iterieren und diese ausgeben (evtl. nur ersten Fehler ausgeben?) let error_message = ''; @@ -69,6 +70,7 @@ contact_form.addEventListener('submit', function(event) { }) feedback.innerHTML = error_message; } else if (json.status == 'ok') { + feedback.classList.remove('--error'); feedback.classList.add('--success'); feedback.textContent = "Deine Nachricht wurde erfolgreich ans Office geschickt."; } From f58ba3bbc119d3f465cb28acd42c9bd016571d03 Mon Sep 17 00:00:00 2001 From: muli Date: Wed, 3 Aug 2022 19:32:59 +0200 Subject: [PATCH 14/20] feat: Now really send emails. --- assets/php/contact_form.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/assets/php/contact_form.php b/assets/php/contact_form.php index 88d2497..cdc4ce6 100644 --- a/assets/php/contact_form.php +++ b/assets/php/contact_form.php @@ -16,8 +16,17 @@ function sanitize_text(string $name) { * mail(): Braucht auf dem Server einen korrekt konfigurierten Mailserver * phpmailer: Bibliothek, der per Composer installiert wird. Tut ganz gut mit SMTP. */ -function send_message_to_office($message, $name, $email) { - return true; +function send_message_to_office($subject, $message, $name, $email) { + return mail( + getenv('WTF_CONTACT_TO'), + 'spielwiese contact form', + $name . "\r\n" . $message, + $additional_headers = array( + "From" => getenv('WTF_CONTACT_FROM'), + "Reply-To" => $email, + "Return-Path" => getenv('WTF_RETURN_PATH'), + ), + ); } function send_response($response_data) { From 360f90fc9dde3e3e1c65d91fefed3240bb3fe5a6 Mon Sep 17 00:00:00 2001 From: muli Date: Tue, 9 Aug 2022 17:42:35 +0200 Subject: [PATCH 15/20] fix: Not just pass it along but really use the subject ;) --- assets/php/contact_form.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/php/contact_form.php b/assets/php/contact_form.php index cdc4ce6..e9bb87e 100644 --- a/assets/php/contact_form.php +++ b/assets/php/contact_form.php @@ -19,7 +19,7 @@ function sanitize_text(string $name) { function send_message_to_office($subject, $message, $name, $email) { return mail( getenv('WTF_CONTACT_TO'), - 'spielwiese contact form', + $subject, $name . "\r\n" . $message, $additional_headers = array( "From" => getenv('WTF_CONTACT_FROM'), From e2fa3f75cce4b62750d11b31e6d9a5388e9b4d06 Mon Sep 17 00:00:00 2001 From: muli Date: Wed, 17 Aug 2022 21:56:57 +0200 Subject: [PATCH 16/20] fix: Changed user facing text to formal speech. --- assets/js/contact_form.js | 2 +- assets/php/contact_form.php | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/assets/js/contact_form.js b/assets/js/contact_form.js index 7a48e1f..5f1fa03 100644 --- a/assets/js/contact_form.js +++ b/assets/js/contact_form.js @@ -72,7 +72,7 @@ contact_form.addEventListener('submit', function(event) { } else if (json.status == 'ok') { feedback.classList.remove('--error'); feedback.classList.add('--success'); - feedback.textContent = "Deine Nachricht wurde erfolgreich ans Office geschickt."; + feedback.textContent = "Ihre Nachricht wurde erfolgreich ans Office geschickt."; } }) .catch(error => console.log(error)); diff --git a/assets/php/contact_form.php b/assets/php/contact_form.php index e9bb87e..6026f05 100644 --- a/assets/php/contact_form.php +++ b/assets/php/contact_form.php @@ -50,13 +50,14 @@ function prepare_response() { $response = array(); if (empty($_POST['message'])) { - $response['errors'][] = 'Du hast keine Nachricht eingegeben.'; + $response['errors'][] = 'Sieh haben keine Nachricht eingegeben.'; } if (empty($_POST['email'])) { - $response['errors'][] = 'Du hast keine E-Mail-Adresse eingegeben.'; + $response['errors'][] = 'Sie haben keine E-Mail-Adresse eingegeben.'; } if (empty($_POST['name'])) { - $response['errors'][] = 'Du hast keinen Namen eingegeben.'; + $response['errors'][] = 'Sie haben keinen Namen eingegeben.'; + } } /** * Idee zur Bot-Erkennung: @@ -69,7 +70,7 @@ function prepare_response() { time() - $_SESSION['start_time'] < 5 or time() - $_SESSION['start_time'] > 3600 ) { - $response['errors'][] = 'Wir glauben du bist ein Bot.'; + $response['errors'][] = 'Wir glauben Sie sind ein Bot.'; } if (!array_key_exists('errors', $response)) { $subject = sanitize_text('subject'); @@ -78,7 +79,7 @@ function prepare_response() { $email = sanitize_text('email'); if (!send_message_to_office($subject, $message, $name, $email)) { - $response['errors'][] = 'Deine Nachricht konnte nicht übermittelt werden.'; + $response['errors'][] = 'Ihre Nachricht konnte nicht übermittelt werden.'; } else { $response['status'] = 'ok'; } From 92d2c37000b4209c8d6d9bf10218dc06927f82c4 Mon Sep 17 00:00:00 2001 From: muli Date: Wed, 17 Aug 2022 21:57:29 +0200 Subject: [PATCH 17/20] fix: Added missing error message for missing subject. --- assets/php/contact_form.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/php/contact_form.php b/assets/php/contact_form.php index 6026f05..483eea8 100644 --- a/assets/php/contact_form.php +++ b/assets/php/contact_form.php @@ -58,6 +58,8 @@ function prepare_response() { if (empty($_POST['name'])) { $response['errors'][] = 'Sie haben keinen Namen eingegeben.'; } + if (empty($_POST['subject'])) { + $response['errors'][] = 'Sie haben keinen Betreff eingegeben.'; } /** * Idee zur Bot-Erkennung: From b65755de8d231affd95edb390c5a4ef25c415086 Mon Sep 17 00:00:00 2001 From: muli Date: Sat, 20 Aug 2022 15:55:16 +0200 Subject: [PATCH 18/20] feat: Switched from hardcoded domain to relative path to improve portability. --- assets/js/contact_form.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/assets/js/contact_form.js b/assets/js/contact_form.js index 5f1fa03..1d8bf65 100644 --- a/assets/js/contact_form.js +++ b/assets/js/contact_form.js @@ -1,5 +1,4 @@ -const ajaxUrl = 'https://spielwiese.wtf-eg.de/php/contact_form.php'; -// const submit_button = document.getElementsByClassName('contact_form__submit_button')[0]; +const ajaxUrl = '../php/contact_form.php'; const contact_form = document.getElementsByClassName('content__contact_form')[0]; const subject = document.getElementsByClassName('contact_form__subject')[0]; const message = document.getElementsByClassName('contact_form__message')[0]; From 4e7b22fde64b94538114c3bfecf939e00521815b Mon Sep 17 00:00:00 2001 From: muli Date: Sun, 21 Aug 2022 14:14:32 +0200 Subject: [PATCH 19/20] fix: Fix sanitation to not break Umlauts and use specific email filter. --- assets/php/contact_form.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/assets/php/contact_form.php b/assets/php/contact_form.php index 483eea8..ec0287f 100644 --- a/assets/php/contact_form.php +++ b/assets/php/contact_form.php @@ -1,11 +1,14 @@ FILTER_SANITIZE_SPECIAL_CHARS, + 'email' => FILTER_SANITIZE_EMAIL, + ); $text = trim($text); + $text = filter_var($_POST[$name], $filters[$type]); $text = stripslashes($text); - $text = htmlspecialchars($text); return $text; } @@ -75,10 +78,10 @@ function prepare_response() { $response['errors'][] = 'Wir glauben Sie sind ein Bot.'; } if (!array_key_exists('errors', $response)) { - $subject = sanitize_text('subject'); - $message = sanitize_text('message'); - $name = sanitize_text('name'); - $email = sanitize_text('email'); + $subject = sanitize_text('subject', 'text'); + $message = sanitize_text('message', 'text'); + $name = sanitize_text('name', 'text'); + $email = sanitize_text('email', 'email'); if (!send_message_to_office($subject, $message, $name, $email)) { $response['errors'][] = 'Ihre Nachricht konnte nicht übermittelt werden.'; From 54482d90f68ac05dbbbb3790d54acd7b24aac1e3 Mon Sep 17 00:00:00 2001 From: muli Date: Sun, 21 Aug 2022 14:16:46 +0200 Subject: [PATCH 20/20] fix: Ensure \r\n for line breaks and properly encode subject for umlauts. --- assets/php/contact_form.php | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/assets/php/contact_form.php b/assets/php/contact_form.php index ec0287f..d0c8e33 100644 --- a/assets/php/contact_form.php +++ b/assets/php/contact_form.php @@ -13,8 +13,23 @@ function sanitize_text(string $name, string $type) { return $text; } +function prepare_message_body($message) { + // Replace HTML-Entities with actual carriage returns and line feeds + $message = str_replace(" ", "\r", $message); + $message = str_replace(" ", "\r", $message); + + // Ensure line breaks via carriage return + line feed + $message = str_replace("\r\n", "\n", $message); + $message = str_replace("\n", "\r\n", $message); + + $message = "Nachricht von: $name\r\n\r\n" . $message; + $message = base64_encode($message); + + return $message; +} + /** - * Sending email (Platzhalter) + * Sending email * * mail(): Braucht auf dem Server einen korrekt konfigurierten Mailserver * phpmailer: Bibliothek, der per Composer installiert wird. Tut ganz gut mit SMTP. @@ -22,12 +37,14 @@ function sanitize_text(string $name, string $type) { function send_message_to_office($subject, $message, $name, $email) { return mail( getenv('WTF_CONTACT_TO'), - $subject, - $name . "\r\n" . $message, + "=?UTF-8?B?" . base64_encode($subject) . "?=", + prepare_message_body($message), $additional_headers = array( "From" => getenv('WTF_CONTACT_FROM'), "Reply-To" => $email, "Return-Path" => getenv('WTF_RETURN_PATH'), + "Content-Type" => "text/plain; charset=utf-8", + "Content-Transfer-Encoding" => "base64", ), ); }