summaryrefslogtreecommitdiff
path: root/cgi
diff options
context:
space:
mode:
authorJonas Kohl <git@jonaskohl.de>2024-09-05 21:39:40 +0200
committerJonas Kohl <git@jonaskohl.de>2024-09-05 21:39:40 +0200
commitc6390e9bb14747de2bc894f817fc6373a7deddaf (patch)
treefe5628fc820146ecac76758865150e6c166ebfd5 /cgi
parent5d4652e6bc0009b32bfe1b1a4fc9b7431cd8fe88 (diff)
Add contact form
Diffstat (limited to 'cgi')
-rwxr-xr-xcgi/captcha.php39
-rwxr-xr-xcgi/contact.php72
2 files changed, 111 insertions, 0 deletions
diff --git a/cgi/captcha.php b/cgi/captcha.php
new file mode 100755
index 0000000..6881063
--- /dev/null
+++ b/cgi/captcha.php
@@ -0,0 +1,39 @@
+<?php
+
+use Gregwar\Captcha\CaptchaBuilder;
+
+const CAPTCHA_PHRASE_LENGTH = 7;
+
+require_once __DIR__ . "/../vendor/autoload.php";
+
+session_start();
+
+$mode = $_GET["m"] ?? "newcaptcha";
+
+if ($mode === "newcaptcha") {
+ header("Pragma: no-cache");
+ header("Cache-Control: no-cache");
+ header("Location: ?m=captcha&r=" . urldecode(bin2hex(random_bytes(10))));
+ exit;
+}
+
+$charset = 'ABCDEFGHKLMNPQRTWXYZ234789abdefghkmnpqr';
+$phrase = "";
+for ($i = 0; $i < CAPTCHA_PHRASE_LENGTH; ++$i)
+ $phrase .= $charset[random_int(0, strlen($charset) - 1)];
+
+$builder = new CaptchaBuilder($phrase);
+$builder->setInterpolation(false);
+$builder->build(256, 64);
+$_SESSION["captcha_phrase"] = $builder->getPhrase();
+
+if ($mode === "captcha") {
+ echo '<body background="?m=captchaimg&r=' . bin2hex(random_bytes(10)) . '">';
+ exit;
+}
+
+if ($mode === "captchaimg") {
+ header("Content-Type: image/jpeg");
+ $builder->save(null, 40);
+ exit;
+}
diff --git a/cgi/contact.php b/cgi/contact.php
new file mode 100755
index 0000000..c6d18d9
--- /dev/null
+++ b/cgi/contact.php
@@ -0,0 +1,72 @@
+<?php
+
+use Symfony\Component\Mailer\Transport;
+use Symfony\Component\Mime\Address;
+use Symfony\Component\Mime\Email;
+
+session_start();
+
+function missing_field(string $name): never {
+ http_response_code(400);
+ echo "Missing or malformed field $name\n";
+ exit;
+}
+
+function getenv_or_fail(string $key): ?string {
+ $value = getenv($key);
+ if ($value !== false)
+ return $value;
+ http_response_code(500);
+ echo "Missing environment variable $key\n";
+ exit;
+}
+
+if ($_SERVER["REQUEST_METHOD"] !== "POST") {
+ http_response_code(405);
+ echo "Invalid request method!\n";
+ exit;
+}
+
+$name = $_POST["name"] ?? missing_field("name");
+if (empty($name) || strlen($name) > 128)
+ missing_field("name");
+
+$email = $_POST["email"] ?? missing_field("email");
+if (empty($email) || strlen($email) > 128 || !str_contains($email, "@"))
+ missing_field("email");
+
+$subject = $_POST["subject"] ?? missing_field("subject");
+if (empty($email) || strlen($subject) > 256)
+ missing_field("subject");
+
+$message = $_POST["message"] ?? missing_field("message");
+if (empty($email) || strlen($message) > 16384)
+ missing_field("message");
+
+$captcha = $_POST["captcha"] ?? missing_field("captcha");
+if (empty($email) || strlen($captcha) > 7)
+ missing_field("captcha");
+
+$expected_captcha = $_SESSION["captcha_phrase"] ?? null;
+
+if ($captcha !== $expected_captcha) {
+ http_response_code(400);
+ echo "Ung&uuml;ltiges CAPTCHA!";
+ exit;
+}
+
+require_once __DIR__ . "/../vendor/autoload.php";
+
+$mailer_dsn = getenv_or_fail("MAILER_DSN");
+
+$transport = Transport::fromDsn($mailer_dsn);
+
+$transport->send((new Email())
+ ->from(new Address("mystic-contactform+no-reply@jonaskohl.de", $name))
+ ->to("mystic@jonaskohl.de")
+ ->replyTo(new Address($email, $name))
+ ->subject("[Mystic House Corner] $subject")
+ ->text($message)
+);
+
+header("Location: /pages/sent.html");