Compare commits
No commits in common. "7ae47ee5903b55ede96239b857700b1d34112fc2" and "b798c02babdb3c76170332987920263a2b730b69" have entirely different histories.
7ae47ee590
...
b798c02bab
11
.gitignore
vendored
11
.gitignore
vendored
@ -14,7 +14,6 @@ temp/
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.AppleDouble
|
.AppleDouble
|
||||||
.LSOverride
|
.LSOverride
|
||||||
.nova
|
|
||||||
|
|
||||||
# Icon must end with two \r
|
# Icon must end with two \r
|
||||||
Icon
|
Icon
|
||||||
@ -87,12 +86,8 @@ $RECYCLE.BIN/
|
|||||||
# Windows shortcuts
|
# Windows shortcuts
|
||||||
*.lnk
|
*.lnk
|
||||||
|
|
||||||
### Python ###
|
# Python virtual enviroment
|
||||||
# Compiled python
|
|
||||||
*.pyc
|
|
||||||
|
|
||||||
# Virtaul environments
|
|
||||||
.env
|
|
||||||
.venv
|
|
||||||
env
|
env
|
||||||
|
.env
|
||||||
venv
|
venv
|
||||||
|
.venv
|
||||||
|
@ -31,10 +31,6 @@
|
|||||||
--wtf-light-grey: #edefeb;
|
--wtf-light-grey: #edefeb;
|
||||||
--wtf-lila: #6600ff;
|
--wtf-lila: #6600ff;
|
||||||
|
|
||||||
/* misc colors */
|
|
||||||
--dark-red: #dc0000;
|
|
||||||
--dark-green: #007000;
|
|
||||||
|
|
||||||
--column-count: 3;
|
--column-count: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -886,47 +882,6 @@ hr.-even {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact_form--required,
|
|
||||||
.--error {
|
|
||||||
color: var(--dark-red)
|
|
||||||
}
|
|
||||||
|
|
||||||
.--success {
|
|
||||||
color: var(--dark-green);
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact_form__textarea,
|
|
||||||
.contact_form__text_input,
|
|
||||||
.contact_form__captcha {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact_form__message {
|
|
||||||
height: 12em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact_form__subject,
|
|
||||||
.contact_form__message,
|
|
||||||
.contact_form__name,
|
|
||||||
.contact_form__email,
|
|
||||||
.contact_form__captcha {
|
|
||||||
font-family: 'Lato', sans-serif;
|
|
||||||
line-height: 1.3rem;
|
|
||||||
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 {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
/* main - Ende */
|
/* main - Ende */
|
||||||
|
|
||||||
/* footer - Start */
|
/* footer - Start */
|
||||||
|
@ -1,78 +0,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];
|
|
||||||
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 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('subject', subject.value);
|
|
||||||
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);
|
|
||||||
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 = '';
|
|
||||||
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 + '<br>';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
error_message = error_message + error;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
feedback.innerHTML = error_message;
|
|
||||||
} else if (json.status == 'ok') {
|
|
||||||
feedback.classList.remove('--error');
|
|
||||||
feedback.classList.add('--success');
|
|
||||||
feedback.textContent = "Ihre Nachricht wurde erfolgreich ans Office geschickt.";
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => console.log(error));
|
|
||||||
}, false);
|
|
@ -1,5 +0,0 @@
|
|||||||
/* 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');
|
|
||||||
});
|
|
@ -6,6 +6,6 @@
|
|||||||
"sizes": "96x96",
|
"sizes": "96x96",
|
||||||
"type": "image\/png",
|
"type": "image\/png",
|
||||||
"density": "2.0"
|
"density": "2.0"
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -1,132 +0,0 @@
|
|||||||
<?php
|
|
||||||
session_start();
|
|
||||||
|
|
||||||
function sanitize_text(string $name, string $type) {
|
|
||||||
$filters = array(
|
|
||||||
'text' => FILTER_SANITIZE_SPECIAL_CHARS,
|
|
||||||
'email' => FILTER_SANITIZE_EMAIL,
|
|
||||||
);
|
|
||||||
$text = trim($text);
|
|
||||||
$text = filter_var($_POST[$name], $filters[$type]);
|
|
||||||
$text = stripslashes($text);
|
|
||||||
|
|
||||||
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
|
|
||||||
*
|
|
||||||
* 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($subject, $message, $name, $email) {
|
|
||||||
return mail(
|
|
||||||
getenv('WTF_CONTACT_TO'),
|
|
||||||
"=?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",
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function send_response($response_data) {
|
|
||||||
$json = json_encode($response_data);
|
|
||||||
if ($json === false) {
|
|
||||||
// Avoid echo of empty string (which is invalid JSON), and
|
|
||||||
// JSONify the error message instead:
|
|
||||||
$json = json_encode(["jsonError" => 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
function prepare_response() {
|
|
||||||
$response = array();
|
|
||||||
|
|
||||||
if (empty($_POST['message'])) {
|
|
||||||
$response['errors'][] = 'Sieh haben keine Nachricht eingegeben.';
|
|
||||||
}
|
|
||||||
if (empty($_POST['email'])) {
|
|
||||||
$response['errors'][] = 'Sie haben keine E-Mail-Adresse eingegeben.';
|
|
||||||
}
|
|
||||||
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:
|
|
||||||
* 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' or
|
|
||||||
time() - $_SESSION['start_time'] < 5 or
|
|
||||||
time() - $_SESSION['start_time'] > 3600
|
|
||||||
) {
|
|
||||||
$response['errors'][] = 'Wir glauben Sie sind ein Bot.';
|
|
||||||
}
|
|
||||||
if (!array_key_exists('errors', $response)) {
|
|
||||||
$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.';
|
|
||||||
} else {
|
|
||||||
$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);
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
_model: contact_page
|
_model: page
|
||||||
---
|
---
|
||||||
title: Kontakt
|
title: Kontakt
|
||||||
---
|
---
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
[model]
|
|
||||||
name = Contact Page
|
|
||||||
label = {{ this.title }}
|
|
||||||
inherits = page
|
|
@ -1,56 +0,0 @@
|
|||||||
{% 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 %}
|
|
||||||
<div class="content__box">
|
|
||||||
<div class="content__inner_box">
|
|
||||||
<h1>{{ this.title }}</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<section class="content -odd">
|
|
||||||
<div class="content__box">
|
|
||||||
<div class="content__inner_box -width_constraint">
|
|
||||||
{{ this.body }}
|
|
||||||
</div>
|
|
||||||
<div class="content__inner_box -width_constraint content__contact_form_wrapper" style="display:none">
|
|
||||||
<h2>Kontaktformular</h2>
|
|
||||||
<form id="contact_form" class="content__contact_form">
|
|
||||||
<p class="contact_form__note">
|
|
||||||
Deine E-Mail-Adresse wird nicht veröffentlicht.<br>
|
|
||||||
<span aria-hidden="true">Erforderliche Felder sind gekennzeichnet <span class="contact_form--required" aria-hidden="true">*</span></span>
|
|
||||||
</p>
|
|
||||||
<p class="contact_form__text_input">
|
|
||||||
<label for="name">Betreff <span class="contact_form--required" aria-hidden="true">*</span></label>
|
|
||||||
<input id="name" class="contact_form__subject" name="subject" type="text" value="" size="30" maxlength="245" required />
|
|
||||||
</p>
|
|
||||||
<p class="contact_form__textarea">
|
|
||||||
<label for="message">Nachricht <span class="contact_form--required" aria-hidden="true">*</span></label>
|
|
||||||
<textarea id="message" class="contact_form__message" aria-label="message" aria-hidden="true" cols="65" rows="7" name="message" required></textarea>
|
|
||||||
</p>
|
|
||||||
<p class="contact_form__text_input">
|
|
||||||
<label for="name">Name <span class="contact_form--required" aria-hidden="true">*</span></label>
|
|
||||||
<input id="name" class="contact_form__name" name="name" type="text" value="" size="30" maxlength="245" required />
|
|
||||||
</p>
|
|
||||||
<p class="contact_form__text_input">
|
|
||||||
<label for="email">E-Mail-Adresse <span class="contact_form--required" aria-hidden="true">*</span></label>
|
|
||||||
<input id="email" class="contact_form__email" name="email" type="email" value="" size="30" maxlength="100" aria-describedby="email-address" required />
|
|
||||||
</p>
|
|
||||||
<p class="contact_form__captcha">
|
|
||||||
<label for="captcha">Captcha <span class="contact_form--required" aria-hidden="true">*</span></label>
|
|
||||||
<input id="captcha" class="contact_form__captcha" name="captcha" type="captcha" value="…" size="30" maxlength="100" required placeholder="Wie viele Ecken hat ein Pentagramm?"/>
|
|
||||||
</p>
|
|
||||||
<p class="contact_form__submit">
|
|
||||||
<input name="submit" type="submit" id="submit" class="contact_form__submit_button" value="Kommentar abschicken" />
|
|
||||||
<p class="contact_form__feedback"></p>
|
|
||||||
</p>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
{% endblock %}
|
|
@ -63,9 +63,6 @@ __ ____________________
|
|||||||
{% if 'manifest.json'|asseturl is defined -%}
|
{% if 'manifest.json'|asseturl is defined -%}
|
||||||
<link rel="manifest" href="{{ 'manifest.json'|asseturl }}">
|
<link rel="manifest" href="{{ 'manifest.json'|asseturl }}">
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{% if '/js/contact_form_toggle.js'|asseturl is defined -%}
|
|
||||||
<script type="text/javascript" src="{{ '/js/contact_form_toggle.js'|asseturl }}"></script>
|
|
||||||
{%- endif %}
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
@ -131,7 +128,4 @@ __ ____________________
|
|||||||
{%- if '/js/nav_toggle.js'|asseturl is defined -%}
|
{%- if '/js/nav_toggle.js'|asseturl is defined -%}
|
||||||
<script type="text/javascript" src="{{ '/js/nav_toggle.js'|asseturl }}"></script>
|
<script type="text/javascript" src="{{ '/js/nav_toggle.js'|asseturl }}"></script>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{% if '/js/contact_form_toggle.js'|asseturl is defined -%}
|
|
||||||
<script type="text/javascript" src="{{ '/js/contact_form.js'|asseturl }}"></script>
|
|
||||||
{%- endif %}
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -13,15 +13,6 @@ default = yes
|
|||||||
locale = de_DE
|
locale = de_DE
|
||||||
target = rsync://wtf@www.wtf-eg.net:/srv/www/www.wtf-eg.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]
|
[alternatives.de]
|
||||||
name = Deutsch
|
name = Deutsch
|
||||||
primary = true
|
primary = true
|
||||||
|
Loading…
Reference in New Issue
Block a user