eventhub-processor2 1.28.2 → 1.29.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd2f7112cce3b298538f8fa33ad0218ced28e2c86a2064b8cd6054df7e5a5718
4
- data.tar.gz: 759bcd489e715c26146e82982f1c894fa3a97615be8c30334159d719cee8f4a6
3
+ metadata.gz: ebef86c063318afa67b5cc9413207ff62b476b2d21f74b273bc38a6e4f1e27f0
4
+ data.tar.gz: 07d8a05aa5b8e9b1ded3c8ecef9ebf57e7d1863a0da9befb29872037126c57f2
5
5
  SHA512:
6
- metadata.gz: aeacaf0d8a2878add3b3b7081f8a386cff4bc996fc66f0ca46832d898cd732e71f8f2efd0009510398fc7ef9ef7fa944ec5f66892e2a5304707c79d52f222921
7
- data.tar.gz: b8b0d57be7bc929b3262b6092e8cac7989c1341071c43c69e7ab1556b78902088d6dc6cc6112eaea48896d053a7d528ed0f1a594a01df845c7a765bd767684f4
6
+ metadata.gz: aa5d0e5a661e0517bd7742844aa8bada9649605113bbf1aa4ca8a750b09a199552aeda5bbcbc8d9c833b1c8c39ae32551d4c6fa99c9cd0836a08fd1ab9349751
7
+ data.tar.gz: adc18094fa6813a9273259491cc4ed546ce00371b677b221b9153785c8a8d08ac6def9a7416ba41c619a5a48ac085a550d3e1a2f894f2b5d3bdc13ef6e2d6d87
@@ -27,7 +27,7 @@ jobs:
27
27
 
28
28
  name: Ruby ${{ matrix.ruby }}
29
29
  steps:
30
- - uses: actions/checkout@v6
30
+ - uses: actions/checkout@v7
31
31
 
32
32
  - name: Set up Ruby
33
33
  uses: ruby/setup-ruby@v1
@@ -13,7 +13,7 @@ jobs:
13
13
  CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
14
14
 
15
15
  steps:
16
- - uses: actions/checkout@v6
16
+ - uses: actions/checkout@v7
17
17
 
18
18
  - name: Set up Ruby
19
19
  uses: ruby/setup-ruby@v1
@@ -41,7 +41,7 @@ jobs:
41
41
 
42
42
  steps:
43
43
  - name: Checkout current code
44
- uses: actions/checkout@v6
44
+ uses: actions/checkout@v7
45
45
  with:
46
46
  ref: main
47
47
 
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- ruby 4.0.4
1
+ ruby 4.0.6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog of EventHub::Processor2
2
2
 
3
+ # 1.29.1 / 2026-08-26
4
+
5
+ * Docs configuration page: sensitive keywords now only redact leaf values, not hash sections named after one (e.g. `database.pool` stays visible, `database.password` stays redacted).
6
+
7
+ # 1.29.0 / 2026-08-26
8
+
9
+ * Docs configuration page: sensitive keys now match by substring with an extended default list (e.g. `base_url`, `api_port` are redacted automatically). Exceptions like `vhost` stay visible and can be customized via `non_sensitive_keys`, analogous to `sensitive_keys`. See README for details.
10
+ * Docs configuration page: redaction keeps hash/array structures visible and masks only the scalar values inside.
11
+ * Test coverage raised to 100% lines; removed a dead duplicate route mount in the HTTP listener.
12
+
3
13
  # 1.28.2 / 2026-05-20
4
14
 
5
15
  * Fix `CorrelationId.current` leaking across messages on the same Bunny consumer thread. `CorrelationId.with` now always saves and restores, even when called with nil/empty. Symptom in production: deadletter messages stamped with an earlier message's `execution_id`.
data/README.md CHANGED
@@ -499,7 +499,7 @@ end
499
499
 
500
500
  ### Configuration
501
501
 
502
- Displays the active configuration as an HTML table. Sensitive values (passwords, tokens, keys) are automatically redacted at any depth — keys matching the sensitive list are masked whether they appear at the top level, inside nested hashes, or inside hashes nested in arrays.
502
+ Displays the active configuration as an HTML table. Sensitive values (passwords, tokens, keys) are automatically redacted at any depth — keys matching the sensitive list are masked whether they appear at the top level, inside nested hashes, or inside hashes nested in arrays. The structure is always preserved: when a sensitive key holds a hash or array, its keys stay visible and only the scalar values inside are replaced by `***`.
503
503
 
