recaptcha 5.18.0 → 5.20.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 +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +1 -0
- data/lib/recaptcha/adapters/controller_methods.rb +10 -8
- data/lib/recaptcha/configuration.rb +5 -2
- data/lib/recaptcha/reply.rb +114 -0
- data/lib/recaptcha/version.rb +1 -1
- data/lib/recaptcha.rb +10 -53
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 995e891c595981b495f6911abe80bdc9de1df1f2d445e12cc9129f4fcc5d523d
|
4
|
+
data.tar.gz: b160af36ee62814a45c2c3e96a0e6e268521b6f0eacc7dee2bcc130068384dd9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa21ffc606ec9e389970f607aaab34449a21454c4ce5044092ae773dab3a2f622b097504969dd4ec3e532222bed29b8185936f4def1ec17886201ff1869106cd
|
7
|
+
data.tar.gz: 7dfe2542b8cda9555c578c4c9c1977d5ddc6ac6a8955b19f0b5abb96e5946cb4d7b25627a107f8bd2aa60984cb6babd0594fc1ae6e856f66ca500265f92be484
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,12 @@
|
|
1
1
|
## Next
|
2
|
+
|
3
|
+
## 5.20.0
|
4
|
+
* turn recpatch reply into a object with logic
|
5
|
+
|
6
|
+
## 5.19.0
|
7
|
+
* require a minimum lenght of 100 for responses, configured via response_minimum
|
8
|
+
|
9
|
+
## 5.18.0
|
2
10
|
* Add key setup to v3 example in README
|
3
11
|
* Remove unnecessary id from textarea - This was unused and may cause accessability concerns if there is more than one recaptcha on the page due to multiple elements with the same id
|
4
12
|
* Update to latest version of rubocop
|
data/README.md
CHANGED
@@ -31,16 +31,18 @@ module Recaptcha
|
|
31
31
|
|
32
32
|
success, @_recaptcha_reply =
|
33
33
|
Recaptcha.verify_via_api_call(recaptcha_response, options.merge(with_reply: true))
|
34
|
+
|
34
35
|
unless success
|
35
|
-
@_recaptcha_failure_reason =
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
36
|
+
@_recaptcha_failure_reason =
|
37
|
+
if @_recaptcha_reply.score && @_recaptcha_reply.score.to_f < options[:minimum_score].to_f
|
38
|
+
"Recaptcha score didn't exceed the minimum: #{@_recaptcha_reply.score} < #{options[:minimum_score]}."
|
39
|
+
elsif @_recaptcha_reply.error_codes.any?
|
40
|
+
"Recaptcha api call returned with error-codes: #{@_recaptcha_reply.error_codes}."
|
41
|
+
else
|
42
|
+
"Recaptcha failure after api call. Api reply: #{@_recaptcha_reply}."
|
43
|
+
end
|
43
44
|
end
|
45
|
+
|
44
46
|
success
|
45
47
|
end
|
46
48
|
|
@@ -37,8 +37,10 @@ module Recaptcha
|
|
37
37
|
'enterprise_verify_url' => 'https://recaptchaenterprise.googleapis.com/v1/projects'
|
38
38
|
}.freeze
|
39
39
|
|
40
|
-
attr_accessor
|
41
|
-
|
40
|
+
attr_accessor(
|
41
|
+
:default_env, :skip_verify_env, :proxy, :secret_key, :site_key, :handle_timeouts_gracefully,
|
42
|
+
:hostname, :enterprise, :enterprise_api_key, :enterprise_project_id, :response_limit, :response_minimum
|
43
|
+
)
|
42
44
|
attr_writer :api_server_url, :verify_url
|
43
45
|
|
44
46
|
def initialize # :nodoc:
|
@@ -57,6 +59,7 @@ module Recaptcha
|
|
57
59
|
@api_server_url = nil
|
58
60
|
|
59
61
|
@response_limit = 4000
|
62
|
+
@response_minimum = 100
|
60
63
|
end
|
61
64
|
|
62
65
|
def secret_key!
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Recaptcha
|
4
|
+
class Reply
|
5
|
+
def initialize(raw_reply, enterprise:)
|
6
|
+
@raw_reply = raw_reply
|
7
|
+
@enterprise = enterprise
|
8
|
+
end
|
9
|
+
|
10
|
+
def success?(options = {})
|
11
|
+
success.to_s == 'true' &&
|
12
|
+
hostname_valid?(options[:hostname]) &&
|
13
|
+
action_valid?(options[:action]) &&
|
14
|
+
score_above_threshold?(options[:minimum_score]) &&
|
15
|
+
score_below_threshold?(options[:maximum_score])
|
16
|
+
end
|
17
|
+
|
18
|
+
def token_properties
|
19
|
+
@raw_reply['tokenProperties'] if enterprise?
|
20
|
+
end
|
21
|
+
|
22
|
+
def success
|
23
|
+
if enterprise?
|
24
|
+
token_properties&.dig('valid')
|
25
|
+
else
|
26
|
+
@raw_reply['success']
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def hostname
|
31
|
+
if enterprise?
|
32
|
+
token_properties&.dig('hostname')
|
33
|
+
else
|
34
|
+
@raw_reply['hostname']
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def action
|
39
|
+
if enterprise?
|
40
|
+
token_properties&.dig('action')
|
41
|
+
else
|
42
|
+
@raw_reply['action']
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def score
|
47
|
+
if enterprise?
|
48
|
+
@raw_reply.dig('riskAnalysis', 'score')
|
49
|
+
else
|
50
|
+
@raw_reply['score'] unless enterprise?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def error_codes
|
55
|
+
if enterprise?
|
56
|
+
[]
|
57
|
+
else
|
58
|
+
@raw_reply['error-codes'] || []
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def challenge_ts
|
63
|
+
return @raw_reply['challenge_ts'] unless enterprise?
|
64
|
+
|
65
|
+
token_properties&.dig('createTime')
|
66
|
+
end
|
67
|
+
|
68
|
+
def hostname_valid?(validation)
|
69
|
+
validation ||= Recaptcha.configuration.hostname
|
70
|
+
|
71
|
+
case validation
|
72
|
+
when nil, FalseClass
|
73
|
+
true
|
74
|
+
when String
|
75
|
+
validation == hostname
|
76
|
+
else
|
77
|
+
validation.call(hostname)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def action_valid?(expected_action)
|
82
|
+
case expected_action
|
83
|
+
when nil, FalseClass
|
84
|
+
true
|
85
|
+
else
|
86
|
+
action == expected_action.to_s
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def score_above_threshold?(minimum_score)
|
91
|
+
!minimum_score || (score && score >= minimum_score)
|
92
|
+
end
|
93
|
+
|
94
|
+
def score_below_threshold?(maximum_score)
|
95
|
+
!maximum_score || (score && score <= maximum_score)
|
96
|
+
end
|
97
|
+
|
98
|
+
def enterprise?
|
99
|
+
@enterprise
|
100
|
+
end
|
101
|
+
|
102
|
+
def to_h
|
103
|
+
@raw_reply
|
104
|
+
end
|
105
|
+
|
106
|
+
def to_s
|
107
|
+
@raw_reply.to_s
|
108
|
+
end
|
109
|
+
|
110
|
+
def to_json(*args)
|
111
|
+
@raw_reply.to_json(*args)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
data/lib/recaptcha/version.rb
CHANGED
data/lib/recaptcha.rb
CHANGED
@@ -6,6 +6,7 @@ require 'uri'
|
|
6
6
|
|
7
7
|
require 'recaptcha/configuration'
|
8
8
|
require 'recaptcha/helpers'
|
9
|
+
require 'recaptcha/reply'
|
9
10
|
require 'recaptcha/adapters/controller_methods'
|
10
11
|
require 'recaptcha/adapters/view_methods'
|
11
12
|
if defined?(Rails)
|
@@ -55,7 +56,7 @@ module Recaptcha
|
|
55
56
|
end
|
56
57
|
|
57
58
|
def self.invalid_response?(resp)
|
58
|
-
resp.empty? || resp.length > configuration.response_limit
|
59
|
+
resp.empty? || resp.length > configuration.response_limit || resp.length < configuration.response_minimum
|
59
60
|
end
|
60
61
|
|
61
62
|
def self.verify_via_api_call(response, options)
|
@@ -76,21 +77,10 @@ module Recaptcha
|
|
76
77
|
body['event']['expectedAction'] = options[:action] if options.key?(:action)
|
77
78
|
body['event']['userIpAddress'] = options[:remote_ip] if options.key?(:remote_ip)
|
78
79
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
token_properties['valid'].to_s == 'true' &&
|
84
|
-
hostname_valid?(token_properties['hostname'], options[:hostname]) &&
|
85
|
-
action_valid?(token_properties['action'], options[:action]) &&
|
86
|
-
score_above_threshold?(score, options[:minimum_score]) &&
|
87
|
-
score_below_threshold?(score, options[:maximum_score])
|
88
|
-
|
89
|
-
if options[:with_reply] == true
|
90
|
-
[success, reply]
|
91
|
-
else
|
92
|
-
success
|
93
|
-
end
|
80
|
+
raw_reply = api_verification_enterprise(query_params, body, project_id, timeout: options[:timeout])
|
81
|
+
reply = Reply.new(raw_reply, enterprise: true)
|
82
|
+
result = reply.success?(options)
|
83
|
+
options[:with_reply] == true ? [result, reply] : result
|
94
84
|
end
|
95
85
|
|
96
86
|
def self.verify_via_api_call_free(response, options)
|
@@ -98,43 +88,10 @@ module Recaptcha
|
|
98
88
|
verify_hash = { 'secret' => secret_key, 'response' => response }
|
99
89
|
verify_hash['remoteip'] = options[:remote_ip] if options.key?(:remote_ip)
|
100
90
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
score_above_threshold?(reply['score'], options[:minimum_score]) &&
|
106
|
-
score_below_threshold?(reply['score'], options[:maximum_score])
|
107
|
-
|
108
|
-
if options[:with_reply] == true
|
109
|
-
[success, reply]
|
110
|
-
else
|
111
|
-
success
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def self.hostname_valid?(hostname, validation)
|
116
|
-
validation ||= configuration.hostname
|
117
|
-
|
118
|
-
case validation
|
119
|
-
when nil, FalseClass then true
|
120
|
-
when String then validation == hostname
|
121
|
-
else validation.call(hostname)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
def self.action_valid?(action, expected_action)
|
126
|
-
case expected_action
|
127
|
-
when nil, FalseClass then true
|
128
|
-
else action == expected_action.to_s
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def self.score_above_threshold?(score, minimum_score)
|
133
|
-
!minimum_score || (score && score >= minimum_score)
|
134
|
-
end
|
135
|
-
|
136
|
-
def self.score_below_threshold?(score, maximum_score)
|
137
|
-
!maximum_score || (score && score <= maximum_score)
|
91
|
+
raw_reply = api_verification_free(verify_hash, timeout: options[:timeout], json: options[:json])
|
92
|
+
reply = Reply.new(raw_reply, enterprise: false)
|
93
|
+
result = reply.success?(options)
|
94
|
+
options[:with_reply] == true ? [result, reply] : result
|
138
95
|
end
|
139
96
|
|
140
97
|
def self.http_client_for(uri:, timeout: nil)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: recaptcha
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason L Perry
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mocha
|
@@ -139,6 +139,7 @@ files:
|
|
139
139
|
- lib/recaptcha/helpers.rb
|
140
140
|
- lib/recaptcha/rails.rb
|
141
141
|
- lib/recaptcha/railtie.rb
|
142
|
+
- lib/recaptcha/reply.rb
|
142
143
|
- lib/recaptcha/version.rb
|
143
144
|
- rails/locales/de.yml
|
144
145
|
- rails/locales/en.yml
|