Initial commit: Frida-Fred Webseite
This commit is contained in:
19
api/.htaccess
Normal file
19
api/.htaccess
Normal file
@@ -0,0 +1,19 @@
|
||||
# Verhindere direkten Zugriff auf config.php
|
||||
<Files "config.php">
|
||||
Order Allow,Deny
|
||||
Deny from all
|
||||
</Files>
|
||||
|
||||
# Verhindere direkten Zugriff auf send-mail.php via GET
|
||||
<Files "send-mail.php">
|
||||
<Limit GET>
|
||||
Order Allow,Deny
|
||||
Deny from all
|
||||
</Limit>
|
||||
</Files>
|
||||
|
||||
# Verstecke sensible Dateien
|
||||
<FilesMatch "^(config\.php|config\.php\.example|\..*|composer\..*)">
|
||||
Order Allow,Deny
|
||||
Deny from all
|
||||
</FilesMatch>
|
||||
27
api/config.php.example
Normal file
27
api/config.php.example
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Konfigurationsdatei VORLAGE für Frida & Fred Kontaktformular
|
||||
*
|
||||
* ANLEITUNG:
|
||||
* 1. Kopiere diese Datei und benenne sie in "config.php" um
|
||||
* 2. Trage deine echten SMTP-Zugangsdaten ein
|
||||
* 3. config.php wird automatisch von Git ignoriert (.gitignore)
|
||||
*/
|
||||
|
||||
// SMTP-Konfiguration
|
||||
define('SMTP_HOST', 'mail.webfarben.net'); // SMTP-Server
|
||||
define('SMTP_PORT', 587); // Port (587 für TLS, 465 für SSL)
|
||||
define('SMTP_USERNAME', 'frida@webfarben.net'); // SMTP-Benutzername
|
||||
define('SMTP_PASSWORD', 'DEIN_PASSWORT_HIER'); // ← PASSWORT HIER EINTRAGEN
|
||||
define('SMTP_SECURE', 'tls'); // Verschlüsselung: 'tls' oder 'ssl'
|
||||
define('SMTP_FROM_EMAIL', 'frida@webfarben.net'); // Absender-E-Mail
|
||||
define('SMTP_FROM_NAME', 'Frida & Fred Kontaktformular'); // Absender-Name
|
||||
|
||||
// Empfänger
|
||||
define('RECIPIENT_EMAIL', 'frida@webfarben.net'); // Empfänger der Kontaktanfragen
|
||||
define('RECIPIENT_NAME', 'Frida & Fred'); // Name des Empfängers
|
||||
|
||||
// Weitere Einstellungen
|
||||
define('FORM_NAME', 'Frida & Fred Kontaktformular');
|
||||
define('RATE_LIMIT_SECONDS', 60); // Max. 1 Nachricht pro Minute
|
||||
define('MAX_MESSAGE_LENGTH', 5000);
|
||||
285
api/send-mail.php
Normal file
285
api/send-mail.php
Normal file
@@ -0,0 +1,285 @@
|
||||
<?php
|
||||
/**
|
||||
* Kontaktformular Mailer für Frida & Fred
|
||||
* SMTP E-Mail-Versand mit Spam-Schutz und Validierung
|
||||
*/
|
||||
|
||||
// Output Buffering aktivieren, um saubere JSON-Antwort zu gewährleisten
|
||||
ob_start();
|
||||
|
||||
// Fehleranzeige für Debugging (in Produktion ausschalten)
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 0); // Wichtig: Fehler nicht direkt ausgeben
|
||||
ini_set('log_errors', 1);
|
||||
|
||||
// PHPMailer laden
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use PHPMailer\PHPMailer\SMTP;
|
||||
use PHPMailer\PHPMailer\Exception;
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
// Output Buffer leeren vor Session-Start
|
||||
ob_clean();
|
||||
|
||||
// Session starten für Rate-Limiting
|
||||
session_start();
|
||||
|
||||
// Konfiguration laden
|
||||
if (!file_exists(__DIR__ . '/config.php')) {
|
||||
ob_clean();
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Konfigurationsfehler. Bitte kontaktieren Sie den Administrator.'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
require_once __DIR__ . '/config.php';
|
||||
|
||||
// Header für JSON-Response setzen
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
// Nur POST-Requests erlauben
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
ob_clean();
|
||||
http_response_code(405);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Nur POST-Requests erlaubt.'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rate-Limiting prüfen
|
||||
*/
|
||||
function checkRateLimit() {
|
||||
if (isset($_SESSION['last_submission'])) {
|
||||
$timeSinceLastSubmit = time() - $_SESSION['last_submission'];
|
||||
if ($timeSinceLastSubmit < RATE_LIMIT_SECONDS) {
|
||||
return [
|
||||
'allowed' => false,
|
||||
'wait_time' => RATE_LIMIT_SECONDS - $timeSinceLastSubmit
|
||||
];
|
||||
}
|
||||
}
|
||||
return ['allowed' => true];
|
||||
}
|
||||
|
||||
/**
|
||||
* Eingabe bereinigen und validieren
|
||||
*/
|
||||
function sanitizeInput($data) {
|
||||
$data = trim($data);
|
||||
$data = stripslashes($data);
|
||||
$data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* E-Mail-Adresse validieren
|
||||
*/
|
||||
function validateEmail($email) {
|
||||
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* CSRF-Token validieren (einfache Implementierung)
|
||||
*/
|
||||
function validateCSRF($token) {
|
||||
// Erwarteter Token-Wert (sollte mit dem im Formular übereinstimmen)
|
||||
return $token === 'frida-fred-csrf-2026';
|
||||
}
|
||||
|
||||
// Rate-Limiting prüfen
|
||||
$rateLimitCheck = checkRateLimit();
|
||||
if (!$rateLimitCheck['allowed']) {
|
||||
ob_clean();
|
||||
http_response_code(429);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Bitte warten Sie ' . $rateLimitCheck['wait_time'] . ' Sekunden, bevor Sie erneut eine Nachricht senden.'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Honeypot-Feld prüfen (sollte leer sein)
|
||||
if (!empty($_POST['website'])) {
|
||||
ob_clean();
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Spam erkannt.'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// CSRF-Token prüfen
|
||||
if (!isset($_POST['csrf_token']) || !validateCSRF($_POST['csrf_token'])) {
|
||||
ob_clean();
|
||||
http_response_code(403);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Ungültiger Sicherheitstoken.'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Formularfelder auslesen und validieren
|
||||
$name = isset($_POST['name']) ? sanitizeInput($_POST['name']) : '';
|
||||
$email = isset($_POST['email']) ? sanitizeInput($_POST['email']) : '';
|
||||
$subject = isset($_POST['subject']) ? sanitizeInput($_POST['subject']) : '';
|
||||
$message = isset($_POST['message']) ? sanitizeInput($_POST['message']) : '';
|
||||
|
||||
// Pflichtfelder prüfen
|
||||
if (empty($name) || empty($email) || empty($subject) || empty($message)) {
|
||||
ob_clean();
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Bitte füllen Sie alle erforderlichen Felder aus.'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// E-Mail-Adresse validieren
|
||||
if (!validateEmail($email)) {
|
||||
ob_clean();
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Bitte geben Sie eine gültige E-Mail-Adresse ein.'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Nachrichtenlänge prüfen
|
||||
if (strlen($message) > MAX_MESSAGE_LENGTH) {
|
||||
ob_clean();
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Ihre Nachricht ist zu lang. Maximal ' . MAX_MESSAGE_LENGTH . ' Zeichen erlaubt.'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// E-Mail-Inhalt erstellen
|
||||
$emailSubject = 'Kontaktanfrage: ' . $subject;
|
||||
$emailBodyText = "Neue Kontaktanfrage über " . FORM_NAME . "\n\n";
|
||||
$emailBodyText .= "Name: " . $name . "\n";
|
||||
$emailBodyText .= "E-Mail: " . $email . "\n";
|
||||
$emailBodyText .= "Betreff: " . $subject . "\n\n";
|
||||
$emailBodyText .= "Nachricht:\n" . $message . "\n\n";
|
||||
$emailBodyText .= "---\n";
|
||||
$emailBodyText .= "Gesendet am: " . date('d.m.Y H:i:s') . "\n";
|
||||
$emailBodyText .= "IP-Adresse: " . $_SERVER['REMOTE_ADDR'] . "\n";
|
||||
|
||||
// HTML-Version der E-Mail
|
||||
$emailBodyHTML = '
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
|
||||
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
|
||||
.header { background-color: #C4B5A0; color: white; padding: 20px; text-align: center; }
|
||||
.content { background-color: #f8f7f4; padding: 20px; margin-top: 20px; }
|
||||
.field { margin-bottom: 15px; }
|
||||
.label { font-weight: bold; color: #2c2c2c; }
|
||||
.footer { margin-top: 20px; padding-top: 20px; border-top: 1px solid #ddd; font-size: 12px; color: #666; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h2>Neue Kontaktanfrage</h2>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="field">
|
||||
<span class="label">Von:</span> ' . htmlspecialchars($name) . '
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">E-Mail:</span> <a href="mailto:' . htmlspecialchars($email) . '">' . htmlspecialchars($email) . '</a>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">Betreff:</span> ' . htmlspecialchars($subject) . '
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">Nachricht:</span><br>
|
||||
' . nl2br(htmlspecialchars($message)) . '
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
Gesendet am: ' . date('d.m.Y H:i:s') . '<br>
|
||||
IP-Adresse: ' . $_SERVER['REMOTE_ADDR'] . '
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
';
|
||||
|
||||
// PHPMailer-Instanz erstellen
|
||||
$mail = new PHPMailer(true);
|
||||
|
||||
try {
|
||||
// SMTP-Konfiguration
|
||||
$mail->isSMTP();
|
||||
$mail->Host = SMTP_HOST;
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = SMTP_USERNAME;
|
||||
$mail->Password = SMTP_PASSWORD;
|
||||
$mail->SMTPSecure = SMTP_SECURE;
|
||||
$mail->Port = SMTP_PORT;
|
||||
$mail->CharSet = 'UTF-8';
|
||||
|
||||
// Debug-Ausgabe deaktivieren (für Produktion)
|
||||
$mail->SMTPDebug = 0;
|
||||
$mail->Debugoutput = function($str, $level) {
|
||||
// Debug-Ausgaben unterdrücken
|
||||
};
|
||||
|
||||
// Absender
|
||||
$mail->setFrom(SMTP_FROM_EMAIL, SMTP_FROM_NAME);
|
||||
$mail->addReplyTo($email, $name);
|
||||
|
||||
// Empfänger
|
||||
$mail->addAddress(RECIPIENT_EMAIL, RECIPIENT_NAME);
|
||||
|
||||
// E-Mail-Inhalt
|
||||
$mail->isHTML(true);
|
||||
$mail->Subject = $emailSubject;
|
||||
$mail->Body = $emailBodyHTML;
|
||||
$mail->AltBody = $emailBodyText;
|
||||
|
||||
// E-Mail senden
|
||||
$mail->send();
|
||||
|
||||
// Zeitstempel für Rate-Limiting speichern
|
||||
$_SESSION['last_submission'] = time();
|
||||
|
||||
// Output Buffer leeren
|
||||
ob_clean();
|
||||
|
||||
http_response_code(200);
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => 'Vielen Dank! Ihre Nachricht wurde erfolgreich versendet. Wir werden uns bald bei Ihnen melden.'
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
// Fehler beim E-Mail-Versand
|
||||
// Output Buffer leeren
|
||||
ob_clean();
|
||||
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Es gab ein Problem beim Senden Ihrer Nachricht. Bitte versuchen Sie es später erneut oder kontaktieren Sie uns direkt per E-Mail.'
|
||||
// 'error' => $mail->ErrorInfo // Nur für Debugging aktivieren!
|
||||
]);
|
||||
}
|
||||
|
||||
exit;
|
||||
Reference in New Issue
Block a user