504
504
  ```
505
505
  GET {base_path}/docs/configuration
@@ -507,7 +507,7 @@ GET {base_path}/docs/configuration
507
507
 
508
508
  **Response:** `200 OK` with HTML page
509
509
 
510
- By default, the following keys are redacted: `password`, `secret`, `token`, `api_key`, `credential`, `username`, `user`, `login`. You can customize the list by defining a `sensitive_keys` method in your processor:
510
+ Matching is by substring: a key is redacted if it *contains* one of the sensitive patterns (case-insensitive). By default, the patterns are: `password`, `secret`, `token`, `api_key`, `credential`, `user`, `login`, `host`, `port`, `database`, `instance`, `url`, `endpoint`, `scheme`. So `base_url`, `api_port`, `username`, or `userpwd` are redacted as well. `vhost` is an explicit exception and stays visible, even though it contains `host`. You can customize the list by defining a `sensitive_keys` method in your processor:
511
511
 
512
512
  ```ruby
513
513
  # Override the entire list
@@ -525,6 +525,17 @@ class MyProcessor < EventHub::Processor2
525
525
  end
526
526
  ```
527
527
 
528
+ Exceptions work the other way around: keys listed as exceptions are never redacted, even if they match a sensitive pattern. Unlike the patterns, exceptions match the whole key exactly (case-insensitive). The default is `vhost`; you can customize the list by defining a `non_sensitive_keys` method:
529
+
530
+ ```ruby
531
+ # Keep username and user visible although they match the user pattern
532
+ class MyProcessor < EventHub::Processor2
533
+ def non_sensitive_keys
534
+ EventHub::DocsRenderer::DEFAULT_NON_SENSITIVE_KEYS + %w[username user]
535
+ end
536
+ end
537
+ ```
538
+
528
539
  Or override the entire page by defining a `configuration_as_html` method:
529
540
 
530
541
  ```ruby
@@ -32,6 +32,6 @@ Gem::Specification.new do |spec|
32
32
 
33
33
  spec.add_development_dependency "rake", "~> 13.2"
34
34
  spec.add_development_dependency "rspec", "~> 3.13"
35
- spec.add_development_dependency "simplecov", "~> 0.21"
35
+ spec.add_development_dependency "simplecov", "~> 1.0"
36
36
  spec.add_development_dependency "standard", "~> 1.39"
37
37
  end
@@ -43,13 +43,12 @@ module EventHub
43
43
  end
44
44
 
45
45
  def mount_resources
46
- # Redirect base path to docs
46
+ # Redirect base path to docs. WEBrick normalizes mount points by
47
+ # stripping the trailing slash, so this single mount serves both
48
+ # "#{@base_path}" and "#{@base_path}/".
47
49
  @server.mount_proc @base_path do |req, res|
48
50
  handle_base_redirect(req, res)
49
51
  end
50
- @server.mount_proc "#{@base_path}/" do |req, res|
51
- handle_base_redirect(req, res)
52
- end
53
52
 
54
53
  # API resources
55
54
  @server.mount_proc "#{@base_path}/heartbeat" do |req, res|
@@ -159,29 +159,30 @@ module EventHub
159
159
  intro + filter + config_to_html_table(config) + script
160
160
  end
161
161
 
162
- def config_to_html_table(hash, depth = 0, prefix = "")
162
+ def config_to_html_table(hash, depth = 0, prefix = "", redact: false)
163
163
  rows = hash.map do |key, value|
164
164
  full_key = prefix.empty? ? key.to_s : "#{prefix}.#{key}"
165
- if sensitive_key?(key) && !value.nil? && !(value.respond_to?(:empty?) && value.empty?)
166
- "<tr><td class=\"config-key\">#{ERB::Util.html_escape(full_key)}</td><td>#{redacted_html}</td></tr>"
167
- elsif depth == 0 && value.is_a?(Hash) && !value.empty?
165
+ hide = redact_value?(key, value, redact)
166
+ if depth == 0 && value.is_a?(Hash) && !value.empty?
168
167
  "<tr class=\"is-section is-section-top\"><td colspan=\"2\"><strong>#{ERB::Util.html_escape(full_key)}</strong></td></tr>\n" \
