Commit graph

33 commits

Author SHA1 Message Date
Agent
def67c4b6c merge origin/main: resolve digest.ts conflict (identical eslint cleanup) 2026-09-10 12:23:37 -04:00
a6fd29cd7d Merge pull request 'fix: resolve eslint unused-variable errors, add branding, idempotent subscriptions, and event verification' (#3) from mailship-66x-fix-pre-existing-eslint-unused-variable--93f into main
Reviewed-on: #3
Reviewed-by: matt <matt@lorentz.is>
2026-09-10 16:01:04 +00:00
Agent
4497a7dee9 fix: remove pre-eslint unused-variable errors across src/
Remove 21 unused imports/variables that caused eslint failures:
- actions.ts (2): Subscription type import, getCronExpression import
- alert.ts (4): CronExpressionParser, tryCatch, int, HOUR
- digest.ts (12): now, nth, nthEq, dateToSeconds, getIdFilters,
  getReplyFilters, Loader, AdapterContext, makeLoader, SocketAdapter,
  call, loadRelaySelections
- env.ts (1): netContext
- worker/email.ts (1): purgeJob variable (kept CronJob side-effect)

All unused symbols were pre-existing, not related to changed files.
tsc --noEmit passes; script/checks now returns 0 on the src check.
2026-09-10 11:58:05 -04:00
Agent
2fb738981e Fix pre-existing eslint unused-import errors to pass script/checks gate
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.
2026-09-10 10:36:54 -04:00
Agent
abc993e595 Remove orphaned web/dist/ reference from .dockerignore 2026-09-10 10:09:13 -04:00
Agent
75f5908039 Strip out the web UI (login + subscription filter management)
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).
2026-09-10 10:08:14 -04:00
mplorentz
d5f54845b6 dedupe and serialize subscription writes. 2026-09-03 13:44:02 -04:00
mplorentz
5abec46cb7 Make subscription upsert idempotent via PUT
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.
2026-09-03 11:47:21 -04:00
mplorentz
ff8e1d7a0d Update styling on confirmation failed page 2026-09-02 16:51:01 -04:00
mplorentz
3a0aff2f30 Update confirmation page 2026-08-27 15:23:18 -04:00
mplorentz
cf335649c0 Wait longer for profile photoes. 2026-08-27 15:18:52 -04:00
mplorentz
14bc273d98 update digest footer 2026-08-27 15:01:13 -04:00
mplorentz
777ab81195 Add relay to nevent in digest links 2026-08-27 14:49:56 -04:00
mplorentz
d143a563ba Process nostr events included directly in the callback. 2026-08-27 11:28:03 -04:00
mplorentz
4e8918c1f3 Add branding to email confirmation screen 2026-08-27 10:30:46 -04:00
mplorentz
f7e0c99764 Update subscription confirmation email template 2026-08-27 10:17:38 -04:00
mplorentz
6e35717072 Rework email template 2026-08-26 17:57:26 -04:00
mplorentz
77e35c26c7 log errors 2026-08-26 17:21:00 -04:00
mplorentz
2088e1be4b Fix web ui error 2026-08-25 14:43:00 -04:00
Agent
2154e654e8 Merge remote-tracking branch 'origin/main' into mailship-4ic-fix-error-in-web-ui-cc5 2026-08-25 10:37:55 -04:00
Agent
adb29c717b Onboard to fragua 2026-08-25 10:37:14 -04:00
Agent
ddc079d8b5 test: add failing test for normalizeRelayUrl(undefined) crash
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
2026-08-25 09:29:29 -04:00
Agent
4e6030f3c2 fix: guard deleteAlert and publishAlert against undefined relay
NOTIFIER_RELAY is string | undefined after the earlier guard fix.
deleteAlert and publishAlert passed it directly to publish() which
expects string[]. Add early-return guards to both functions.

Fixes the 2 new TS2322 errors introduced by the previous commit.
2026-08-24 18:22:46 -04:00
Agent
57f7d94669 fix: guard normalizeRelayUrl against undefined env var
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
2026-08-24 18:21:00 -04:00
Agent
b3d8d186a5 Merge remote-tracking branch 'origin/main' 2026-08-24 17:51:15 -04:00
mplorentz
1865128f41 Switch postmark api to smtp 2026-08-24 16:12:32 -04:00
Agent
e47b0bf9ca bd init: initialize beads issue tracking 2026-08-24 16:11:52 -04:00
mplorentz
1b797b3759 Fix docker build 2026-08-24 15:45:40 -04:00
mplorentz
a799e1ba1c add permissive CORS headers 2026-08-20 12:42:31 -04:00
Agent
31deaf3aa5 Add Dockerfile, docker-compose.yml, .dockerignore
Multi-stage Dockerfile:
- Stage 1: install deps, build TS, build web UI
- Stage 2: minimal production image with sqlite, only prod deps
- Exposes port 4738, uses /data volume for SQLite

docker-compose.yml for easy local deployment with .env support.
.dockerignore to keep the build context lean.
README updated with Docker usage.
.env.template adds DATA_DIR.
2026-08-18 12:40:42 -04:00
Agent
f220301154 Add integration test script, fix root handler, add DATA_DIR support
- 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
2026-08-18 12:35:20 -04:00
Agent
25645e1d0e Fix unsubscribe page path, remove pool override, handle Postmark error gracefully
- Fix unsubscribe page path (unsubscribe-success.html → unsubscribe.html)
- Remove netContext.pool.get override that crashed load()
- Handle Postmark registration error gracefully by returning subscription from DB
- Add getSubscriptionByPubkey import to server.ts
2026-08-18 12:26:07 -04:00
Agent
21e7058862 Initial mailship fork from anchor
Fork anchor, strip all push notification code (APNs, FCM, WebPush),
rename from anchor to mailship, add new database schema for
subscriptions + events tables, and add HTTP API for email
notification registration and NIP-9a relay push callbacks.

- POST /subscription/email — register for email digests
- DELETE /subscription/:key — unsubscribe
- POST /notify/:id — NIP-9a relay push callback
- GET /confirm?token=... — confirm email
- GET /unsubscribe?token=... — unsubscribe

Co-authored-by: mplorentz
2026-08-18 12:21:22 -04:00