bot_challenge_page 0.10.0 → 1.0.0

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: cb4f4b1a29eae8a320d95d2279e21ab44ef8168be416136790c96d2150de1ac3
4
- data.tar.gz: fa8fe854808413b95c4e2c4a5c4ecf4ed7b3826f77b487d46aee895f9a2d6735
3
+ metadata.gz: 62e4404007888e13f20c7ec554c37d7afd5727c5e3b2e21e671d72fa7bf9c589
4
+ data.tar.gz: 3f52d0766f04f9268fff39ebca416fa7fb51c7b2314dc4e39e204fce5c25811b
5
5
  SHA512:
6
- metadata.gz: '082b26cdef3709185fb7616d009798c26d244485ccb03e24593512f1af6481450413351356f044e380e953f65e28a6ac386ca490ba778fbea78c71109f2dc98d'
7
- data.tar.gz: 805a64dfc7de28b6f27fdf0c4b64b18cba29e98ae59376bce6565e133b993246b3783312f65ad69d9c65df8ea31a4193f0dbe2cd5cb4006ca81264caa60464c7
6
+ metadata.gz: 7f9cc9d5917dbe0eced73fdbe74529644197d5181c2b77511bd5055664ba46b01525a149b1ff1258071015dec2862772179f11073ee28bb3fbfcd1c1b05300d6
7
+ data.tar.gz: 1d2a65e52aada9752f5d7149834a73ae75e6d9974839f91f55982da49b6803e3f3f2cd052f5fe809039de96f34e8180b916ac5da7c8eeb46e033c9c8dc1b7873
data/README.md CHANGED
@@ -31,7 +31,7 @@ The motivating use case is fairly dumb (probably AI-related) crawlers crawling s
31
31
  * Configure in the generated `./config/initializers/bot_challenge_page.rb`
32
32
  * At a minimum you need to configure your Cloudflare Turnstile keys
33
33
 
34
- * Some other configuration options are offered -- more advanced/specialized ones are available that are not mentioned in generated config file, see [Config class](./app/models/bot_challenge_page/config.rb)
34
+ * Some other configuration options are offered -- more advanced/specialized ones are available that are not mentioned in generated config file, see [Config class](./lib/bot_challenge_page/config.rb)
35
35
 
36
36
  ## Protect some paths
37
37
 
@@ -39,15 +39,15 @@ You can add `bot_challenge` to a controller to protect all actions in that contr
39
39
 
40
40
  You can also use all the Rails `before_action` params to apply to only some actions or requests in that controller: `only` and `except` to specify actions; and `if` and `unless` to specify procs to filter individual requests.
41
41
 
