3.4 KiB
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
- Set
ADMIN_SECRET_TOKENin your environment. - Open
/admin/login. - Enter token.
- 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
- Visitor submits message at
/guestbook. - Entry is saved as
pending. - Admin logs in at
/admin/loginwith token. - Admin approves/rejects/marks spam in
/admin. - 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
httpOnlyandSameSite=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 |