169
- "#{config_to_html_table(value, 1, full_key)}"
168
+ "#{config_to_html_table(value, 1, full_key, redact: hide)}"
170
169
  elsif value.is_a?(Hash) && value.empty?
171
170
  "<tr><td class=\"config-key\">#{ERB::Util.html_escape(full_key)}</td><td><span class=\"not-set\">(empty)</span></td></tr>"
172
171
  elsif value.is_a?(Hash) && value.values.all? { |v| v.is_a?(Hash) && v.empty? }
173
172
  items = value.keys.map { |k| "<li>#{ERB::Util.html_escape(k)}</li>" }.join("\n")
174
173
  "<tr><td class=\"config-key\">#{ERB::Util.html_escape(full_key)}</td><td><ul class=\"config-array\">#{items}</ul></td></tr>"
175
174
  elsif value.is_a?(Hash) && compact_hash?(value)
176
- "<tr><td class=\"config-key\">#{ERB::Util.html_escape(full_key)}</td><td>#{format_nested_value(value)}</td></tr>"
175
+ "<tr><td class=\"config-key\">#{ERB::Util.html_escape(full_key)}</td><td>#{format_nested_value(value, redact: hide)}</td></tr>"
177
176
  elsif value.is_a?(Hash)
178
177
  "<tr class=\"is-section\"><td colspan=\"2\"><strong>#{ERB::Util.html_escape(full_key)}</strong></td></tr>\n" \
179
- "#{config_to_html_table(value, depth + 1, full_key)}"
178
+ "#{config_to_html_table(value, depth + 1, full_key, redact: hide)}"
180
179
  elsif value.is_a?(Array)
181
- format_array_rows(full_key, key, value, depth)
180
+ format_array_rows(full_key, value, depth, redact: hide)
182
181
  else
183
182
  display_value = if value.nil? || value.to_s.strip.empty?
184
183
  "<span class=\"not-set\">(not set)</span>"
184
+ elsif hide
185
+ redacted_html
185
186
  else
186
187
  ERB::Util.html_escape(value.to_s)
187
188
  end
@@ -196,44 +197,42 @@ module EventHub
196
197
  end
197
198
  end
198
199
 
199
- def format_array_rows(full_key, key, array, _depth)
200
+ def format_array_rows(full_key, array, _depth, redact: false)
200
201
  return "<tr><td class=\"config-key\">#{ERB::Util.html_escape(full_key)}</td><td><span class=\"not-set\">(empty)</span></td></tr>" if array.empty?
201
202
 
202
- if sensitive_key?(key)
203
- return "<tr><td class=\"config-key\">#{ERB::Util.html_escape(full_key)}</td><td>#{redacted_html}</td></tr>"
204
- end
205
-
206
- inner = array.map { |item| format_array_item(item) }.join("\n")
203
+ inner = array.map { |item| format_array_item(item, redact: redact) }.join("\n")
207
204
  "<tr><td class=\"config-key\">#{ERB::Util.html_escape(full_key)}</td><td><ul class=\"config-array\">#{inner}</ul></td></tr>"
208
205
  end
209
206
 
210
- def format_array_item(item)
207
+ def format_array_item(item, redact: false)
211
208
  if item.is_a?(Hash)
212
209
  rows = item.map do |k, v|
213
- value = sensitive_key?(k) ? redacted_html : format_nested_value(v)
214
- "<tr><td>#{ERB::Util.html_escape(k)}</td><td>#{value}</td></tr>"
210
+ hide = redact_value?(k, v, redact)
211
+ "<tr><td>#{ERB::Util.html_escape(k)}</td><td>#{format_nested_value(v, redact: hide)}</td></tr>"
215
212
  end.join
216
213
  "<li><table class=\"table is-bordered is-narrow config-subtable\">#{rows}</table></li>"
217
214
  elsif item.is_a?(Array)
218
- inner = item.map { |i| format_array_item(i) }.join("\n")
215
+ inner = item.map { |i| format_array_item(i, redact: redact) }.join("\n")
219
216
  "<li><ul class=\"config-array\">#{inner}</ul></li>"
220
217
  else
221
- "<li>#{ERB::Util.html_escape(item.to_s)}</li>"
218
+ "<li>#{redact ? redacted_html : ERB::Util.html_escape(item.to_s)}</li>"
222
219
  end
