chore: sync in-progress work across marketing, admin, API and tests

Snapshot of uncommitted work that had accumulated in the tree alongside
the Turnstile changes:

- marketing pages, SEO helpers (lib/seo.ts, lib/marketing/) and
  structured data
- admin billing actions and a per-user portfolio view, plus an admin
  error boundary
- rate limiting (lib/rate-limit.ts) applied across the /api/v1 surface
- CSP and proxy adjustments, accounting/webhook lib updates
- Playwright config and an e2e/unit test suite
- next bumped to ^16.3.4 with the lockfile regenerated
- generated AGENTS.md / CLAUDE.md

Authored by other sessions working in this tree; committed here so the
Turnstile work could be pushed without leaving the tree dirty.
Typecheck passes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Leon Serfaty
2026-09-05 16:27:16 -04:00
co-authored by Claude Opus 5
parent 8f90347659
commit 1d02598786
71 changed files with 3641 additions and 819 deletions
+65 -11
View File
@@ -39,18 +39,72 @@ function isPrivateIPv4(ip: string): boolean {
return false
}
/** True for IPv6 loopback, unspecified, ULA, link-local, multicast, or mapped-v4. */
/**
* Expand an IPv6 literal to its eight numeric hextets, or null if unparseable.
* Handles "::" compression and a trailing dotted-quad (::ffff:1.2.3.4).
*/
function ipv6Hextets(input: string): number[] | null {
let s = input.toLowerCase().split("%")[0].replace(/^\[|\]$/g, "")
// Fold a trailing dotted-quad into two hextets so one code path handles both
// spellings of an IPv4-mapped address.
const dotted = s.match(/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/)
if (dotted && dotted.index !== undefined) {
const parts = dotted[1].split(".").map((n) => parseInt(n, 10))
if (parts.some((n) => Number.isNaN(n) || n < 0 || n > 255)) return null
s =
s.slice(0, dotted.index) +
(((parts[0] << 8) | parts[1]) >>> 0).toString(16) +
":" +
(((parts[2] << 8) | parts[3]) >>> 0).toString(16)
}
const halves = s.split("::")
if (halves.length > 2) return null
const split = (chunk: string) => (chunk ? chunk.split(":").filter(Boolean) : [])
const head = split(halves[0])
const tail = halves.length === 2 ? split(halves[1]) : []
const groups =
halves.length === 2
? [...head, ...Array(Math.max(0, 8 - head.length - tail.length)).fill("0"), ...tail]
: head
if (groups.length !== 8) return null
const out: number[] = []
for (const g of groups) {
if (!/^[0-9a-f]{1,4}$/.test(g)) return null
out.push(parseInt(g, 16))
}
return out
}
/**
* True for IPv6 loopback, unspecified, ULA, link-local, multicast, or any
* address embedding a private IPv4 address.
*
* The embedded-IPv4 check works on the NUMERIC hextets, not on the text. Node's
* URL parser rewrites `::ffff:169.254.169.254` to `::ffff:a9fe:a9fe`, so a
* previous version that only matched the dotted-quad spelling let the cloud
* metadata endpoint — and every private range — straight through.
*/
function isPrivateIPv6(ip: string): boolean {
const addr = ip.toLowerCase().split("%")[0] // strip zone id
if (addr === "::1" || addr === "::") return true
// IPv4-mapped / -compatible (e.g. ::ffff:169.254.169.254) — check the v4 part.
const mapped = addr.match(/(?:^::ffff:|^::)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/)
if (mapped) return isPrivateIPv4(mapped[1])
const head = addr.replace(/^\[|\]$/g, "")
if (head.startsWith("fe8") || head.startsWith("fe9") || head.startsWith("fea") || head.startsWith("feb"))
return true // fe80::/10 link-local
if (head.startsWith("fc") || head.startsWith("fd")) return true // fc00::/7 unique-local
if (head.startsWith("ff")) return true // ff00::/8 multicast
const h = ipv6Hextets(ip)
if (!h) return true // unparseable → treat as unsafe
// ::/96 (covers :: and ::1) and ::ffff:0:0/96 both carry an IPv4 address in
// the low 32 bits. Decode it and reuse the IPv4 rules.
const embedsIPv4 =
h[0] === 0 && h[1] === 0 && h[2] === 0 && h[3] === 0 && h[4] === 0 &&
(h[5] === 0 || h[5] === 0xffff)
if (embedsIPv4) {
const v4 = [h[6] >> 8, h[6] & 0xff, h[7] >> 8, h[7] & 0xff].join(".")
return isPrivateIPv4(v4)
}
const first = h[0]
if ((first & 0xffc0) === 0xfe80) return true // fe80::/10 link-local
if ((first & 0xfe00) === 0xfc00) return true // fc00::/7 unique-local
if ((first & 0xff00) === 0xff00) return true // ff00::/8 multicast
return false
}