golib/cmd/form2mail
AJ ONeal 271b22fa1f
refactor(formmailer): ergonomic cleanups after prod deploy learnings
- Collapse SuccessBody/SuccessBodyFunc (and Error*) into a single required
  func() []byte. Callers build closures with baked-in fallbacks; one field,
  one code path, no priority ordering.
- Split EHLO local name from peer hostname. Add LocalName field + default
  to os.Hostname(). smtp.NewClient gets the peer name (for AUTH + TLS
  binding); c.Hello(localName) overrides the EHLO greeting separately.
  Stdlib conflates these but they're semantically distinct.
- Add TLSConfig override field (supports custom CAs, cert pinning, and
  test-time InsecureSkipVerify). Default is still ServerName: <SMTP host>.
- Add TrustedProxies []netip.Prefix. X-Forwarded-For is now only honored
  when r.RemoteAddr is in the trusted set — otherwise any client can forge
  their IP to bypass rate limits, blacklist, and geo gating.
- Integration tests drive sendMail against a fake SMTP server that does
  STARTTLS + AUTH PLAIN. Regression test for StartTLS(nil) panic (Go 1.22+
  requires ServerName or InsecureSkipVerify).

cmd/form2mail:
- Extract hotReload() helper; replaces the inline closures.
- silentDropRU looks up the email FormName from Fields by Kind instead of
  hardcoding "input_3" (survives field renames).
- Set TrustedProxies to loopback (proxy runs on same host).
- scripts/deploy.sh automates the rename-first / scp / restart / verify /
  cleanup cycle — leaves .old in place on verification failure for rollback.
2026-04-20 23:20:13 -06:00
..