The server was setting Access-Control-Allow-Origin: * on every route,
including the unauthenticated GET /subscription/email which returns the
subscriber's email address. Any website could query known pubkeys and
harvest emails.
Changes:
- src/env.ts: require CORS_ORIGIN env var (fail closed, no wildcard)
- src/server.ts: scope CORS middleware to browser-facing routes only,
skip /notify (server-to-server), add Vary: Origin header, import
CORS_ORIGIN from env instead of defaulting to '*'
- .env.template: document new CORS_ORIGIN variable
- test/cors.test.sh: verify CORS on browser routes, no CORS on
server-to-server routes, Vary: Origin presence
Lines 8 and 22 of digest.mjml hardcoded #7161FF for the event-item
border-left and footer link color, while mailer.ts already passes
brandAccent into the template (used at lines 15 and 34). When
BRAND_ACCENT is customized, the border and footer links stayed the
default purple.
Drive both from {{brandAccent}} so they respect the customization.
Fixes bead mailship-hu5
Switch the subscribe endpoint from POST to an idempotent PUT so clients can
always upsert without a stateful lookup first.
- Add GET /subscription/email?pubkey= lookup so clients can avoid re-POSTing.
- insertSubscription no longer clears confirmed_at unless the email address
changes; a frequency change keeps the existing confirmation.
- registerSubscription only sends a confirmation email when the subscription
is new, unconfirmed, or the email address changed.
- Update integration test and README for the PUT endpoint.
Adds a test that validates the fix for the web UI crash when
VITE_NOTIFIER_RELAY is not set. The test exercises the guarded
pattern (ternary guard before calling normalizeRelayUrl) that
prevents the TypeError crash on undefined input.
Closes mailship-4ic
The web UI crashed on load when VITE_NOTIFIER_RELAY was not set
because normalizeRelayUrl(undefined) calls url.match(...) on the
undefined argument, producing:
TypeError: can't access property 'match', A is undefined
Fix: guard with a truthy check before calling normalizeRelayUrl,
and early-return from loadAlerts when NOTIFIER_RELAY is undefined.
Fixes bead mailship-4ic
- test/integration.sh: runs full E2E flow against fresh server
- pnpm test and pnpm test:server scripts added
- Root endpoint handles missing web UI gracefully (returns JSON)
- database.ts reads DATA_DIR env var for test isolation
- .gitignore updated for test artifacts