Files
Bonchellon 3954082e8d v0.3.2 — commit/submit progress, cancel, thumbnails, waitlist landing+admin
Client:
- Commit: batch `p4 reopen` so huge changelists (63k+) no longer blow the
  Windows command-line limit; live "N / total" progress + spinner during commit.
- Submit dialog: white arrow, "N of total" + % bar, running file log,
  Cancel button (aborts pre-commit; changelist stays pending).
- Disk scan: streaming reconcile with a live "found N files" counter + Cancel.
- Thumbnails: only decode browser-renderable image formats; glyph fallback
  (+ onError) instead of a broken-image icon for bmp/tga/dds/etc.

Landing + waitlist:
- waitlist-server: Express + SQLite email collector (dedup) with a secure
  admin panel (scrypt auth, rate-limited login, signed cookies) and CSV export.
- landing form now POSTs signups to the waitlist API.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 20:40:53 +03:00

2.1 KiB

Exbyte Depot — Waitlist server + admin

Collects waitlist emails from the landing page (deduplicated) and gives you a password-protected admin panel to browse them and export to CSV.

Stack

  • express — HTTP + static landing
  • better-sqlite3 — storage; UNIQUE COLLATE NOCASE on email → no duplicates, ever
  • express-rate-limit — brute-force protection on the login endpoint
  • node:crypto — scrypt password hashing + HMAC-signed session cookies (no extra deps)

Setup

cd waitlist-server
npm install

cp .env.example .env
npm run gen-secret        # → paste into SESSION_SECRET in .env
npm run set-password      # type a password → paste the ADMIN_PASS_HASH line into .env
# set ADMIN_USER in .env (default: admin)

npm start

How it works

  • The landing form POSTs { email } to POST /api/waitlist.
    • Invalid emails are rejected; a repeat email is silently deduped (no dup row).
    • A hidden honeypot field (website) traps bots.
  • /admin requires login. Session is a signed, HttpOnly, SameSite=Strict cookie (Secure in production), valid 8h. Wrong logins are rate-limited (8 / 15 min / IP).
  • Export CSV: GET /admin/export.csv streams all signups (UTF-8 + BOM for Excel).

Security notes

  • No plaintext password anywhere — only a scrypt hash in .env (git-ignored).
  • Refuses to start without ADMIN_USER, ADMIN_PASS_HASH, and a strong SESSION_SECRET.
  • Security headers set (CSP, X-Frame-Options: DENY, nosniff, no-referrer).
  • Behind a reverse proxy, set TRUST_PROXY=1 so rate-limiting and stored IPs are correct, and terminate TLS at the proxy (cookies become Secure when NODE_ENV=production).

Deploy (Linux VPS, sketch)

  1. NODE_ENV=production, real .env, npm ci --omit=dev.
  2. Run under systemd (or pm2); put nginx/Caddy in front for TLS + TRUST_PROXY=1.
  3. Point your domain at it; the landing is served from ../landing (or set LANDING_DIR).

Data

SQLite file at data/waitlist.db (git-ignored). Back it up to keep your list.