223
220
  end
224
221
 
225
- def format_nested_value(value)
222
+ def format_nested_value(value, redact: false)
226
223
  if value.is_a?(Hash)
227
224
  rows = value.map do |k, v|
228
- inner = sensitive_key?(k) ? redacted_html : format_nested_value(v)
229
- "<tr><td>#{ERB::Util.html_escape(k)}</td><td>#{inner}</td></tr>"
225
+ hide = redact_value?(k, v, redact)
226
+ "<tr><td>#{ERB::Util.html_escape(k)}</td><td>#{format_nested_value(v, redact: hide)}</td></tr>"
230
227
  end.join
231
228
  "<table class=\"table is-bordered is-narrow config-subtable\">#{rows}</table>"
232
229
  elsif value.is_a?(Array)
233
- items = value.map { |i| format_array_item(i) }.join("\n")
230
+ items = value.map { |i| format_array_item(i, redact: redact) }.join("\n")
234
231
  "<ul class=\"config-array\">#{items}</ul>"
235
232
  elsif value.nil? || value.to_s.strip.empty?
236
233
  "<span class=\"not-set\">(not set)</span>"
234
+ elsif redact
235
+ redacted_html
237
236
  else
238
237
  ERB::Util.html_escape(value.to_s)
239
238
  end
@@ -253,15 +252,34 @@ module EventHub
253
252
  end
254
253
  end
255
254
 
256
- DEFAULT_SENSITIVE_KEYS = %w[password secret token api_key credential username user login].freeze
255
+ DEFAULT_SENSITIVE_KEYS = %w[password secret token api_key credential user login host port database instance url endpoint scheme].freeze
256
+ DEFAULT_NON_SENSITIVE_KEYS = %w[vhost].freeze
257
+
258
+ # A sensitive keyword only triggers redaction on leaf nodes (scalars and
259
+ # arrays). A hash named e.g. "database" stays visible; its keys are
260
+ # checked individually instead.
261
+ def redact_value?(key, value, inherited)
262
+ inherited || (!value.is_a?(Hash) && sensitive_key?(key))
263
+ end
257
264
 
258
265
  def sensitive_key?(key)
266
+ normalized = key.to_s.downcase
267
+ return false if non_sensitive_keys.any? { |exception| normalized == exception.downcase }
268
+
259
269
  keys = if @processor&.class&.method_defined?(:sensitive_keys)
260
270
  @processor.sensitive_keys
261
271
  else
262
272
  DEFAULT_SENSITIVE_KEYS
263
273
  end
264
- keys.any? { |pattern| key.to_s.downcase == pattern.downcase }
274
+ keys.any? { |pattern| normalized.include?(pattern.downcase) }
275
+ end
276
+
277
+ def non_sensitive_keys
278
+ if @processor&.class&.method_defined?(:non_sensitive_keys)
279
+ @processor.non_sensitive_keys
280
+ else
281
+ DEFAULT_NON_SENSITIVE_KEYS
282
+ end
265
283
  end
266
284
 
267
285
  def markdown_to_html(markdown)
@@ -1,3 +1,3 @@
1
1
  module EventHub
2
- VERSION = "1.28.2".freeze
2
+ VERSION = "1.29.1".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eventhub-processor2
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.28.2
4
+ version: 1.29.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steiner, Thomas
@@ -141,14 +141,14 @@ dependencies:
141
141
  requirements:
142
142
  - - "~>"
143
143
  - !ruby/object:Gem::Version
144
- version: '0.21'
144
+ version: '1.0'
145
145
  type: :development
146
146
  prerelease: false
147
147
  version_requirements: !ruby/object:Gem::Requirement
148
148
  requirements:
149
149
  - - "~>"
150
150
  - !ruby/object:Gem::Version
151
- version: '0.21'
151
+ version: '1.0'
152
152
  - !ruby/object:Gem::Dependency
153
153
  name: standard
154
154
  requirement: !ruby/object:Gem::Requirement
@@ -247,7 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
247
247
  - !ruby/object:Gem::Version
248
248
  version: '0'
249
249
  requirements: []
250
- rubygems_version: 4.0.10
250
+ rubygems_version: 4.0.16
251
251
  specification_version: 4
252
252
  summary: Next generation gem to build ruby based eventhub processor
253
253
  test_files: []