diff --git a/data/.htaccess b/data/.htaccess new file mode 100644 index 0000000..3a42882 --- /dev/null +++ b/data/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/index.html b/index.html index 975a8db..09c507c 100644 --- a/index.html +++ b/index.html @@ -198,6 +198,9 @@

Täytä lomake ja selvitämme valokuidun saatavuuden osoitteessasi. Vastaamme yleensä 1–2 arkipäivän kuluessa. Kysely ei velvoita mihinkään.

+
+ +
@@ -259,5 +262,48 @@
+ diff --git a/send.php b/send.php new file mode 100644 index 0000000..11b82b7 --- /dev/null +++ b/send.php @@ -0,0 +1,100 @@ + false, 'error' => 'Virheellinen pyyntö']); + exit; +} + +// Rate limiting (yksinkertainen, IP-pohjainen) +$rateLimitDir = __DIR__ . '/data'; +if (!is_dir($rateLimitDir)) { + mkdir($rateLimitDir, 0755, true); +} +$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown'; +$rateLimitFile = $rateLimitDir . '/ratelimit_' . md5($ip) . '.txt'; +$now = time(); +if (file_exists($rateLimitFile)) { + $lastSent = (int) file_get_contents($rateLimitFile); + if ($now - $lastSent < 60) { + http_response_code(429); + echo json_encode(['success' => false, 'error' => 'Odota hetki ennen uutta lähetystä']); + exit; + } +} + +// Honeypot-kenttä (botisuoja) +if (!empty($_POST['website'])) { + http_response_code(200); + echo json_encode(['success' => true]); + exit; +} + +// Kentät +$company = trim($_POST['company'] ?? ''); +$email = trim($_POST['email'] ?? ''); +$address = trim($_POST['address'] ?? ''); +$city = trim($_POST['city'] ?? ''); +$message = trim($_POST['message'] ?? ''); + +// Validointi +if (empty($company) || empty($email) || empty($address) || empty($city)) { + http_response_code(400); + echo json_encode(['success' => false, 'error' => 'Täytä kaikki pakolliset kentät']); + exit; +} + +if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + http_response_code(400); + echo json_encode(['success' => false, 'error' => 'Tarkista sähköpostiosoite']); + exit; +} + +// Sanitointi +$company = htmlspecialchars($company, ENT_QUOTES, 'UTF-8'); +$email = htmlspecialchars($email, ENT_QUOTES, 'UTF-8'); +$address = htmlspecialchars($address, ENT_QUOTES, 'UTF-8'); +$city = htmlspecialchars($city, ENT_QUOTES, 'UTF-8'); +$message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8'); + +// Sähköpostin sisältö +$to = 'asiakaspalvelu@cuitunet.fi'; +$subject = "Saatavuuskysely: $company – $address, $city"; + +$body = "Uusi saatavuuskysely cuitunet.fi-sivustolta\n"; +$body .= "=========================================\n\n"; +$body .= "Yritys: $company\n"; +$body .= "Sähköposti: $email\n"; +$body .= "Osoite: $address\n"; +$body .= "Kaupunki: $city\n"; +if (!empty($message)) { + $body .= "Lisätiedot: $message\n"; +} +$body .= "\n-----------------------------------------\n"; +$body .= "Lähetetty: " . date('d.m.Y H:i') . "\n"; +$body .= "IP: $ip\n"; + +$headers = "From: sivusto@cuitunet.fi\r\n"; +$headers .= "Reply-To: $email\r\n"; +$headers .= "Content-Type: text/plain; charset=UTF-8\r\n"; +$headers .= "X-Mailer: Cuitunet-Web\r\n"; + +// Lähetys +$sent = mail($to, $subject, $body, $headers); + +if ($sent) { + // Tallenna rate limit + file_put_contents($rateLimitFile, $now); + + // Tallenna kopio kyselyistä + $logFile = $rateLimitDir . '/kyselyt.log'; + $logEntry = date('Y-m-d H:i:s') . " | $company | $email | $address, $city | $message\n"; + file_put_contents($logFile, $logEntry, FILE_APPEND | LOCK_EX); + + echo json_encode(['success' => true]); +} else { + http_response_code(500); + echo json_encode(['success' => false, 'error' => 'Viestin lähetys epäonnistui. Yritä myöhemmin uudelleen.']); +}