innhold/content/kontakt/01-kontaktskjema.php
Ruben 6682e94798 Remove redundant article container and extra whitespace
Remove unnecessary closing article tags and extra whitespace
2026-01-14 23:15:43 +01:00

274 lines
11 KiB
PHP

<?php
// Contact form processing with spam prevention
$formSubmitted = false;
$formSuccess = false;
$formErrors = [];
$formData = ['name' => '', 'email' => '', 'message' => ''];
// Start session for CSRF token and rate limiting
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// Generate CSRF token if not exists
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// Process form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['contact_form_submit'])) {
$formSubmitted = true;
// Security: CSRF Token Validation
if (!isset($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
$formErrors[] = 'Ugyldig sikkerhetskode. Vennligst prøv igjen.';
}
// Spam Prevention 1: Honeypot field (should be empty)
if (!empty($_POST['website'])) {
$formErrors[] = 'Spam detected.';
}
// Spam Prevention 2: Time-based check (form must be visible for at least 3 seconds)
$formStartTime = isset($_POST['form_start_time']) ? (int)$_POST['form_start_time'] : 0;
$timeDiff = time() - $formStartTime;
if ($timeDiff < 3) {
$formErrors[] = 'Form submitted too quickly.';
}
// Spam Prevention 3: Referrer check (only if referrer is present and clearly from different domain)
if (!empty($_SERVER['HTTP_REFERER'])) {
$referrer = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
$currentHost = $_SERVER['HTTP_HOST'];
// Only block if referrer exists and doesn't match (allows empty referrer for privacy browsers)
if ($referrer && $referrer !== $currentHost && $referrer !== 'localhost') {
$formErrors[] = 'Invalid form submission.';
}
}
// Spam Prevention 4: Rate limiting (session-based)
$lastSubmitTime = isset($_SESSION['last_contact_submit']) ? $_SESSION['last_contact_submit'] : 0;
if (time() - $lastSubmitTime < 60) {
$formErrors[] = 'Vennligst vent litt før du sender inn igjen.';
}
// Get and sanitize form data
$formData['name'] = trim($_POST['name'] ?? '');
$formData['email'] = trim($_POST['email'] ?? '');
// Normalize line endings in message (convert \r\n to \n)
$formData['message'] = trim(str_replace("\r\n", "\n", $_POST['message'] ?? ''));
// Validation
if (empty($formData['name'])) {
$formErrors[] = 'Vennligst oppgi navn.';
} elseif (strlen($formData['name']) > 100) {
$formErrors[] = 'Navnet er for langt.';
}
if (empty($formData['email'])) {
$formErrors[] = 'Vennligst oppgi e-postadresse.';
} elseif (!filter_var($formData['email'], FILTER_VALIDATE_EMAIL)) {
$formErrors[] = 'Ugyldig e-postadresse.';
} elseif (strlen($formData['email']) > 100) {
$formErrors[] = 'E-postadressen er for lang.';
}
if (empty($formData['message'])) {
$formErrors[] = 'Vennligst skriv en melding.';
} elseif (strlen($formData['message']) < 10) {
$formErrors[] = 'Meldingen er for kort (minimum 10 tegn).';
} elseif (strlen($formData['message']) > 5000) {
$formErrors[] = 'Meldingen er for lang (maksimum 5000 tegn).';
}
// Spam Prevention 5: Check for suspicious patterns
$spamPatterns = [
'/\[url=/i',
'/\[link=/i',
'/<a href=/i',
'/viagra|cialis|casino|poker|lottery/i',
'/http.*http.*http/i', // Multiple URLs
];
$fullText = $formData['name'] . ' ' . $formData['email'] . ' ' . $formData['message'];
foreach ($spamPatterns as $pattern) {
if (preg_match($pattern, $fullText)) {
$formErrors[] = 'Meldingen inneholder ikke tillatt innhold.';
break;
}
}
// If no errors, send email
if (empty($formErrors)) {
// Load SMTP configuration
$smtpConfig = require __DIR__ . '/../../custom/smtp-config.php';
// Prepare email body
$emailBody = "Ny henvendelse fra kontaktskjemaet på stopplidelsen.no\n\n";
$emailBody .= "Navn: " . $formData['name'] . "\n";
$emailBody .= "E-post: " . $formData['email'] . "\n";
$emailBody .= "IP-adresse: " . $_SERVER['REMOTE_ADDR'] . "\n";
$emailBody .= "Tidspunkt: " . date('Y-m-d H:i:s') . "\n\n";
$emailBody .= "Melding:\n" . $formData['message'] . "\n";
$mailSent = false;
// Try PHPMailer.Lite if SMTP is configured
if ($smtpConfig['enabled']) {
// Pre-flight check: Test SMTP connection before attempting to send
$smtpConnectable = false;
$fp = @fsockopen($smtpConfig['host'], $smtpConfig['port'], $errno, $errstr, 10);
if ($fp) {
// Successfully connected
$smtpConnectable = true;
fclose($fp);
} else {
error_log("SMTP Pre-flight check failed: Cannot connect to {$smtpConfig['host']}:{$smtpConfig['port']} - Error: $errno - $errstr");
$formErrors[] = 'Det oppstod en feil ved sending av meldingen. Vennligst prøv igjen senere.';
}
if ($smtpConnectable) {
try {
require_once __DIR__ . '/../../custom/vendor/PHPMailer.Lite.php';
$mail = new \codeworxtech\PHPMailerLite\PHPMailerLite();
// Enable debug output in development
// $mail->debug = 1; // Uncomment to see SMTP debug output
$mail->SetSMTPhost($smtpConfig['host']);
$mail->SetSMTPport($smtpConfig['port']);
$mail->SetSMTPuser($smtpConfig['username']);
$mail->SetSMTPpass($smtpConfig['password']);
$mail->SetSender([$smtpConfig['from_email'] => $smtpConfig['from_name']]);
$mail->AddRecipient([$smtpConfig['to_email'] => $smtpConfig['to_name']]);
$mail->AddReplyTo([$formData['email'] => $formData['name']]);
$mail->SetSubject('Ny henvendelse fra kontaktskjema');
$mail->SetBodyText($emailBody);
// Capture any output from PHPMailer.Lite (it might exit() on error)
ob_start();
$mailSent = @$mail->Send('smtp');
$smtpOutput = ob_get_clean();
// Check if there was an error in the output
if (!$mailSent || stripos($smtpOutput, 'error') !== false || stripos($smtpOutput, '&#10007;') !== false) {
$mailSent = false;
error_log("SMTP Send failed. Output: " . strip_tags($smtpOutput));
$formErrors[] = 'Det oppstod en feil ved sending av meldingen. Vennligst prøv igjen senere.';
}
} catch (\Exception $e) {
$mailSent = false;
error_log("PHPMailer Exception: " . $e->getMessage());
$formErrors[] = 'Det oppstod en feil ved sending av meldingen. Vennligst prøv igjen senere.';
}
}
} else {
// Fallback to native mail() function
$headers = "From: kontaktskjema@stopplidelsen.no\r\n";
$headers .= "Reply-To: " . $formData['email'] . "\r\n";
$headers .= "X-Mailer: PHP/" . phpversion() . "\r\n";
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
$mailSent = mail('ruben@stopplidelsen.no', 'Ny henvendelse fra kontaktskjema', $emailBody, $headers);
}
if ($mailSent) {
$formSuccess = true;
$_SESSION['last_contact_submit'] = time();
// Clear form data on success
$formData = ['name' => '', 'email' => '', 'message' => ''];
} else {
if (empty($formErrors)) {
$formErrors[] = 'Det oppstod en feil ved sending av meldingen. Vennligst prøv igjen senere.';
}
}
}
}
// Generate form start time token
$currentTime = time();
?>
<h2>Kontaktskjema</h2>
<p>Har du spørsmål, innspill eller ønsker å delta i arbeidet vårt? Fyll ut skjemaet nedenfor! Men husk at det kan ta tid før du får svar, vi er ikke så mange og driver alt på frivillig basis.</p>
<section class="contact-form">
<?php if ($formSuccess): ?>
<div class="form-success">
<p><strong>Takk for din henvendelse!</strong></p>
<p>Vi har mottatt meldingen din og vil svare så snart som mulig.</p>
</div>
<?php endif; ?>
<?php if (!empty($formErrors)): ?>
<div class="form-errors">
<p><strong>Vennligst rett opp følgende:</strong></p>
<ul>
<?php foreach ($formErrors as $error): ?>
<li><?= htmlspecialchars($error) ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<?php if (!$formSuccess): ?>
<form method="post" action="<?= htmlspecialchars($_SERVER['REQUEST_URI']) ?>" class="contact-form-inner">
<!-- Honeypot field (hidden from users, bots will fill it) -->
<div class="hp-field" aria-hidden="true">
<label for="website">Website</label>
<input type="text" id="website" name="website" tabindex="-1" autocomplete="off">
</div>
<!-- CSRF Token -->
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<!-- Time-based token -->
<input type="hidden" name="form_start_time" value="<?= $currentTime ?>">
<div class="form-group">
<label for="contact_name">Navn <span class="required">*</span></label>
<input
type="text"
id="contact_name"
name="name"
value="<?= htmlspecialchars($formData['name']) ?>"
required
maxlength="100"
>
</div>
<div class="form-group">
<label for="contact_email">E-postadresse <span class="required">*</span></label>
<input
type="email"
id="contact_email"
name="email"
value="<?= htmlspecialchars($formData['email']) ?>"
required
maxlength="100"
>
</div>
<div class="form-group">
<label for="contact_message">Melding <span class="required">*</span></label>
<textarea
id="contact_message"
name="message"
rows="8"
required
minlength="10"
maxlength="5000"
><?= htmlspecialchars($formData['message']) ?></textarea>
<small>Minimum 10 tegn, maksimum 5000 tegn.</small>
</div>
<div class="form-group">
<button type="submit" name="contact_form_submit" class="button">Send melding</button>
</div>
</form>
<?php endif; ?>
</section>