From 84e80f1ef96738caea6332f290167b35b4c735b8 Mon Sep 17 00:00:00 2001 From: Ali Momen Sani Date: Tue, 28 Apr 2026 11:33:37 +0200 Subject: [PATCH 1/3] chore: relax jwt dependency to allow v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow ruby-jwt v3 in addition to v2.x and add a CI matrix entry that pins jwt ~> 3.0 so compat is verified by tests, not just by inspection. Also tighten the JWT.decode call in spec/client_spec.rb to pass an explicit HS256 algorithm — relying on header-inferred algorithms is brittle across jwt versions. Co-Authored-By: Sérgio Patrício Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 9 ++++++++- spec/client_spec.rb | 2 +- stream-chat.gemspec | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8905680..cc738d2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,12 +16,19 @@ jobs: lint: true - ruby: "3.4" lint: true - name: 💎 Ruby ${{ matrix.ruby }} + # Exercise jwt v3 alongside the default v2 resolution. + - ruby: "4.0" + jwt: "~> 3.0" + name: 💎 Ruby ${{ matrix.ruby }}${{ matrix.jwt && format(' (jwt {0})', matrix.jwt) || '' }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # gives the commit linter access to previous commits + - name: Pin jwt to ${{ matrix.jwt }} + if: matrix.jwt + run: echo "gem 'jwt', '${{ matrix.jwt }}'" >> Gemfile + - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} diff --git a/spec/client_spec.rb b/spec/client_spec.rb index c60452d..b120f1e 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -118,7 +118,7 @@ def loop_times(times) it 'creates a user token' do token = @client.create_token('tommaso') - payload = JWT.decode(token, @client.api_secret) + payload = JWT.decode(token, @client.api_secret, true, { algorithm: 'HS256' }) expect(payload[0].fetch('user_id')).to eq 'tommaso' end diff --git a/stream-chat.gemspec b/stream-chat.gemspec index 9a84d11..523b44b 100644 --- a/stream-chat.gemspec +++ b/stream-chat.gemspec @@ -29,7 +29,7 @@ Gem::Specification.new do |gem| gem.add_dependency 'faraday', '~> 2.12' gem.add_dependency 'faraday-multipart', '~> 1.1' gem.add_dependency 'faraday-net_http_persistent', '~> 2.3' - gem.add_dependency 'jwt', '~> 2.10' + gem.add_dependency 'jwt', '>= 2.10', '< 4' gem.add_dependency 'net-http-persistent', '~> 4.0' gem.add_dependency 'sorbet-runtime', '>= 0.5.11820', '< 1' end From 2e86461180602d91587156184f226ebe6c0143ce Mon Sep 17 00:00:00 2001 From: Ali Momen Sani Date: Tue, 28 Apr 2026 16:33:49 +0200 Subject: [PATCH 2/3] fix: drop conflicting StringScanner#initialize from hidden RBI sorbet/rbi/hidden-definitions/hidden.rbi declared StringScanner#initialize(*arg), which conflicts with sorbet's bundled stdlib RBI signature (arg0, arg1=T.unsafe(nil)) and made `srb tc` fail on Ruby 3.4. The latent error was masked because Ruby 3.4 has been getting cancelled by earlier matrix failures for months. This is a workaround; the root cause is a Ruby/Sorbet stdlib RBI mismatch and a future `srb rbi hidden-definitions` regen may re-add the line. Co-Authored-By: Claude Opus 4.7 (1M context) --- sorbet/rbi/hidden-definitions/hidden.rbi | 2 -- 1 file changed, 2 deletions(-) diff --git a/sorbet/rbi/hidden-definitions/hidden.rbi b/sorbet/rbi/hidden-definitions/hidden.rbi index a82e732..664d182 100644 --- a/sorbet/rbi/hidden-definitions/hidden.rbi +++ b/sorbet/rbi/hidden-definitions/hidden.rbi @@ -8698,8 +8698,6 @@ end class StringScanner def bol?(); end - - def initialize(*arg); end Id = ::T.let(nil, ::T.untyped) Version = ::T.let(nil, ::T.untyped) end From 5338f3029f9f063bf0e9dc183e8a8eb206310124 Mon Sep 17 00:00:00 2001 From: Ali Momen Sani Date: Wed, 29 Apr 2026 11:06:30 +0200 Subject: [PATCH 3/3] fix: update DEFAULT_BLOCKLIST to current backend name The server renamed the canonical built-in blocklist from profanity_en_2020_v1 to profanity (chat PR #12716, MOD2-563). The list_blocklists API now returns the new name, so list/get specs that asserted on DEFAULT_BLOCKLIST were failing. Update the constant, the doc comments, and the moderation_spec literal to match. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/best_practices/moderation.md | 4 ++-- docs/webhooks/webhook_events.md | 4 ++-- lib/stream-chat/client.rb | 12 ++++++------ spec/moderation_spec.rb | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/best_practices/moderation.md b/docs/best_practices/moderation.md index e4c2e86..915bfde 100644 --- a/docs/best_practices/moderation.md +++ b/docs/best_practices/moderation.md @@ -99,7 +99,7 @@ client.update_channel_type( ### Blocklist -A Blocklist is a list of words that you can use to moderate chat messages. Stream Chat comes with a built-in Blocklist called `profanity_en_2020_v1` which contains over a thousand of the most common profane words. +A Blocklist is a list of words that you can use to moderate chat messages. Stream Chat comes with a built-in Blocklist called `profanity` which contains over a thousand of the most common profane words. You can manage your own blocklists via the Stream dashboard or APIs to a manage blocklists and configure your channel types to use them. Channel types can be configured to block or flag messages from your users based on your blocklists. To do this you need to configure your channel type(s) with these two configurations: `blocklist` and `blocklist_behavior` . The first one refers to the name of the blocklist and the second must be set as `block` or `flag` . @@ -145,7 +145,7 @@ client.update_channel_type("messaging", blocklist: "no-cakes", blocklist_behavio #### List available blocklists -All applications have the `profanity_en_2020_v1` blocklist available. This endpoint returns all blocklists available for this application. +All applications have the `profanity` blocklist available. This endpoint returns all blocklists available for this application. ```ruby client.list_blocklists() diff --git a/docs/webhooks/webhook_events.md b/docs/webhooks/webhook_events.md index a87ef06..bec85dd 100644 --- a/docs/webhooks/webhook_events.md +++ b/docs/webhooks/webhook_events.md @@ -574,7 +574,7 @@ When applicable, the following attributes are included to the event user and to "blocklist_behavior": "flag", "blocklists": [ { - "blocklist": "profanity_en_2020_v1", + "blocklist": "profanity", "behavior": "block" } ], @@ -877,7 +877,7 @@ When applicable, the following attributes are included to the event user and to "max_message_length": 5000, "automod": "disabled", "automod_behavior": "flag", - "blocklist": "profanity_en_2020_v1", + "blocklist": "profanity", "blocklist_behavior": "block", "automod_thresholds": {}, "commands": [ diff --git a/lib/stream-chat/client.rb b/lib/stream-chat/client.rb index e9a14ea..e5503c4 100644 --- a/lib/stream-chat/client.rb +++ b/lib/stream-chat/client.rb @@ -20,7 +20,7 @@ require 'stream-chat/channel_batch_updater' module StreamChat - DEFAULT_BLOCKLIST = 'profanity_en_2020_v1' + DEFAULT_BLOCKLIST = 'profanity' SOFT_DELETE = 'soft' HARD_DELETE = 'hard' @@ -739,7 +739,7 @@ def create_guest(user) # Returns all blocklists. # # A Block List is a list of words that you can use to moderate chat messages. Stream Chat - # comes with a built-in Block List called profanity_en_2020_v1 which contains over a thousand + # comes with a built-in Block List called profanity which contains over a thousand # of the most common profane words. # You can manage your own block lists via the Stream dashboard or APIs to a manage # blocklists and configure your channel types to use them. @@ -751,7 +751,7 @@ def list_blocklists # Returns a blocklist. # # A Block List is a list of words that you can use to moderate chat messages. Stream Chat - # comes with a built-in Block List called profanity_en_2020_v1 which contains over a thousand + # comes with a built-in Block List called profanity which contains over a thousand # of the most common profane words. # You can manage your own block lists via the Stream dashboard or APIs to a manage # blocklists and configure your channel types to use them. @@ -763,7 +763,7 @@ def get_blocklist(name) # Creates a blocklist. # # A Block List is a list of words that you can use to moderate chat messages. Stream Chat - # comes with a built-in Block List called profanity_en_2020_v1 which contains over a thousand + # comes with a built-in Block List called profanity which contains over a thousand # of the most common profane words. # You can manage your own block lists via the Stream dashboard or APIs to a manage # blocklists and configure your channel types to use them. @@ -775,7 +775,7 @@ def create_blocklist(name, words) # Updates a blocklist. # # A Block List is a list of words that you can use to moderate chat messages. Stream Chat - # comes with a built-in Block List called profanity_en_2020_v1 which contains over a thousand + # comes with a built-in Block List called profanity which contains over a thousand # of the most common profane words. # You can manage your own block lists via the Stream dashboard or APIs to a manage # blocklists and configure your channel types to use them. @@ -787,7 +787,7 @@ def update_blocklist(name, words) # Deletes a blocklist. # # A Block List is a list of words that you can use to moderate chat messages. Stream Chat - # comes with a built-in Block List called profanity_en_2020_v1 which contains over a thousand + # comes with a built-in Block List called profanity which contains over a thousand # of the most common profane words. # You can manage your own block lists via the Stream dashboard or APIs to a manage # blocklists and configure your channel types to use them. diff --git a/spec/moderation_spec.rb b/spec/moderation_spec.rb index ec7faf1..cb83ed3 100644 --- a/spec/moderation_spec.rb +++ b/spec/moderation_spec.rb @@ -197,7 +197,7 @@ def loop_times(times) enabled: true, rules: [ { - name: 'profanity_en_2020_v1', + name: StreamChat::DEFAULT_BLOCKLIST, action: 'flag' } ]