From 2dd35f9b5d143f218826c2a49d694d7424dc5516 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 22 Jul 2026 01:08:18 +0000 Subject: [PATCH] RELEASING: Releasing 1 package(s) Releases: nostream@3.1.0 [skip ci] --- .changeset/admin-console-phase-1.md | 5 -- .changeset/admin-dashboard-ui.md | 5 -- .../admin-metrics-collector-foundation.md | 5 -- .../admin-metrics-handler-instrumentation.md | 5 -- .changeset/admin-metrics-sse-endpoint.md | 5 -- .changeset/dependabot-pr-646.md | 5 -- .../duplicate-events-on-tag-filter-queries.md | 15 ---- .changeset/flat-rice-brush.md | 2 - .changeset/nip-50-search.md | 17 ----- .changeset/nip42-restricted-reads.md | 5 -- .changeset/nip43-invite-codes.md | 5 -- .changeset/nip43-join-leave.md | 5 -- .changeset/nip70-reject-protected-events.md | 5 -- .changeset/optimize-nip03-nip05-tests.md | 10 --- .../rate-limiter-continues-after-hit.md | 10 --- .changeset/redis-haskey-missing-await.md | 5 -- .../root-handler-crash-payments-disabled.md | 5 -- .changeset/shared-settings-config-module.md | 5 -- CHANGELOG.md | 73 +++++++++++++++++++ package.json | 2 +- 20 files changed, 74 insertions(+), 120 deletions(-) delete mode 100644 .changeset/admin-console-phase-1.md delete mode 100644 .changeset/admin-dashboard-ui.md delete mode 100644 .changeset/admin-metrics-collector-foundation.md delete mode 100644 .changeset/admin-metrics-handler-instrumentation.md delete mode 100644 .changeset/admin-metrics-sse-endpoint.md delete mode 100644 .changeset/dependabot-pr-646.md delete mode 100644 .changeset/duplicate-events-on-tag-filter-queries.md delete mode 100644 .changeset/flat-rice-brush.md delete mode 100644 .changeset/nip-50-search.md delete mode 100644 .changeset/nip42-restricted-reads.md delete mode 100644 .changeset/nip43-invite-codes.md delete mode 100644 .changeset/nip43-join-leave.md delete mode 100644 .changeset/nip70-reject-protected-events.md delete mode 100644 .changeset/optimize-nip03-nip05-tests.md delete mode 100644 .changeset/rate-limiter-continues-after-hit.md delete mode 100644 .changeset/redis-haskey-missing-await.md delete mode 100644 .changeset/root-handler-crash-payments-disabled.md delete mode 100644 .changeset/shared-settings-config-module.md diff --git a/.changeset/admin-console-phase-1.md b/.changeset/admin-console-phase-1.md deleted file mode 100644 index 248884a2..00000000 --- a/.changeset/admin-console-phase-1.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nostream": minor ---- - -feat: add disabled-by-default admin API with password auth, session, and health endpoints diff --git a/.changeset/admin-dashboard-ui.md b/.changeset/admin-dashboard-ui.md deleted file mode 100644 index c6c8b2e0..00000000 --- a/.changeset/admin-dashboard-ui.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nostream": minor ---- - -feat: add admin observability dashboard with Grafana embed and provisioned metrics panels diff --git a/.changeset/admin-metrics-collector-foundation.md b/.changeset/admin-metrics-collector-foundation.md deleted file mode 100644 index 4c2ecb60..00000000 --- a/.changeset/admin-metrics-collector-foundation.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nostream": minor ---- - -feat: add OpenTelemetry metrics bootstrap with OTLP export for Prometheus diff --git a/.changeset/admin-metrics-handler-instrumentation.md b/.changeset/admin-metrics-handler-instrumentation.md deleted file mode 100644 index 45424dfa..00000000 --- a/.changeset/admin-metrics-handler-instrumentation.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nostream": minor ---- - -feat: instrument event and websocket handlers with OpenTelemetry metrics diff --git a/.changeset/admin-metrics-sse-endpoint.md b/.changeset/admin-metrics-sse-endpoint.md deleted file mode 100644 index 2431746d..00000000 --- a/.changeset/admin-metrics-sse-endpoint.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nostream": minor ---- - -feat: add Prometheus-backed admin metrics SSE endpoint diff --git a/.changeset/dependabot-pr-646.md b/.changeset/dependabot-pr-646.md deleted file mode 100644 index e870c5f5..00000000 --- a/.changeset/dependabot-pr-646.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nostream": patch ---- - -chore(deps): bump js-yaml from 4.1.1 to 4.2.0 diff --git a/.changeset/duplicate-events-on-tag-filter-queries.md b/.changeset/duplicate-events-on-tag-filter-queries.md deleted file mode 100644 index 5208ab2c..00000000 --- a/.changeset/duplicate-events-on-tag-filter-queries.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"nostream": patch ---- - -fix: de-duplicate events returned by generic tag-filter subscriptions - -`EventRepository.findByFilters()` left-joins `event_tags` for generic tag filters -(`#e`, `#p`, etc.) without deduplicating the result. An event matching more than one -tag row for the same filter (e.g. `{"#p": ["a", "b"]}` matching an event tagged with -both) was returned once per matching `event_tags` row, so subscribers received the -same `EVENT` message multiple times. The query now selects `DISTINCT events.*` for -tag-filtered queries so each stored event is returned at most once. This also covers -generic tag filters combined with a NIP-50 `search` term (e.g. -`{"search": "...", "#p": ["a", "b"]}`), which take the search branch and are now -de-duplicated as well. diff --git a/.changeset/flat-rice-brush.md b/.changeset/flat-rice-brush.md deleted file mode 100644 index a845151c..00000000 --- a/.changeset/flat-rice-brush.md +++ /dev/null @@ -1,2 +0,0 @@ ---- ---- diff --git a/.changeset/nip-50-search.md b/.changeset/nip-50-search.md deleted file mode 100644 index 57d54ef7..00000000 --- a/.changeset/nip-50-search.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -"nostream": minor ---- - -Add NIP-50 full-text search support with PostgreSQL `tsvector`/`GIN` indexing. - -Clients can now include a `search` field in REQ filter objects to perform full-text -queries against event content. Results are ranked by relevance (`ts_rank`) instead -of the usual `created_at` ordering, per the NIP-50 specification. - -Features: -- New `search` filter field accepted in REQ messages -- PostgreSQL GIN index on `to_tsvector('simple', event_content)` for fast full-text lookups -- Configurable text-search language (defaults to `simple`, supports `english`, `spanish`, etc.) -- Configurable max search query length for abuse prevention -- NIP-50 listed in NIP-11 relay information document -- Search can be combined with all existing filter fields (kinds, authors, tags, etc.) diff --git a/.changeset/nip42-restricted-reads.md b/.changeset/nip42-restricted-reads.md deleted file mode 100644 index 907d5301..00000000 --- a/.changeset/nip42-restricted-reads.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nostream": minor ---- - -feat(nip42): enforce authentication on reads for restricted event kinds (encrypted DMs, gift wraps) across REQ, live broadcasts and COUNT diff --git a/.changeset/nip43-invite-codes.md b/.changeset/nip43-invite-codes.md deleted file mode 100644 index e5f9eb7c..00000000 --- a/.changeset/nip43-invite-codes.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nostream": minor ---- - -Add NIP-43 invite code foundation: InviteCodeRepository with atomic claimCode, invite_codes migration, and event kind/tag constants. diff --git a/.changeset/nip43-join-leave.md b/.changeset/nip43-join-leave.md deleted file mode 100644 index c10a809a..00000000 --- a/.changeset/nip43-join-leave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nostream": minor ---- - -Add NIP-43 join/leave request event strategies (kinds 28934/28936) with NIP-42 auth enforcement, created_at freshness validation, invite code claiming, and admission management. When `nip43.enabled` is set, publishing is restricted to admitted members even without payments enabled, and NIP-43 is advertised in the NIP-11 document (hidden when disabled). Join/leave update the admission cache so membership changes take effect immediately. diff --git a/.changeset/nip70-reject-protected-events.md b/.changeset/nip70-reject-protected-events.md deleted file mode 100644 index a5247b13..00000000 --- a/.changeset/nip70-reject-protected-events.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nostream": minor ---- - -feat: reject NIP-70 protected events and reposts embedding them diff --git a/.changeset/optimize-nip03-nip05-tests.md b/.changeset/optimize-nip03-nip05-tests.md deleted file mode 100644 index 39c583ac..00000000 --- a/.changeset/optimize-nip03-nip05-tests.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"nostream": patch ---- - -test: optimize nip05.spec.ts & nip03.spec.ts resource management - -- Lift sinon stub to `before`/`after` in verifyNip05Identifier tests (create once, reset between tests) -- Extract SSRF guard callback once in `before` instead of per-test `beforeEach` -- Pre-build shared OTS buffers and attestations at module scope to eliminate redundant Buffer.concat calls -- Add shared event factory for extractNip05FromEvent tests diff --git a/.changeset/rate-limiter-continues-after-hit.md b/.changeset/rate-limiter-continues-after-hit.md deleted file mode 100644 index dfdeb57b..00000000 --- a/.changeset/rate-limiter-continues-after-hit.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"nostream": patch ---- - -fix: stop checking additional rate limit windows once a client is already rate-limited - -`isRateLimited()` in `EventMessageHandler` and `WebSocketAdapter` looped through every -configured rate limit window even after one had already tripped, calling `rateLimiter.hit()` -(a Redis write) for each remaining window. Both now return as soon as the first exceeded -window is found, avoiding redundant Redis writes for clients that are already being limited. diff --git a/.changeset/redis-haskey-missing-await.md b/.changeset/redis-haskey-missing-await.md deleted file mode 100644 index 3021b7d7..00000000 --- a/.changeset/redis-haskey-missing-await.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nostream": patch ---- - -fix: await Redis EXISTS call in RedisAdapter.hasKey() so it reflects actual key presence instead of always returning true diff --git a/.changeset/root-handler-crash-payments-disabled.md b/.changeset/root-handler-crash-payments-disabled.md deleted file mode 100644 index 49f5313d..00000000 --- a/.changeset/root-handler-crash-payments-disabled.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nostream": patch ---- - -fix: prevent crash in NIP-11 relay information document when payments settings are absent diff --git a/.changeset/shared-settings-config-module.md b/.changeset/shared-settings-config-module.md deleted file mode 100644 index f8743f7a..00000000 --- a/.changeset/shared-settings-config-module.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nostream": minor ---- - -refactor: extract shared settings-config module and guided schema for admin settings editor foundation diff --git a/CHANGELOG.md b/CHANGELOG.md index b51c6089..f918d40f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,78 @@ # nostream +## 3.1.0 + +### Minor Changes + +- [#641](https://github.com/cameri/nostream/pull/641) [`837540b`](https://github.com/cameri/nostream/commit/837540b1c5e557fd987fdb10af8a99bab953bdc6) Thanks [@Ferryx349](https://github.com/Ferryx349)! - feat: add disabled-by-default admin API with password auth, session, and health endpoints + +- [#666](https://github.com/cameri/nostream/pull/666) [`44f3bb4`](https://github.com/cameri/nostream/commit/44f3bb4a48d917ca3302ef464f32c52d17b1897e) Thanks [@Ferryx349](https://github.com/Ferryx349)! - feat: add admin observability dashboard with Grafana embed and provisioned metrics panels + +- [#653](https://github.com/cameri/nostream/pull/653) [`8ab4825`](https://github.com/cameri/nostream/commit/8ab482559fad7b50518984f4159af5b4071de547) Thanks [@Ferryx349](https://github.com/Ferryx349)! - feat: add OpenTelemetry metrics bootstrap with OTLP export for Prometheus + +- [#661](https://github.com/cameri/nostream/pull/661) [`237b1a4`](https://github.com/cameri/nostream/commit/237b1a4275fde23f842f6a2841218351f3964b60) Thanks [@Ferryx349](https://github.com/Ferryx349)! - feat: instrument event and websocket handlers with OpenTelemetry metrics + +- [#662](https://github.com/cameri/nostream/pull/662) [`36d95cc`](https://github.com/cameri/nostream/commit/36d95ccd0ec21c1c33e4c75a72c4367756c1ce74) Thanks [@Ferryx349](https://github.com/Ferryx349)! - feat: add Prometheus-backed admin metrics SSE endpoint + +- [#587](https://github.com/cameri/nostream/pull/587) [`30fa252`](https://github.com/cameri/nostream/commit/30fa252afffa1e79ac704fb616a2833484b0177f) Thanks [@Anshumancanrock](https://github.com/Anshumancanrock)! - Add NIP-50 full-text search support with PostgreSQL `tsvector`/`GIN` indexing. + + Clients can now include a `search` field in REQ filter objects to perform full-text + queries against event content. Results are ranked by relevance (`ts_rank`) instead + of the usual `created_at` ordering, per the NIP-50 specification. + + Features: + + - New `search` filter field accepted in REQ messages + - PostgreSQL GIN index on `to_tsvector('simple', event_content)` for fast full-text lookups + - Configurable text-search language (defaults to `simple`, supports `english`, `spanish`, etc.) + - Configurable max search query length for abuse prevention + - NIP-50 listed in NIP-11 relay information document + - Search can be combined with all existing filter fields (kinds, authors, tags, etc.) + +- [#702](https://github.com/cameri/nostream/pull/702) [`e172cce`](https://github.com/cameri/nostream/commit/e172cce3d7a4d025b3ecbc8a199f6ed8c1b0673c) Thanks [@Anshumancanrock](https://github.com/Anshumancanrock)! - feat(nip42): enforce authentication on reads for restricted event kinds (encrypted DMs, gift wraps) across REQ, live broadcasts and COUNT + +- [#650](https://github.com/cameri/nostream/pull/650) [`3461dfe`](https://github.com/cameri/nostream/commit/3461dfee95d6759a8a2a88ee2f3fbe88d1b3b002) Thanks [@Anshumancanrock](https://github.com/Anshumancanrock)! - Add NIP-43 invite code foundation: InviteCodeRepository with atomic claimCode, invite_codes migration, and event kind/tag constants. + +- [#676](https://github.com/cameri/nostream/pull/676) [`0bfa0b5`](https://github.com/cameri/nostream/commit/0bfa0b59b627e5a07c286f769d2ca3d83355bc57) Thanks [@Anshumancanrock](https://github.com/Anshumancanrock)! - Add NIP-43 join/leave request event strategies (kinds 28934/28936) with NIP-42 auth enforcement, created_at freshness validation, invite code claiming, and admission management. When `nip43.enabled` is set, publishing is restricted to admitted members even without payments enabled, and NIP-43 is advertised in the NIP-11 document (hidden when disabled). Join/leave update the admission cache so membership changes take effect immediately. + +- [#644](https://github.com/cameri/nostream/pull/644) [`2f6d773`](https://github.com/cameri/nostream/commit/2f6d77354cd150110c850e8d0a2601558742d3a6) Thanks [@Anshumancanrock](https://github.com/Anshumancanrock)! - feat: reject NIP-70 protected events and reposts embedding them + +- [#672](https://github.com/cameri/nostream/pull/672) [`595c0a6`](https://github.com/cameri/nostream/commit/595c0a625b53f854bbf020a82ec56d986b43bd9d) Thanks [@Ferryx349](https://github.com/Ferryx349)! - refactor: extract shared settings-config module and guided schema for admin settings editor foundation + +### Patch Changes + +- [#646](https://github.com/cameri/nostream/pull/646) [`eb64d8a`](https://github.com/cameri/nostream/commit/eb64d8a937a5a55f5bbd39ecabee84c3402c7101) Thanks [@dependabot](https://github.com/apps/dependabot)! - chore(deps): bump js-yaml from 4.1.1 to 4.2.0 + +- [#694](https://github.com/cameri/nostream/pull/694) [`7c4b728`](https://github.com/cameri/nostream/commit/7c4b728c99a9a56bfb3b31f18dff3aff2c5551df) Thanks [@Priyanshubhartistm](https://github.com/Priyanshubhartistm)! - fix: de-duplicate events returned by generic tag-filter subscriptions + + `EventRepository.findByFilters()` left-joins `event_tags` for generic tag filters + (`#e`, `#p`, etc.) without deduplicating the result. An event matching more than one + tag row for the same filter (e.g. `{"#p": ["a", "b"]}` matching an event tagged with + both) was returned once per matching `event_tags` row, so subscribers received the + same `EVENT` message multiple times. The query now selects `DISTINCT events.*` for + tag-filtered queries so each stored event is returned at most once. This also covers + generic tag filters combined with a NIP-50 `search` term (e.g. + `{"search": "...", "#p": ["a", "b"]}`), which take the search branch and are now + de-duplicated as well. + +- [#640](https://github.com/cameri/nostream/pull/640) [`ca23be1`](https://github.com/cameri/nostream/commit/ca23be1dcdd71becfb735f8a832b01176bf5bcc1) Thanks [@Anshumancanrock](https://github.com/Anshumancanrock)! - test: optimize nip05.spec.ts & nip03.spec.ts resource management + + - Lift sinon stub to `before`/`after` in verifyNip05Identifier tests (create once, reset between tests) + - Extract SSRF guard callback once in `before` instead of per-test `beforeEach` + - Pre-build shared OTS buffers and attestations at module scope to eliminate redundant Buffer.concat calls + - Add shared event factory for extractNip05FromEvent tests + +- [#686](https://github.com/cameri/nostream/pull/686) [`cb7daf6`](https://github.com/cameri/nostream/commit/cb7daf61b2e4de33b84ec937ebdd739bce45d8cf) Thanks [@Priyanshubhartistm](https://github.com/Priyanshubhartistm)! - fix: stop checking additional rate limit windows once a client is already rate-limited + + `isRateLimited()` in `EventMessageHandler` and `WebSocketAdapter` looped through every + configured rate limit window even after one had already tripped, calling `rateLimiter.hit()` + (a Redis write) for each remaining window. Both now return as soon as the first exceeded + window is found, avoiding redundant Redis writes for clients that are already being limited. + +- [#684](https://github.com/cameri/nostream/pull/684) [`3648954`](https://github.com/cameri/nostream/commit/3648954659e206cc656e6be69d370bee72faa761) Thanks [@Priyanshubhartistm](https://github.com/Priyanshubhartistm)! - fix: await Redis EXISTS call in RedisAdapter.hasKey() so it reflects actual key presence instead of always returning true + +- [#682](https://github.com/cameri/nostream/pull/682) [`dc78df5`](https://github.com/cameri/nostream/commit/dc78df5352603842de6692b04cec4f8d3441dace) Thanks [@Priyanshubhartistm](https://github.com/Priyanshubhartistm)! - fix: prevent crash in NIP-11 relay information document when payments settings are absent + ## 3.0.0 ### Major Changes diff --git a/package.json b/package.json index fb5d882b..c21e54e5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nostream", - "version": "3.0.0", + "version": "3.1.0", "packageManager": "pnpm@10.33.0", "private": true, "description": "A Nostr relay written in Typescript.",