Files

3.4 KiB

Guestbook — Implementation Notes

Architecture summary

The guestbook extends the Astro site with hybrid SSR mode using the @astrojs/node standalone adapter.

  • Existing content pages remain static.
  • Guestbook and admin pages are server-rendered (export const prerender = false).
  • API routes handle submissions, moderation, and token-based admin login.
  • SQLite (better-sqlite3) stores entries, sessions, rate-limit data, and audit logs.

Relevant files

src/
  lib/
    db.ts                  — SQLite singleton + schema
    guestbook.ts           — Entry CRUD, pagination, moderation reads
    auth.ts                — Session management + cookie policy
    spam.ts                — Validation + heuristic spam scoring
  pages/
    guestbook.astro        — Public guestbook page
    admin/
      index.astro          — Moderation portal (session-gated)
      login.astro          — Token login form
  pages/api/
    guestbook/submit.ts    — POST: public guestbook submission
    admin/token-login.ts   — POST: token authentication + session creation
    admin/moderate.ts      — POST: approve / reject / spam
    admin/logout.ts        — POST: end admin session
  layouts/
    AdminLayout.astro      — Minimal admin UI layout

Environment variables

Copy .env.example to .env and set:

Variable Required Description
SECRET_KEY Yes Random secret for IP-hash salting and session-related values
ADMIN_SECRET_TOKEN Yes Shared secret token for /admin/login
COOKIE_SECURE No Force secure cookies (true/false). If unset, NODE_ENV=production => secure cookies
DB_PATH No SQLite path (default: ./data/guestbook.db)
PORT No Server port (default: 3000)
HOST No Bind host (default: 0.0.0.0)

Generate secrets:

openssl rand -hex 32   # SECRET_KEY
openssl rand -hex 32   # ADMIN_SECRET_TOKEN

Admin setup

  1. Set ADMIN_SECRET_TOKEN in your environment.
  2. Open /admin/login.
  3. Enter token.
  4. After success, you are redirected to /admin.

If token is missing, /admin/login shows a configuration warning and login is disabled.

Local development

npm install
cp .env.example .env
# set at minimum:
# SECRET_KEY=...
# ADMIN_SECRET_TOKEN=...
# DB_PATH=./data/guestbook.db
# COOKIE_SECURE=false   # for local http

npm run dev
# guestbook: http://localhost:4321/guestbook
# admin:     http://localhost:4321/admin/login

Docker deployment

docker compose up -d --build
docker compose logs -f cozy-den

The guestbook_data Docker volume persists the SQLite database.

Moderation flow

  1. Visitor submits message at /guestbook.
  2. Entry is saved as pending.
  3. Admin logs in at /admin/login with token.
  4. Admin approves/rejects/marks spam in /admin.
  5. Approved entries are shown publicly.

Privacy decisions

  • IP addresses are never stored directly.
  • A truncated salted hash is stored only for rate limiting.
  • No tracking scripts or third-party analytics.
  • Admin session cookie is httpOnly and SameSite=Strict.
  • User content is stored as plain text (HTML stripped server-side).

Database tables

Table Purpose
guestbook_entries Submissions + moderation status
admin_sessions Active admin sessions
rate_limit Submission throttling by IP hash
audit_log Moderation actions