42
- * Note that we can only protect GET paths, and also think about making sure you DON'T protect
43
- any path your front-end needs JS `fetch` access to, as this would block it (at least
44
- without custom front-end code we haven't really explored)
42
+ * Note that we can only protect GET paths, and also think about making sure you DON'T protect
43
+ any path your front-end needs JS `fetch` access to, as this would block it (at least
44
+ without custom front-end code we haven't really explored)
45
45
 
46
- * If you are tempted to just protect `/` that may work, but you may need to exclude hearbeat paths, front-end (AJAX) requestable paths, API endpoints, uptime checker requests, or other machine-access-desired paths. These may be good candidates for an `unless` parameter, or the `skip_when` configuration.
46
+ * If you are tempted to just protect `/` that may work, but you may need to exclude hearbeat paths, front-end (AJAX) requestable paths, API endpoints, uptime checker requests, or other machine-access-desired paths. These may be good candidates for an `unless` parameter, or the `skip_when` configuration.
47
47
 
48
- * The author is a librarian who believes maintaining machine access in general is a public good, and tries to limit access with a bot challenge to the minimum paths necessary for app sustainability.
48
+ * The author is a librarian who believes maintaining machine access in general is a public good, and tries to limit access with a bot challenge to the minimum paths necessary for app sustainability.
49
49
 
50
- * The default configuration only allows re-use of a 'pass' cookie from requests with same IP address subnet and user-agent-related headers. This can be customized.
50
+ * The default configuration only allows re-use of a 'pass' cookie from requests with same IP address subnet and user-agent-related headers. This can be customized.
51
51
 
52
52
  ```ruby
53
53
  class WidgetController < ApplicationController
@@ -92,7 +92,7 @@ The challenge page by default will be displayed in your app's default rails `lay
92
92
  To customize the layout or challenge page HTML more further, you can use configuration to supply a `render` method for the controller pointing to your own templates or other layouts. You will probably want to re-use the partials we use in our default template, for standard functionality. And you'll want to provide `<template>` elements with the same id's for those elements, but can put whatever you want inside the templates!
93
93
 
94
94
  ```ruby
95
- BotChallengePage::BotChallengePageController.bot_challenge_config.challenge_renderer = ()-> {
95
+ config.challenge_renderer = ()-> {
96
96
  render "my_local_view_folder/whatever", layout "another_layout"
97
97
  }
98
98
  ```
@@ -107,7 +107,7 @@ If you'd like to log or observe challenge issues, you can configure a proc that
107
107
  in the context of the controller, and is called when a page is blocked by a challenge.
108
108
 
109
109
  ```ruby
110
- BotChallengePage::BotChallengePageController.bot_challenge_config.after_blocked = (_bot_challenge_class)-> {
110
+ config.after_blocked = (_bot_challenge_class)-> {
111
111
  logger.info("page blocked by challenge: #{request.uri}")
112
112
  }
113
113
  ```
@@ -115,7 +115,7 @@ BotChallengePage::BotChallengePageController.bot_challenge_config.after_blocked
115
115
  Or, here's how I managed to get it in [lograge](https://github.com/roidrage/lograge), so a page blocked results in a `bot_chlng=true` param in a lograge line.
116
116
 
117
117
  ```ruby
118
- BotChallengePage::BotChallengePageController.bot_challenge_config.after_blocked =
118
+ config.after_blocked =
119
119
  ->(bot_detect_class) {
120
120
  request.env["bot_detect.blocked_for_challenge"] = true
121
121
  }
@@ -129,6 +129,8 @@ config.lograge.custom_payload do |controller|
129
129
  end
130
130
  ```
131
131
 
132
+ Later, however, using similar mechanism, I actually suppressed logging of actions that resulted in bot challenges altogether -- they were exhausting my log platform quota.
133
+
132
134
  ## Example possible Blacklight config
133
135
 
134
136
  Many of us in my professional community use [blacklight](https://github.com/projectblacklight/blacklight). Here's a possible sample blacklight config to:
@@ -143,18 +145,18 @@ Many of us in my professional community use [blacklight](https://github.com/proj
143
145
 
144
146
  ```ruby
145
147
  # ./config/initializers/bot_challenge_page.rb
146
- Rails.application.config.to_prepare do
147
- BotChallengePage::BotChallengePageController.bot_challenge_config.enabled = true
148
+ BotChanngePage.configure do
149
+ config.enabled = true
148
150
 
149
151
  # Need to set store to a Rails cache store other than null store, if you want to track
150
- # rate limits.
151
- BotChallengePage::BotChallengePageController.bot_challenge_config.store = :redis_store
152
+ # rate limits. We chooes to use a different store than Rails.cache.
153
+ config.store = ActiveSupport::Cache::RedisCacheStore.new(url: $some_redis_url)
152
154
 
153
155
  # Get from CloudFlare Turnstile: https://www.cloudflare.com/application-services/products/turnstile/
154
- BotChallengePage::BotChallengePageController.bot_challenge_config.cf_turnstile_sitekey = "MUST GET"
155
- BotChallengePage::BotChallengePageController.bot_challenge_config.cf_turnstile_secret_key = "MUST GET"
156
+ config.cf_turnstile_sitekey = "MUST GET"
157
+ config.cf_turnstile_secret_key = "MUST GET"
156
158
 
157
- BotChallengePage::BotChallengePageController.bot_challenge_config.skip_when = ->(config) {
159
+ config.skip_when = ->(config) {
158
160
  # Exempt honeybadger token to allow HB uptime checker in
159
161
  # https://docs.honeybadger.io/guides/security/
160
162
  (
@@ -193,6 +195,7 @@ class CatalogController < ApplicationController
193
195
  }
194
196
 
195
197
  end
198
+ ```
196
199
 
197
200
  ## Development and automated testing
198
201
 
@@ -235,4 +238,6 @@ The gem is available as open source under the terms of the [MIT License](https:/
235
238
 
236
239
  * And yet another implementation in Rails that perhaps makes more assumptions about use cases, [turnstile-captcha](https://github.com/pfeiffer/turnstile-captcha). Haven't looked at it much.
237
240
 
241
+ * Great article summarizing our community of practice's knowledge of bot defenses, written after this gem: [Mitigating Aggressive Crawler Traffic in the Age of Generative AI: A Collaborative Approach from the University of North Carolina at Chapel Hill Libraries](https://journal.code4lib.org/articles/18489), by Jason Casden, David Romani, Tim Shearer, and Jeff Campbell, Code4Lib Journal Issue 61, 2025-10-21
242
+
238
243
 
@@ -31,6 +31,16 @@ module BotChallengePage
31
31
  else
32
32
  # hacky way to get config to view template in an arbitrary controller, good enough for now
33
33
  controller.instance_variable_set("@bot_challenge_config", self.bot_challenge_config) unless controller.instance_variable_get("@bot_challenge_config")
34
+
35
+ # set preload HTTP header with turnstile url for better page speed
36
+ # May or may not be one there already, we can always add on
37
+ preload_link_value = %Q{<#{self.bot_challenge_config.cf_turnstile_js_url}>; rel=preload; as=script}
38
+ if controller.headers["link"].present?
39
+ controller.headers["link"] += ",#{preload_link_value}"
40
+ else
41
+ controller.headers["link"] = "#{preload_link_value}"
42
+ end
43
+
34
44
  controller.instance_exec &self.bot_challenge_config.challenge_renderer
35
45
  end
36
46
 
@@ -1,3 +1,3 @@
1
1
  module BotChallengePage
2
- VERSION = "0.10.0"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bot_challenge_page
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Rochkind
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-08-04 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: appraisal
@@ -103,7 +102,7 @@ dependencies:
103
102
  version: '7.1'
104
103
  - - "<"
105
104
  - !ruby/object:Gem::Version
106
- version: '8.1'
105
+ version: '8.2'
107
106
  type: :runtime
108
107
  prerelease: false
109
108
  version_requirements: !ruby/object:Gem::Requirement
@@ -113,7 +112,7 @@ dependencies:
113
112
  version: '7.1'
114
113
  - - "<"
115
114
  - !ruby/object:Gem::Version
116
- version: '8.1'
115
+ version: '8.2'
117
116
  - !ruby/object:Gem::Dependency
118
117
  name: http
119
118
  requirement: !ruby/object:Gem::Requirement
@@ -128,7 +127,6 @@ dependencies:
128
127
  - - "~>"
129
128
  - !ruby/object:Gem::Version
130
129
  version: '5.2'
131
- description:
132
130
  email:
133
131
  - jonathan@dnil.net
134
132
  executables: []
@@ -162,7 +160,6 @@ licenses:
162
160
  metadata:
163
161
  homepage_uri: https://github.com/samvera-labs/bot_challenge_page
164
162
  source_code_uri: https://github.com/samvera-labs/bot_challenge_page
165
- post_install_message:
166
163
  rdoc_options: []
167
164
  require_paths:
168
165
  - lib
@@ -177,8 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
177
174
  - !ruby/object:Gem::Version
178
175
  version: '0'
179
176
  requirements: []
180
- rubygems_version: 3.5.9
181
- signing_key:
177
+ rubygems_version: 3.7.1
182
178
  specification_version: 4
183
179
  summary: Show a bot challenge interstitial for Rails, usually using Cloudflare Turnstile
184
180
  test_files: []