361 lines
12 KiB
PHP
361 lines
12 KiB
PHP
<?php
|
|
/**
|
|
* HexaHost.de Contact Form Handler
|
|
* E-Mail-Verarbeitung mit nativer PHP-mail()-Funktion und Spam-Schutz
|
|
*/
|
|
|
|
require_once __DIR__ . '/../backend/includes/functions.php';
|
|
require_once __DIR__ . '/../backend/config/mail-config.php';
|
|
require_once __DIR__ . '/../backend/config/contact-config.php';
|
|
|
|
$config = getHexaHostConfig();
|
|
|
|
// CORS Headers für AJAX-Requests (nur eigene Domain erlauben)
|
|
$allowed_origins = [
|
|
'https://hexahost.de',
|
|
'https://www.hexahost.de',
|
|
'https://dev.hexahost.de',
|
|
'http://localhost',
|
|
'http://127.0.0.1',
|
|
];
|
|
|
|
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
|
|
if (in_array($origin, $allowed_origins, true)) {
|
|
header('Access-Control-Allow-Origin: ' . $origin);
|
|
}
|
|
|
|
header('Access-Control-Allow-Methods: POST');
|
|
header('Access-Control-Allow-Headers: Content-Type');
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
http_response_code(405);
|
|
echo json_encode(['success' => false, 'message' => 'Method not allowed']);
|
|
exit;
|
|
}
|
|
|
|
function checkRateLimit($ip) {
|
|
global $config;
|
|
$cache_file = sys_get_temp_dir() . '/hexahost_contact_' . md5($ip) . '.txt';
|
|
$current_time = time();
|
|
$data = ['requests' => []];
|
|
|
|
$handle = @fopen($cache_file, 'c+');
|
|
if ($handle === false) {
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
if (!flock($handle, LOCK_EX)) {
|
|
return true;
|
|
}
|
|
|
|
$contents = stream_get_contents($handle);
|
|
if ($contents !== false && $contents !== '') {
|
|
$decoded = json_decode($contents, true);
|
|
if (is_array($decoded) && isset($decoded['requests'])) {
|
|
$data = $decoded;
|
|
}
|
|
}
|
|
|
|
$data['requests'] = array_values(array_filter(
|
|
$data['requests'],
|
|
static fn($timestamp) => ($current_time - (int) $timestamp) < 3600
|
|
));
|
|
|
|
if (count($data['requests']) >= $config['max_requests_per_hour']) {
|
|
return false;
|
|
}
|
|
|
|
$data['requests'][] = $current_time;
|
|
ftruncate($handle, 0);
|
|
rewind($handle);
|
|
fwrite($handle, json_encode($data));
|
|
} finally {
|
|
flock($handle, LOCK_UN);
|
|
fclose($handle);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function checkHoneypot($data) {
|
|
global $config;
|
|
$honeypot_field = $config['honeypot_field'];
|
|
return empty($data[$honeypot_field]);
|
|
}
|
|
|
|
function sanitizeFormField($input) {
|
|
return strip_tags(trim((string) $input));
|
|
}
|
|
|
|
function getSubjectLabel($subjectKey) {
|
|
$map = getContactSubjectMap();
|
|
return $map[$subjectKey] ?? 'Neue Kontaktanfrage';
|
|
}
|
|
|
|
function sendEmail($data) {
|
|
global $config;
|
|
|
|
$subject = '[HexaHost.de] ' . getSubjectLabel($data['subject']);
|
|
$replyName = sanitizeHeaderValue($data['firstName'] . ' ' . $data['lastName']);
|
|
$replyEmail = sanitizeHeaderValue($data['email']);
|
|
|
|
$headers = [
|
|
'From: ' . $config['from_name'] . ' <' . $config['from_email'] . '>',
|
|
'Reply-To: ' . $replyName . ' <' . $replyEmail . '>',
|
|
'MIME-Version: 1.0',
|
|
'Content-Type: text/html; charset=UTF-8',
|
|
'X-Mailer: HexaHost Contact Form',
|
|
'X-Priority: 3',
|
|
'X-MSMail-Priority: Normal',
|
|
'Importance: Normal',
|
|
'X-Report-Abuse: Please report abuse here: abuse@hexahost.de',
|
|
];
|
|
|
|
// Native PHP Mailversand ohne externe Libraries
|
|
return mail($config['to_email'], $subject, generateEmailHTML($data), implode("\r\n", $headers));
|
|
}
|
|
|
|
function generateEmailHTML($data) {
|
|
$subject_text = htmlspecialchars(getSubjectLabel($data['subject']), ENT_QUOTES, 'UTF-8');
|
|
|
|
$html = '
|
|
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Neue Kontaktanfrage - HexaHost.de</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
|
|
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
|
|
.header { background: linear-gradient(135deg, #ff51f9, #a348ff); color: white; padding: 20px; text-align: center; }
|
|
.content { background: #f9f9f9; padding: 20px; }
|
|
.field { margin-bottom: 15px; }
|
|
.label { font-weight: bold; color: #666; }
|
|
.value { color: #333; }
|
|
.message { background: white; padding: 15px; border-left: 4px solid #ff51f9; margin: 15px 0; }
|
|
.footer { text-align: center; padding: 20px; color: #666; font-size: 12px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="header">
|
|
<h1>Neue Kontaktanfrage</h1>
|
|
<p>HexaHost.de Kontaktformular</p>
|
|
</div>
|
|
|
|
<div class="content">
|
|
<div class="field">
|
|
<div class="label">Betreff:</div>
|
|
<div class="value">' . $subject_text . '</div>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<div class="label">Name:</div>
|
|
<div class="value">' . htmlspecialchars($data['firstName'] . ' ' . $data['lastName'], ENT_QUOTES, 'UTF-8') . '</div>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<div class="label">E-Mail:</div>
|
|
<div class="value">' . htmlspecialchars($data['email'], ENT_QUOTES, 'UTF-8') . '</div>
|
|
</div>';
|
|
|
|
if (!empty($data['phone'])) {
|
|
$html .= '
|
|
<div class="field">
|
|
<div class="label">Telefon:</div>
|
|
<div class="value">' . htmlspecialchars($data['phone'], ENT_QUOTES, 'UTF-8') . '</div>
|
|
</div>';
|
|
}
|
|
|
|
if (!empty($data['company'])) {
|
|
$html .= '
|
|
<div class="field">
|
|
<div class="label">Unternehmen:</div>
|
|
<div class="value">' . htmlspecialchars($data['company'], ENT_QUOTES, 'UTF-8') . '</div>
|
|
</div>';
|
|
}
|
|
|
|
$html .= '
|
|
<div class="field">
|
|
<div class="label">Nachricht:</div>
|
|
<div class="message">' . nl2br(htmlspecialchars($data['message'], ENT_QUOTES, 'UTF-8')) . '</div>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<div class="label">IP-Adresse:</div>
|
|
<div class="value">' . htmlspecialchars(getClientIP(), ENT_QUOTES, 'UTF-8') . '</div>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<div class="label">Zeitstempel:</div>
|
|
<div class="value">' . date('d.m.Y H:i:s') . '</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="footer">
|
|
<p>Diese E-Mail wurde automatisch vom HexaHost.de Kontaktformular generiert.</p>
|
|
<p>© ' . date('Y') . ' HexaHost.de - Alle Rechte vorbehalten</p>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
function generateEmailText($data) {
|
|
$text = "NEUE KONTAKTANFRAGE - HexaHost.de\n";
|
|
$text .= "=====================================\n\n";
|
|
$text .= "Betreff: " . getSubjectLabel($data['subject']) . "\n";
|
|
$text .= "Name: " . $data['firstName'] . " " . $data['lastName'] . "\n";
|
|
$text .= "E-Mail: " . $data['email'] . "\n";
|
|
|
|
if (!empty($data['phone'])) {
|
|
$text .= "Telefon: " . $data['phone'] . "\n";
|
|
}
|
|
|
|
if (!empty($data['company'])) {
|
|
$text .= "Unternehmen: " . $data['company'] . "\n";
|
|
}
|
|
|
|
$text .= "\nNachricht:\n";
|
|
$text .= "----------\n";
|
|
$text .= $data['message'] . "\n\n";
|
|
$text .= "IP-Adresse: " . getClientIP() . "\n";
|
|
$text .= "Zeitstempel: " . date('d.m.Y H:i:s') . "\n\n";
|
|
$text .= "---\n";
|
|
$text .= "Diese E-Mail wurde automatisch vom HexaHost.de Kontaktformular generiert.\n";
|
|
$text .= "© " . date('Y') . " HexaHost.de - Alle Rechte vorbehalten";
|
|
|
|
return $text;
|
|
}
|
|
|
|
try {
|
|
if (!empty($config['enable_csrf'])) {
|
|
if (empty($_POST['csrf_token']) || !validateCSRFToken($_POST['csrf_token'])) {
|
|
http_response_code(403);
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Ungültige Sitzung. Bitte laden Sie die Seite neu und versuchen Sie es erneut.',
|
|
]);
|
|
exit;
|
|
}
|
|
}
|
|
|
|
if (!checkRateLimit(getClientIP())) {
|
|
http_response_code(429);
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Zu viele Anfragen. Bitte versuchen Sie es später erneut.',
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
if (!checkHoneypot($_POST)) {
|
|
http_response_code(400);
|
|
echo json_encode(['success' => false, 'message' => 'Ungültige Anfrage.']);
|
|
exit;
|
|
}
|
|
|
|
$required_fields = ['firstName', 'lastName', 'email', 'subject', 'message', 'privacy'];
|
|
$missing_fields = [];
|
|
|
|
foreach ($required_fields as $field) {
|
|
if (empty($_POST[$field])) {
|
|
$missing_fields[] = $field;
|
|
}
|
|
}
|
|
|
|
if (!empty($missing_fields)) {
|
|
http_response_code(400);
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Bitte füllen Sie alle Pflichtfelder aus.',
|
|
'missing_fields' => $missing_fields,
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
$subjectKey = trim((string) $_POST['subject']);
|
|
if (!isAllowedContactSubject($subjectKey)) {
|
|
http_response_code(400);
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Bitte wählen Sie einen gültigen Betreff.',
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
$email = trim((string) $_POST['email']);
|
|
if (!isValidEmail($email)) {
|
|
http_response_code(400);
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Bitte geben Sie eine gültige E-Mail-Adresse ein.',
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
$message = trim((string) $_POST['message']);
|
|
$messageLength = mb_strlen($message, 'UTF-8');
|
|
|
|
if ($messageLength < $config['min_message_length']) {
|
|
http_response_code(400);
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Ihre Nachricht ist zu kurz.',
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
if ($messageLength > $config['max_message_length']) {
|
|
http_response_code(400);
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Ihre Nachricht ist zu lang.',
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
$data = [
|
|
'firstName' => sanitizeFormField($_POST['firstName']),
|
|
'lastName' => sanitizeFormField($_POST['lastName']),
|
|
'email' => sanitizeHeaderValue($email),
|
|
'phone' => sanitizeFormField($_POST['phone'] ?? ''),
|
|
'company' => sanitizeFormField($_POST['company'] ?? ''),
|
|
'subject' => $subjectKey,
|
|
'message' => sanitizeFormField($message),
|
|
'privacy' => isset($_POST['privacy']),
|
|
];
|
|
|
|
if (sendEmail($data)) {
|
|
if (LOG_EMAILS) {
|
|
logEmail('sent', [
|
|
'subject' => $subjectKey,
|
|
'email' => $data['email'],
|
|
'ip' => getClientIP(),
|
|
]);
|
|
}
|
|
echo json_encode([
|
|
'success' => true,
|
|
'message' => 'Ihre Nachricht wurde erfolgreich gesendet! Wir melden uns in Kürze bei Ihnen.',
|
|
]);
|
|
} else {
|
|
http_response_code(500);
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Beim Senden der Nachricht ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut.',
|
|
]);
|
|
}
|
|
} catch (Exception $e) {
|
|
error_log('HexaHost Contact Form Error: ' . $e->getMessage());
|
|
http_response_code(500);
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.',
|
|
]);
|
|
}
|