From 15a5b4c07ea092a2dfbe4b82060698ecc62cebed Mon Sep 17 00:00:00 2001 From: Vivek Date: Tue, 11 Aug 2026 03:38:31 +0530 Subject: [PATCH] chore: release server 0.8.63 and cli 0.10.55 Ships the `clientIpHeader` option and the scaffold demo that depends on it. Without this release a freshly scaffolded app installs server 0.8.62, whose `rateLimit` has no such option, while the rate-limit demo it also receives tells the reader to reach for it behind a CDN. server carries the option itself. cli carries the two scaffold-side halves: the emitted middleware passing `trustProxy: true`, and its comments explaining why a CDN deploy also has to name the header. The option stays unset in the generated app, because the right header depends on the topology. core, mcp, and ui picked up nothing in the range, so they stay where they are. The generated notes were curated before committing. The generator excerpts the squash body, which is one shared narrative across both packages, so each entry is rewritten to the slice its own package ships. --- changelog/cli/0.10.55.md | 25 +++++++++++++++++++++++++ changelog/server/0.8.63.md | 27 +++++++++++++++++++++++++++ package-lock.json | 4 ++-- packages/cli/package.json | 2 +- packages/server/package.json | 2 +- 5 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 changelog/cli/0.10.55.md create mode 100644 changelog/server/0.8.63.md diff --git a/changelog/cli/0.10.55.md b/changelog/cli/0.10.55.md new file mode 100644 index 000000000..2e2eb6f54 --- /dev/null +++ b/changelog/cli/0.10.55.md @@ -0,0 +1,25 @@ +--- +package: "@webjsdev/cli" +version: 0.10.55 +date: 2026-08-10T22:07:33.109Z +commit_count: 2 +--- +## Fixes + +- **the scaffold's rate-limit demo keys on the visitor, not the proxy** ([#1388](https://github.com/webjsdev/webjs/pull/1388)) [`ec610c69`](https://github.com/webjsdev/webjs/commit/ec610c69) + The rate-limit middleware a generated app receives took the default bucket key, + which is the socket peer. Deployed behind anything, that peer is the proxy, and + a proxy POOL hands out one full allowance per proxy, so the demo promised five + requests per ten seconds and refused nobody. It passes `trustProxy: true` now, + and its comments say what the default keys on and what a CDN does to it, since + the old `keyed by client IP by default` line is what made the mistake easy to + copy. `gallery:clear` also sheds the card's own test alongside the card, so a + reset app does not keep a test for a demo it no longer has. +- **the api template's demo explains the CDN case** ([#1390](https://github.com/webjsdev/webjs/pull/1390)) [`215b8f18`](https://github.com/webjsdev/webjs/commit/215b8f18) + The emitted middleware now points at `clientIpHeader` (new in + `@webjsdev/server` 0.8.63) and says why it is needed behind a CDN: the default + chain reads the leftmost `X-Forwarded-For` entry, which is then the CDN's + egress address, pinned per connection, so the limiter buckets connections + rather than visitors. The option is left UNSET in the generated app on purpose, + because the right header depends on what you deploy behind, and naming the + wrong one is a spoofing hazard rather than a no-op. diff --git a/changelog/server/0.8.63.md b/changelog/server/0.8.63.md new file mode 100644 index 000000000..0788c1700 --- /dev/null +++ b/changelog/server/0.8.63.md @@ -0,0 +1,27 @@ +--- +package: "@webjsdev/server" +version: 0.8.63 +date: 2026-08-10T22:07:33.040Z +commit_count: 1 +--- +## Fixes + +- **`rateLimit` can name the header carrying the visitor** ([#1390](https://github.com/webjsdev/webjs/pull/1390)) [`215b8f18`](https://github.com/webjsdev/webjs/commit/215b8f18) + `trustProxy: true` was not enough behind a CDN. The default chain starts at the + leftmost `X-Forwarded-For` entry, which behind Cloudflare is Cloudflare's + EGRESS address rather than the visitor, and those are pinned per connection, so + the limiter handed out one bucket per connection. The failure reads as working: + a page that pings on a button click holds one connection and counts down + correctly, while every fresh connection starts a new window and nobody is ever + refused. `rateLimit({ clientIpHeader })` and `clientIp(req, { header })` now + name the ONE forwarded header to trust, e.g. `'cf-connecting-ip'`. When set it + is the only wire header read, falling back to the stamped peer then `_anon_`; a + blank value falls through rather than becoming a bucket key every visitor + shares, and a comma chain is split so a proxy that appends cannot mint a bucket + per hop. It requires `trustProxy: true`, since naming a header to trust is the + trust decision, and `WEBJS_NO_TRUST_PROXY=1` still outranks both. Resolution + with no `clientIpHeader` is unchanged: the framework deliberately does NOT + prefer `CF-Connecting-IP` on its own, because Cloudflare overwrites that header + (unforgeable behind Cloudflare, forgeable everywhere else), so preferring it + globally would let a client on an nginx or bare-platform deploy outrank the + header the real proxy sets. diff --git a/package-lock.json b/package-lock.json index 14cd0b167..006a70660 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6979,7 +6979,7 @@ }, "packages/cli": { "name": "@webjsdev/cli", - "version": "0.10.54", + "version": "0.10.55", "license": "MIT", "dependencies": { "@webjsdev/mcp": "^0.1.0", @@ -7044,7 +7044,7 @@ }, "packages/server": { "name": "@webjsdev/server", - "version": "0.8.62", + "version": "0.8.63", "license": "MIT", "dependencies": { "@webjsdev/core": "^0.7.50", diff --git a/packages/cli/package.json b/packages/cli/package.json index 18ea284a8..cb79c0a19 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@webjsdev/cli", - "version": "0.10.54", + "version": "0.10.55", "type": "module", "description": "The CLI for WebJs, a full-stack JavaScript framework built on web components with server-side rendering and no build step. Runs the dev and production servers, scaffolds apps, validates conventions, and drives the database. Node 24+ or Bun.", "bin": { diff --git a/packages/server/package.json b/packages/server/package.json index 426253300..8925f2d62 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@webjsdev/server", - "version": "0.8.62", + "version": "0.8.63", "type": "module", "description": "The server for WebJs, a full-stack JavaScript framework built on web components with server-side rendering and no build step. Provides the file-based router, SSR, server actions, route handlers, middleware, and live reload on Node 24+ or Bun.", "main": "index.js",