Closes issue 218. Flips the convention from "remember to opt in to
redirect: manual" to "remember to opt out". Every outbound fetch that
doesn't pin a hard-coded host now routes through safeFetch and inherits
AbortSignal.timeout(15_000) so a tar-pit upstream can no longer pin a
worker indefinitely. The local AI client also gates on
requirePublicHost: true since its host is user-supplied; operators
running self-hosted Ollama / LM Studio on an RFC1918 address keep their
escape hatch via ALLOW_LOCAL_AI_PRIVATE_HOSTS=true (also enforced at
write-time in /api/user/ai-provider).
14 outbound call sites migrated. The four that already pinned manual
redirect (the historic templates) keep their semantics; the wrapper
preserves an explicit init.redirect. Adds undici as an explicit
dependency so the connect-time pin landing alongside this can rely on
the documented API rather than a transitive hop.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`/api/send` is the public Umami proxy. The hand-rolled allowlist it
carried predated the central `isPublicUrl` helper in
`src/lib/validations/notifications.ts` and was missing every
notation-bypass class the helper catches:
- 100.64.0.0/10 CGNAT
- 0.0.0.0/8 (only the literal `0.0.0.0` was matched)
- 169.254/16 outside the AWS metadata IP (e.g. azure metadata is
`169.254.169.254` too, but other addresses in the block are
routable to other internal endpoints)
- IPv6 ULA (`fc00::/7`)
- IPv4-mapped IPv6 (`::ffff:127.0.0.1`)
- Leading-zero IPv4 octal bypass (`http://010.0.0.1` → 8.0.0.1)
- Hex IPv4 (`http://0x7f.0.0.1`)
- Pure-decimal IPv4 (`http://2130706433`)
The dev-mode escape hatch is also dropped — serving the proxy against
a localhost / RFC1918 Umami target was never a useful configuration
anyway, since the proxy sends the visitor's user-agent + body upstream
which only makes sense against an externally-reachable analytics host.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
HealthLog — personal health-tracking PWA with weight, blood pressure,
pulse, mood tracking, medication compliance, Withings integration,
doctor report PDF export, and Dracula-themed UI.