diff --git a/.changeset/admin-moderation-634.md b/.changeset/admin-moderation-634.md deleted file mode 100644 index 9016953a7..000000000 --- a/.changeset/admin-moderation-634.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"nostream": minor ---- - -feat(admin): moderation tools for pubkey, kind, and IP limits (closes #634) - -Adds admin API and console view to read and update event pubkey/kind lists, rate-limit bypass lists, quick ban/unban actions, and activity stats for top publishers, client IPs, and rate-limit hits. diff --git a/.changeset/brotli-patched-node.md b/.changeset/brotli-patched-node.md deleted file mode 100644 index 7296affbd..000000000 --- a/.changeset/brotli-patched-node.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"nostream": patch ---- - -chore(deps): build and test on Node 24.22.1, which patches the Brotli decoder - -CVE-2026-111497 is an out-of-bounds write in every Brotli decoder up to 1.2.0, -reachable by anything that decodes a `br` stream. Node bundles its own decoder, -so the fix is the Node release: 24.22.1 on the 24 line. `.nvmrc` and both -Dockerfile stages move from floating `node:24-alpine` to a pinned -`node:24.22.1-alpine`. diff --git a/.changeset/ewma-key-namespace.md b/.changeset/ewma-key-namespace.md deleted file mode 100644 index 574cd028d..000000000 --- a/.changeset/ewma-key-namespace.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"nostream": patch ---- - -Namespace EWMA rate-limiter keys so they cannot collide with sliding-window keys - -The two strategies store different Redis types under the same key name: a sliding -window keeps a sorted set, EWMA keeps a hash. A cache volume carried over from 2.x, -or an operator switching `limits.rateLimiter.strategy`, therefore left EWMA reading a -sorted set as a hash — a `WRONGTYPE` error on every connection and message until the -old key expired. EWMA now writes under an `ewma:` prefix, which also keeps both -strategies' windows intact if the strategy is switched back. diff --git a/.changeset/legal-release-image-tags.md b/.changeset/legal-release-image-tags.md deleted file mode 100644 index ad18fa91c..000000000 --- a/.changeset/legal-release-image-tags.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -"nostream": patch -"nostream-website": patch ---- - -fix(ci): publish legal image tags and keep `latest` off prereleases - -A changesets relay release is tagged `nostream@3.7.0`, and `@` is not legal in a -Docker tag, so the `type=ref,event=tag` rule handed buildx a tag it refused: the -first live run of the Release workflow failed with `invalid tag ...: invalid -reference format` and published no image for the release (#964). - -The tags are now computed by a shell step, so every tag is a value this -repository chose and can check: the bare version, `vX.Y.Z` as well beside it for -a legacy tag, and `latest` only when the release is not a prerelease. Each tag is -validated against Docker's grammar before the build, so an illegal one fails by -name at that step instead of at buildx. - -`docs/CI-MIGRATION.md`, `docs/DEPLOYMENT.md` and `docs/DEPLOY-RUNBOOK.md` no -longer promise `nostream@X.Y.Z` as a pinnable image tag, and the runbook now -names the receiver change that subscribing to `release` events depends on. diff --git a/.changeset/peering-launch-film.md b/.changeset/peering-launch-film.md deleted file mode 100644 index 3846980fa..000000000 --- a/.changeset/peering-launch-film.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"nostream": patch -"nostream-website": patch ---- - -feat(website): add the relay peering launch film and home-page section diff --git a/.changeset/release-dispatch-rerun.md b/.changeset/release-dispatch-rerun.md deleted file mode 100644 index a3dbcbf8a..000000000 --- a/.changeset/release-dispatch-rerun.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"nostream": patch -"nostream-website": patch ---- - -ci(release): allow the image build to be dispatched for an existing tag - -A published release is immutable, so when the image build fails while publishing -it, the release cannot be re-published to retry: GitHub refuses the round trip -with `immutable cannot be changed when release is immutable`. That left #964's -release with no image and no way to build one. - -`release.yml` now accepts `workflow_dispatch` with a `tag` input, and refuses a -tag that is not a relay release, since the event carries no tag of its own. With -no release flags present the prerelease is read from the version, so a dispatch -of `nostream@3.8.0-rc.1` still leaves `latest` where it is. diff --git a/.changeset/repository-unit-tests.md b/.changeset/repository-unit-tests.md deleted file mode 100644 index a845151cc..000000000 --- a/.changeset/repository-unit-tests.md +++ /dev/null @@ -1,2 +0,0 @@ ---- ---- diff --git a/CHANGELOG.md b/CHANGELOG.md index e5721451b..4034fc8e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,63 @@ # nostream +## 3.8.0 + +### Minor Changes + +- [#941](https://github.com/cameri/nostream/pull/941) [`42ed39e`](https://github.com/cameri/nostream/commit/42ed39edf61ef6e8091e2fa32cad8e76823bb67d) Thanks [@Ferryx349](https://github.com/Ferryx349)! - feat(admin): moderation tools for pubkey, kind, and IP limits (closes [#634](https://github.com/cameri/nostream/issues/634)) + + Adds admin API and console view to read and update event pubkey/kind lists, rate-limit bypass lists, quick ban/unban actions, and activity stats for top publishers, client IPs, and rate-limit hits. + +### Patch Changes + +- [#968](https://github.com/cameri/nostream/pull/968) [`98bd234`](https://github.com/cameri/nostream/commit/98bd2340af5bfd79deaa83bcd3a145550e269343) Thanks [@chappie-daemon](https://github.com/chappie-daemon)! - chore(deps): build and test on Node 24.22.1, which patches the Brotli decoder + + CVE-2026-111497 is an out-of-bounds write in every Brotli decoder up to 1.2.0, + reachable by anything that decodes a `br` stream. Node bundles its own decoder, + so the fix is the Node release: 24.22.1 on the 24 line. `.nvmrc` and both + Dockerfile stages move from floating `node:24-alpine` to a pinned + `node:24.22.1-alpine`. + +- [#945](https://github.com/cameri/nostream/pull/945) [`062ee00`](https://github.com/cameri/nostream/commit/062ee007d150b7c4d0daff5032be3ad71de7773e) Thanks [@chappie-daemon](https://github.com/chappie-daemon)! - Namespace EWMA rate-limiter keys so they cannot collide with sliding-window keys + + The two strategies store different Redis types under the same key name: a sliding + window keeps a sorted set, EWMA keeps a hash. A cache volume carried over from 2.x, + or an operator switching `limits.rateLimiter.strategy`, therefore left EWMA reading a + sorted set as a hash — a `WRONGTYPE` error on every connection and message until the + old key expired. EWMA now writes under an `ewma:` prefix, which also keeps both + strategies' windows intact if the strategy is switched back. + +- [#965](https://github.com/cameri/nostream/pull/965) [`ee65257`](https://github.com/cameri/nostream/commit/ee652577236a2a2da6499f3a58f98e0ed3e581c4) Thanks [@chappie-daemon](https://github.com/chappie-daemon)! - fix(ci): publish legal image tags and keep `latest` off prereleases + + A changesets relay release is tagged `nostream@3.7.0`, and `@` is not legal in a + Docker tag, so the `type=ref,event=tag` rule handed buildx a tag it refused: the + first live run of the Release workflow failed with `invalid tag ...: invalid +reference format` and published no image for the release ([#964](https://github.com/cameri/nostream/issues/964)). + + The tags are now computed by a shell step, so every tag is a value this + repository chose and can check: the bare version, `vX.Y.Z` as well beside it for + a legacy tag, and `latest` only when the release is not a prerelease. Each tag is + validated against Docker's grammar before the build, so an illegal one fails by + name at that step instead of at buildx. + + `docs/CI-MIGRATION.md`, `docs/DEPLOYMENT.md` and `docs/DEPLOY-RUNBOOK.md` no + longer promise `nostream@X.Y.Z` as a pinnable image tag, and the runbook now + names the receiver change that subscribing to `release` events depends on. + +- [#969](https://github.com/cameri/nostream/pull/969) [`8ea15fc`](https://github.com/cameri/nostream/commit/8ea15fce0f65916d6c9c1956eb2a3a77eb121a2b) Thanks [@Ferryx349](https://github.com/Ferryx349)! - feat(website): add the relay peering launch film and home-page section + +- [#967](https://github.com/cameri/nostream/pull/967) [`9c736c8`](https://github.com/cameri/nostream/commit/9c736c83d7ea116cd9492c619c7a2f7a156c20ba) Thanks [@chappie-daemon](https://github.com/chappie-daemon)! - ci(release): allow the image build to be dispatched for an existing tag + + A published release is immutable, so when the image build fails while publishing + it, the release cannot be re-published to retry: GitHub refuses the round trip + with `immutable cannot be changed when release is immutable`. That left [#964](https://github.com/cameri/nostream/issues/964)'s + release with no image and no way to build one. + + `release.yml` now accepts `workflow_dispatch` with a `tag` input, and refuses a + tag that is not a relay release, since the event carries no tag of its own. With + no release flags present the prerelease is read from the version, so a dispatch + of `nostream@3.8.0-rc.1` still leaves `latest` where it is. + ## 3.7.0 ### Minor Changes diff --git a/package.json b/package.json index 6b2162544..a819a6ab7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nostream", - "version": "3.7.0", + "version": "3.8.0", "packageManager": "pnpm@10.33.0", "private": true, "description": "A Nostr relay written in Typescript.", diff --git a/website/site/CHANGELOG.md b/website/site/CHANGELOG.md index 76b84dc3c..9b7ed7890 100644 --- a/website/site/CHANGELOG.md +++ b/website/site/CHANGELOG.md @@ -1,5 +1,40 @@ # nostream-website +## 1.3.3 + +### Patch Changes + +- [#965](https://github.com/cameri/nostream/pull/965) [`ee65257`](https://github.com/cameri/nostream/commit/ee652577236a2a2da6499f3a58f98e0ed3e581c4) Thanks [@chappie-daemon](https://github.com/chappie-daemon)! - fix(ci): publish legal image tags and keep `latest` off prereleases + + A changesets relay release is tagged `nostream@3.7.0`, and `@` is not legal in a + Docker tag, so the `type=ref,event=tag` rule handed buildx a tag it refused: the + first live run of the Release workflow failed with `invalid tag ...: invalid +reference format` and published no image for the release ([#964](https://github.com/cameri/nostream/issues/964)). + + The tags are now computed by a shell step, so every tag is a value this + repository chose and can check: the bare version, `vX.Y.Z` as well beside it for + a legacy tag, and `latest` only when the release is not a prerelease. Each tag is + validated against Docker's grammar before the build, so an illegal one fails by + name at that step instead of at buildx. + + `docs/CI-MIGRATION.md`, `docs/DEPLOYMENT.md` and `docs/DEPLOY-RUNBOOK.md` no + longer promise `nostream@X.Y.Z` as a pinnable image tag, and the runbook now + names the receiver change that subscribing to `release` events depends on. + +- [#969](https://github.com/cameri/nostream/pull/969) [`8ea15fc`](https://github.com/cameri/nostream/commit/8ea15fce0f65916d6c9c1956eb2a3a77eb121a2b) Thanks [@Ferryx349](https://github.com/Ferryx349)! - feat(website): add the relay peering launch film and home-page section + +- [#967](https://github.com/cameri/nostream/pull/967) [`9c736c8`](https://github.com/cameri/nostream/commit/9c736c83d7ea116cd9492c619c7a2f7a156c20ba) Thanks [@chappie-daemon](https://github.com/chappie-daemon)! - ci(release): allow the image build to be dispatched for an existing tag + + A published release is immutable, so when the image build fails while publishing + it, the release cannot be re-published to retry: GitHub refuses the round trip + with `immutable cannot be changed when release is immutable`. That left [#964](https://github.com/cameri/nostream/issues/964)'s + release with no image and no way to build one. + + `release.yml` now accepts `workflow_dispatch` with a `tag` input, and refuses a + tag that is not a relay release, since the event carries no tag of its own. With + no release flags present the prerelease is read from the version, so a dispatch + of `nostream@3.8.0-rc.1` still leaves `latest` where it is. + ## 1.3.2 ### Patch Changes diff --git a/website/site/package.json b/website/site/package.json index 107ede55f..f0313c0af 100644 --- a/website/site/package.json +++ b/website/site/package.json @@ -1,6 +1,6 @@ { "name": "nostream-website", - "version": "1.3.2", + "version": "1.3.3", "private": true, "type": "module", "description": "nostream.dev landing page and docs, built with Astro",