devise-cloudflare-turnstile 0.12.0 → 0.12.2

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: 11f41c4964063781c8e59be1c7030ce996230ece6674388be3a12cb0ebfbc1f8
4
- data.tar.gz: 8da777725211daaf3d95c5ef642f52ce1dfa6cbcc09890d344614fa3e7b441de
3
+ metadata.gz: 9be86bd9bc783a6287f049c134ba5267f4b78f3414f4bf8f2ec0b6d0c30b6c85
4
+ data.tar.gz: e0f4678b0668e47801a35f67581acf076512d74054461d1dfda44b4e80269d69
5
5
  SHA512:
6
- metadata.gz: e28097cca5cdfe4a358980ea4d443d4a6edd761cab258efc82b22188cf2d6a08233def94e755bc0b0470db189c3f6e5898dd687671935e19ab30f26542342d7e
7
- data.tar.gz: 27ea16b46b2605f5fac172e583054677bb0b2ef791ba873a672a312cee371a25b47ccc498213af58066b68b71969a210e121c2724f83f8546e43d2cdf2a190ba
6
+ metadata.gz: b212f30b5dc70e328a25a5e1a5345497c2ecdbe8a84416bf5db93d8f58bd60c4e11b322b4fd0eb7922e0baec448ff7f40473c0ca52bf71095c819c172c13b1e3
7
+ data.tar.gz: 4beb91ef50ca21a48b1b0f83de932eeab282802201b9edf76da70898077f10847c428d17023d070809de3c55c96af71432356d0b0bb05433f53e338a09391440
@@ -12,16 +12,14 @@ module Cloudflare
12
12
  end
13
13
 
14
14
  # Registers Devise controllers/actions that should not be protected.
15
+ # Repeated calls for the same controller accumulate.
15
16
  #
16
17
  # config.skip :confirmations # every action
17
18
  # config.skip passwords: :create # a single action
18
19
  # config.skip unlocks: [:new, :create] # a set of actions
19
20
  def skip(*controllers, **controller_actions)
20
- controllers.each { |controller| skips[controller.to_s] = :all }
21
-
22
- controller_actions.each do |controller, actions|
23
- skips[controller.to_s] = Array(actions).map(&:to_s)
24
- end
21
+ controllers.each { |controller| skip_named(controller) }
22
+ controller_actions.each { |controller, actions| skip_actions(controller.to_s, actions) }
25
23
  end
26
24
 
27
25
  def skipped?(controller_name, action_name)
@@ -31,6 +29,21 @@ module Cloudflare
31
29
 
32
30
  rule.include?(action_name.to_s)
33
31
  end
32
+
33
+ private
34
+
35
+ # Ruby 2.6 passes a string-key hash as a positional argument, not as keywords.
36
+ def skip_named(controller)
37
+ return skips[controller.to_s] = :all unless controller.is_a?(Hash)
38
+
39
+ controller.each { |name, actions| skip_actions(name.to_s, actions) }
40
+ end
41
+
42
+ def skip_actions(controller, actions)
43
+ return if skips[controller] == :all
44
+
45
+ skips[controller] = Array(skips[controller]) | Array(actions).map(&:to_s)
46
+ end
34
47
  end
35
48
  end
36
49
  end
@@ -10,6 +10,7 @@ module Devise
10
10
  class_attribute :_turnstile_skip_rules, instance_accessor: false
11
11
  self._turnstile_skip_rules = []
12
12
 
13
+ prepend_before_action :prevalidate_cloudflare_turnstile!, if: :turnstile_verify_action?
13
14
  before_action :verify_cloudflare_turnstile!, if: :turnstile_verify_action?
14
15
  before_action :set_turnstile_page_marker, if: :turnstile_form_action?
15
16
  end
@@ -30,13 +31,20 @@ module Devise
30
31
 
31
32
  private
32
33
 
33
- def verify_cloudflare_turnstile!
34
+ # Runs ahead of the application's own filters, since any filter that
35
+ # reads the signed-in user lets Warden authenticate from the posted
36
+ # credentials. verify_cloudflare_turnstile! still renders the failure.
37
+ def prevalidate_cloudflare_turnstile!
38
+ return unless turnstile_devise_resource?
34
39
  return if turnstile_skipped?
40
+ return if turnstile_verified?
35
41
 
36
- self.resource ||= resource_class.new
37
- # No model is passed, so the failure stays out of resource.errors and is
38
- # reported through the flash, scoped to the render below.
39
- return if valid_turnstile?(flash: :now, **turnstile_verify_options)
42
+ revoke_params_authentication!
43
+ end
44
+
45
+ def verify_cloudflare_turnstile!
46
+ return if turnstile_skipped?
47
+ return if turnstile_verified?
40
48
 
41
49
  revoke_params_authentication!
42
50
  restore_turnstile_submitted_values
@@ -46,10 +54,25 @@ module Devise
46
54
  render turnstile_failure_action, status: :unprocessable_entity
47
55
  end
48
56
 
57
+ # Memoised because Cloudflare tokens are single use, so the early check
58
+ # and a direct verify_cloudflare_turnstile! call verify only once.
59
+ def turnstile_verified?
60
+ return @_turnstile_verified unless @_turnstile_verified.nil?
61
+
62
+ self.resource ||= resource_class.new
63
+ # No model is passed, so the failure stays out of resource.errors and is
64
+ # reported through the flash, scoped to the render that follows.
65
+ @_turnstile_verified = valid_turnstile?(flash: :now, **turnstile_verify_options)
66
+ end
67
+
68
+ # Devise asserts the mapping in its own prepended callback, which runs
69
+ # after ours. Standing down without one keeps its clearer error.
70
+ def turnstile_devise_resource?
71
+ !respond_to?(:devise_mapping, true) || !devise_mapping.nil?
72
+ end
73
+
49
74
  # Devise's sessions#create marks the request eligible for authentication
50
- # straight from the posted credentials. That flag outlives our halt, so
51
- # any current_user call during the failure render would sign the visitor
52
- # in. Devise publishes no constant for the key.
75
+ # from the posted credentials, and publishes no constant for the key.
53
76
  def revoke_params_authentication!
54
77
  request.env.delete('devise.allow_params_authentication')
55
78
  end
@@ -1,7 +1,7 @@
1
1
  module Devise
2
2
  module Cloudflare
3
3
  module Turnstile
4
- VERSION = '0.12.0'.freeze
4
+ VERSION = '0.12.2'.freeze
5
5
  end
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise-cloudflare-turnstile
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.12.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vadim Kononov
@@ -37,8 +37,9 @@ dependencies:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
39
  version: '4.0'
40
- description: Automatically protect Devise authentication forms with Cloudflare Turnstile,
41
- without changing your Devise views or controllers.
40
+ description: Drop-in Cloudflare Turnstile CAPTCHA, a reCAPTCHA alternative, for Devise
41
+ and Devise extensions. Auto-injected widget with Turbo, Turbolinks, CSP nonce and
42
+ i18n support.
42
43
  email:
43
44
  - vadim@konoson.com
44
45
  executables: []
@@ -79,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
80
  - !ruby/object:Gem::Version
80
81
  version: '0'
81
82
  requirements: []
82
- rubygems_version: 3.7.2
83
+ rubygems_version: 4.0.10
83
84
  specification_version: 4
84
- summary: Cloudflare Turnstile integration for Devise
85
+ summary: Cloudflare Turnstile CAPTCHA for Devise with zero view or controller changes
85
86
  test_files: []