From da888e085b1c648d0fa1a87aa2e7b6bb9ae89a46 Mon Sep 17 00:00:00 2001 From: 0xA0 Date: Wed, 22 Jul 2026 11:33:23 +0200 Subject: [PATCH 1/4] moderation --- guestbook.php | 60 ++++++++++++++++++++++++++++++++++++++++++---- inc/moderation.php | 28 ++++++++++++++++++++++ 2 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 inc/moderation.php diff --git a/guestbook.php b/guestbook.php index 95ba906..df8513a 100644 --- a/guestbook.php +++ b/guestbook.php @@ -1,5 +1,6 @@ exec('CREATE TABLE IF NOT EXISTS entries ( msg TEXT NOT NULL, ts INTEGER NOT NULL )'); +$db->exec('CREATE TABLE IF NOT EXISTS ratelimit ( + ip_hash TEXT PRIMARY KEY, + last_ts INTEGER NOT NULL +)'); $isHtmx = isset($_SERVER['HTTP_HX_REQUEST']); +$notice = ''; + +function client_ip(): string { + $xff = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? ''; + if ($xff !== '') { + return trim(explode(',', $xff)[0]); + } + return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0'; +} if ($_SERVER['REQUEST_METHOD'] === 'POST') { $name = trim($_POST['name'] ?? ''); $msg = trim($_POST['msg'] ?? ''); - if ($name !== '' && $msg !== '') { - $stmt = $db->prepare('INSERT INTO entries (name, msg, ts) VALUES (?, ?, ?)'); - $stmt->execute([mb_substr($name, 0, 40), mb_substr($msg, 0, 500), time()]); + $trap = trim($_POST['url'] ?? ''); + $ok = false; + + if ($trap !== '') { + $ok = true; + } elseif ($name === '' || $msg === '') { + $notice = 'name and message are required.'; + } elseif (gb_has_link($msg)) { + $notice = 'links aren\'t allowed.'; + } else { + $ipHash = hash('sha256', client_ip() . '|guestbook'); + $now = time(); + $window = 30; + $stmt = $db->prepare('SELECT last_ts FROM ratelimit WHERE ip_hash = ?'); + $stmt->execute([$ipHash]); + $last = (int) $stmt->fetchColumn(); + + if ($last && $now - $last < $window) { + $notice = 'you\'re posting too fast — wait a moment.'; + } else { + $ins = $db->prepare('INSERT INTO entries (name, msg, ts) VALUES (?, ?, ?)'); + $ins->execute([ + gb_censor(mb_substr($name, 0, 40)), + gb_censor(mb_substr($msg, 0, 500)), + $now, + ]); + $db->prepare('INSERT INTO ratelimit (ip_hash, last_ts) VALUES (?, ?) + ON CONFLICT(ip_hash) DO UPDATE SET last_ts = excluded.last_ts') + ->execute([$ipHash, $now]); + $ok = true; + } } - if (!$isHtmx) { + + if (!$isHtmx && $ok) { header('Location: /guestbook.php'); exit; } @@ -39,6 +82,9 @@ function render_entries(iterable $rows): void { } if ($isHtmx) { + if ($notice !== '') { + echo '

' . htmlspecialchars($notice) . '

'; + } render_entries($rows); exit; } @@ -47,10 +93,16 @@ require __DIR__ . '/inc/header.php'; ?>

guestbook

+ +

+ +
+
diff --git a/inc/moderation.php b/inc/moderation.php new file mode 100644 index 0000000..34befc9 --- /dev/null +++ b/inc/moderation.php @@ -0,0 +1,28 @@ + Date: Wed, 22 Jul 2026 13:14:12 +0200 Subject: [PATCH 2/4] deployment --- .gitea/workflows/deploy.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .gitea/workflows/deploy.yml diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..bc8682b --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,24 @@ +name: Deploy +on: + push: + branches: [main] + +jobs: + deploy: + runs-on: ubuntu-latest + container: + image: node:20-bookworm + volumes: + - /mnt/deploy:/mnt/deploy + steps: + - uses: actions/checkout@v4 + + - name: Publish to docroot + run: | + find /mnt/deploy -mindepth 1 -delete + cp -R . /mnt/deploy/ + rm -rf /mnt/deploy/.git /mnt/deploy/.gitea + SHA="${{ github.sha }}" + echo "${{ github.run_number }} (${SHA:0:7})" > /mnt/deploy/build.txt + find /mnt/deploy -type d -exec chmod 755 {} + + find /mnt/deploy -type f -exec chmod 644 {} + From c5aa7ef6c398a3340a8c668e9d638ffeb5c667d2 Mon Sep 17 00:00:00 2001 From: 0xA0 Date: Wed, 22 Jul 2026 13:15:54 +0200 Subject: [PATCH 3/4] deployment2 --- .gitea/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index bc8682b..04dd8ca 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -18,7 +18,7 @@ jobs: find /mnt/deploy -mindepth 1 -delete cp -R . /mnt/deploy/ rm -rf /mnt/deploy/.git /mnt/deploy/.gitea - SHA="${{ github.sha }}" - echo "${{ github.run_number }} (${SHA:0:7})" > /mnt/deploy/build.txt + SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7) + echo "${{ github.run_number }} ($SHORT_SHA)" > /mnt/deploy/build.txt find /mnt/deploy -type d -exec chmod 755 {} + find /mnt/deploy -type f -exec chmod 644 {} + From d7071727bf2459f0bf37a3794e56c66b861918c0 Mon Sep 17 00:00:00 2001 From: 0xA0 Date: Wed, 22 Jul 2026 13:21:39 +0200 Subject: [PATCH 4/4] limit to 250 --- guestbook.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/guestbook.php b/guestbook.php index df8513a..f8ea795 100644 --- a/guestbook.php +++ b/guestbook.php @@ -53,7 +53,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $ins = $db->prepare('INSERT INTO entries (name, msg, ts) VALUES (?, ?, ?)'); $ins->execute([ gb_censor(mb_substr($name, 0, 40)), - gb_censor(mb_substr($msg, 0, 500)), + gb_censor(mb_substr($msg, 0, 250)), $now, ]); $db->prepare('INSERT INTO ratelimit (ip_hash, last_ts) VALUES (?, ?) @@ -100,7 +100,7 @@ require __DIR__ . '/inc/header.php';
- +