v0.1.4
28 September 2026 Latest- Client-IP trust model.
trustedClientIp.trustedProxies(IPv4/IPv6 addresses or CIDRs) names the proxies in front of the API.x-forwarded-foris now only consulted when the TCP peer is one of them, and the client address is the right-most entry that is not itself a trusted proxy — a browser can no longer inject an address into the rate limiter, funnel or decline log. WithouttrustedProxiesthe header is ignored andreq.ip(yourapiOptions.trustProxysetting) or the socket is used.trustCloudflareHeadernow defaults tofalseunlesstrustedProxiesis set or it is enabled explicitly; withtrustedProxiesit is only read from a trusted peer. The secret-header path (x-real-client-ip+x-checkout-guard-proxy) is unchanged and still wins. InvalidtrustedProxiesentries fail at boot. The effective values are shown in the Settings tab. Hosts that relied on the firstx-forwarded-forentry withouttrustProxyshould settrustedProxies. - Auto-capture off the row lock. A below-threshold hold is now captured after the recording transaction commits (same result, same alerts); the Stripe capture call no longer runs while
SELECT … FOR UPDATEis held on the order row. If the capture fails the hold stays Authorized and ahold.capture_failedalert is raised instead of rolling the hold back. - Live intent check before recording a hold. Before
amount_capturable_updatedadds a payment, the PaymentIntent is retrieved from Stripe (outside the transaction).requires_captureproceeds as before;succeededis recorded and settled immediately (captured in the dashboard before the event was delivered);canceledis logged as ahold_expiredpayment event with ahold.expiredalert and no payment is added; any other status is ignored. A redelivered event is de-duplicated before the Stripe call. When the channel has no Stripe key or Stripe is unreachable the signed event payload is used as before. - Admin UI. Effective settings are cached after the first load (only Refresh re-fetches them) and every HTTP/modal subscription is torn down when the page is left.
- Unit tests for
StripeHoldService(webhook flow, dedupe, channel/order errors, transition failure, premium lock, capture/cancel state mapping, safety capture),BankTransferService(channel-scoped listing, mark received / cancel incl. stale-under-lock, sweep expire + remind, stranded repair) andReconciliationService.runOnce(orphan rows, second-run dedupe, single alert, persisted last run) on lightweight fakes — no database. - Postgres corpus test (
src/__tests__/pg-corpus.test.ts, runs whenHULO_PG_URLis set): extracts every SQL template literal, translates it through the dialect adapter and executes it against PostgreSQL 17 with quoted-camelCase stand-ins for the Vendure tables. 37/37 statements pass. parseCidr,isTrustedProxy,clientIpFromForwardedFor,ipToBigIntare exported for hosts that want the same matcher.