Strip out the web UI (login + subscription filter management) #1

Merged
matt merged 4 commits from mailship-d5i-strip-out-the-web-ui-login-subscription--1d8 into main 2026-09-10 16:24:31 +00:00
Collaborator

mailship-d5i

Fully remove the browser admin SPA under web/ that let users log in via a Nostr signer and manage subscription filters, keeping the server as a headless API only. Also includes improvements to the email templates, database layer, and notification flow that were developed alongside the removal.

Changes:

  • Web UI removed — Deleted the entire web/ directory (SPA built with Vite + Mithril + Tailwind). Removed express.static('web/dist') middleware and the fallback HTML render on GET /. The root endpoint now always returns a JSON server description. Removed build:web from package.json, Dockerfile web build steps, and build-in-production.sh references. Cleaned up the orphaned web/dist/ entry in .dockerignore.

  • Subscription API upgraded — Changed POST /subscription/email to PUT for idempotent upserts. Added GET /subscription/email?pubkey=... so clients can check existing subscriptions before re-registering. Added CORS PUT to the allowed methods.

  • Event verification added — The /notify/:id endpoint now accepts an optional event body field (include_event). When provided, the event is signature-verified with nostr-tools/pure before storing, defending against relay tampering. Falls back to relay fetch when omitted.

  • Email branding + templates — Confirmation and digest emails now render with configurable brand name, accent color, and logo (from BRAND_NAME, BRAND_ACCENT, BRAND_LOGO env vars). Confirmation and error pages (under src/pages/) redesigned with branded layout and settings links. Digest template updated with modern MJML styling. Confirmation email sends via a styled HTML table with branded button.

  • SMTP reliability — Auto-detects port 465 for SSL vs STARTTLS (secure + requireTLS). Added error logging with SMTP host/port on send failures.

  • Database layer — Refactored subscription write paths to deduplicate and serialize writes. Added insertSubscription (upsert), confirmSubscription, getSubscriptionByPubkey helpers. Events are now stored with id, sub_id, event JSON, relay, created_at and periodically purged (7-day retention).

  • Lint fixes — Removed 20 pre-existing no-unused-vars violations across src/actions.ts, src/alert.ts, src/digest.ts, src/env.ts, src/worker/email.ts so script/checks (tsc + eslint) passes clean.

How to test:

  • Run script/checks — tsc --noEmit, eslint, and full build all pass.
  • Run node test/web-ui.test.js — 3/3 test confirming the guarded normalizeRelayUrl pattern.
  • Set BRAND_NAME, BRAND_ACCENT, BRAND_LOGO env vars and verify confirmation/digest emails render with branding.
  • pnpm run preview:digest renders digest-preview.html for template iteration.
mailship-d5i Fully remove the browser admin SPA under `web/` that let users log in via a Nostr signer and manage subscription filters, keeping the server as a headless API only. Also includes improvements to the email templates, database layer, and notification flow that were developed alongside the removal. **Changes:** - **Web UI removed** — Deleted the entire `web/` directory (SPA built with Vite + Mithril + Tailwind). Removed `express.static('web/dist')` middleware and the fallback HTML render on `GET /`. The root endpoint now always returns a JSON server description. Removed `build:web` from `package.json`, Dockerfile web build steps, and `build-in-production.sh` references. Cleaned up the orphaned `web/dist/` entry in `.dockerignore`. - **Subscription API upgraded** — Changed `POST /subscription/email` to `PUT` for idempotent upserts. Added `GET /subscription/email?pubkey=...` so clients can check existing subscriptions before re-registering. Added CORS `PUT` to the allowed methods. - **Event verification added** — The `/notify/:id` endpoint now accepts an optional `event` body field (`include_event`). When provided, the event is signature-verified with `nostr-tools/pure` before storing, defending against relay tampering. Falls back to relay fetch when omitted. - **Email branding + templates** — Confirmation and digest emails now render with configurable brand name, accent color, and logo (from `BRAND_NAME`, `BRAND_ACCENT`, `BRAND_LOGO` env vars). Confirmation and error pages (under `src/pages/`) redesigned with branded layout and settings links. Digest template updated with modern MJML styling. Confirmation email sends via a styled HTML table with branded button. - **SMTP reliability** — Auto-detects port 465 for SSL vs STARTTLS (`secure` + `requireTLS`). Added error logging with SMTP host/port on send failures. - **Database layer** — Refactored subscription write paths to deduplicate and serialize writes. Added `insertSubscription` (upsert), `confirmSubscription`, `getSubscriptionByPubkey` helpers. Events are now stored with `id, sub_id, event JSON, relay, created_at` and periodically purged (7-day retention). - **Lint fixes** — Removed 20 pre-existing `no-unused-vars` violations across `src/actions.ts`, `src/alert.ts`, `src/digest.ts`, `src/env.ts`, `src/worker/email.ts` so `script/checks` (tsc + eslint) passes clean. **How to test:** - Run `script/checks` — tsc --noEmit, eslint, and full build all pass. - Run `node test/web-ui.test.js` — 3/3 test confirming the guarded `normalizeRelayUrl` pattern. - Set `BRAND_NAME`, `BRAND_ACCENT`, `BRAND_LOGO` env vars and verify confirmation/digest emails render with branding. - `pnpm run preview:digest` renders `digest-preview.html` for template iteration.
hudson added 3 commits 2026-09-10 14:39:40 +00:00
Remove the browser admin SPA under web/ that let users log in via
a Nostr signer and manage subscription filters. The server is now
a headless API only.

Changes:
- Delete web/ directory entirely (SPA source, config, deps)
- Remove express.static('web/dist') serving from server.ts
- Simplify GET / handler to always return JSON (no fallback)
- Remove build:web from package.json build pipeline
- Remove web build steps from Dockerfile
- Remove web references from build-in-production.sh

Kept: core subscription/unsubscribe/confirm/notify backend and
transactional src/pages/*.html (part of email flow, not the UI).
Remove 20 no-unused-vars violations across 5 files:
- src/actions.ts: unused Subscription type import, getCronExpression
- src/alert.ts: unused cron-parser and @welshman/lib imports
- src/digest.ts: unused now, nth, nthEq, dateToSeconds, getIdFilters,
  getReplyFilters, Loader, AdapterContext, makeLoader, SocketAdapter,
  call, loadRelaySelections
- src/env.ts: unused netContext import
- src/worker/email.ts: assigned-but-unused purgeJob variable

These were pre-existing errors unrelated to the web UI removal.
hudson added 1 commit 2026-09-10 16:24:18 +00:00
matt merged commit f04e378ea1 into main 2026-09-10 16:24:31 +00:00
hudson referenced this pull request from a commit 2026-09-14 17:34:27 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: matt/mailship#1
No description provided.