Commit Graph

1 Commits

Author SHA1 Message Date
Matt Ciaccio
872c75f1a1 fix(safety): plug 3 EMAIL_REDIRECT_TO leaks + 10 unit tests + live smoke
Some checks failed
Build & Push Docker Images / lint (push) Failing after 1m10s
Build & Push Docker Images / build-and-push (push) Has been skipped
A pre-import audit caught three places where outbound comms could escape
even with EMAIL_REDIRECT_TO set. Plugged each, added unit tests so the
behavior can't silently regress, and shipped a live smoke script the
operator can run before any production data import.

Leak 1: email-compose.service.ts (per-account user composer)
  Built its own nodemailer transporter and called sendMail() directly,
  bypassing the centralized sendEmail()'s redirect. Now mirrors the same
  redirect: when EMAIL_REDIRECT_TO is set, "to" is rewritten, "cc" is
  dropped, and the subject is prefixed with "[redirected from <orig>]".

Leak 2: documenso-client.sendDocument()
  Tells Documenso to actually email the document. Recipient emails were
  rerouted at create-time (in pass-3) but a document created BEFORE the
  redirect was turned on could still trigger a real-client email. Now
  short-circuited when the redirect is set — returns the existing doc
  shape so downstream code doesn't see an unexpected null.

Leak 3: documenso-client.sendReminder()
  Same shape as sendDocument: emails a stored recipient address that may
  predate the redirect. Now short-circuits with a warn-level log.

Tests (tests/unit/comms-safety.test.ts):
  - createDocument rewrites recipients
  - generateDocumentFromTemplate rewrites both v1.13 formValues.*Email
    keys AND v2.x recipients[] arrays
  - sendDocument is short-circuited (no /send call)
  - sendReminder is short-circuited (no /remind call)
  - createDocument passes through unchanged when redirect unset
  - sendEmail rewrites to + subject for single recipient
  - sendEmail handles array of recipients (joined into subject prefix)
  - sendEmail passes through unchanged when redirect unset
  - Webhook worker reads process.env.EMAIL_REDIRECT_TO at dispatch time
    (no module-level caching that could miss a runtime flip)

Live smoke (scripts/smoke-test-redirect.ts):
  Monkey-patches nodemailer.createTransport, calls the real sendEmail()
  with a fake real-client address, verifies the captured outbound has
  the right "to" + subject. Run: `pnpm tsx scripts/smoke-test-redirect.ts`.
  Exits non-zero if the redirect failed for any reason — drop-in for a
  pre-deploy check.

Verification:
  pnpm exec tsc --noEmit       — 0 errors
  pnpm exec vitest run         — 936/936 (was 926, +10 new safety tests)
  pnpm tsx scripts/smoke-test-redirect.ts — PASS

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 20:55:53 +02:00