recaptcha 5.3.0 → 5.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/README.md +44 -9
- data/lib/recaptcha.rb +7 -1
- data/lib/recaptcha/adapters/controller_methods.rb +12 -5
- data/lib/recaptcha/helpers.rb +6 -5
- data/lib/recaptcha/version.rb +1 -1
- data/rails/locales/fr.yml +5 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec76ff47d12ef3388c2a45d56850272fff3675c9f59619a09b55c918f70b5494
|
4
|
+
data.tar.gz: 697f0a4d41ffab63c6eb5b7d7b81c1f5ac2b1305f27bb84b5fccc421bcd38e2c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51b3627583241aef9a99e2a3ed9c78091c87a92e87210749d38e9ccf0d418dbec455fd524d83210b8331be7064efac2be2308366b8288c574c53b84f6013333e
|
7
|
+
data.tar.gz: 8018c4668d7eef292e5908d609a7ebdd5cfbfb84b0c86a361dac36d3982cc075dc7e694c51639dd09eaf148cfd9536cecb12f6fa188ec72f87328e85976a4e22
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
## Next
|
2
2
|
|
3
|
+
## 5.7.0
|
4
|
+
* french locale
|
5
|
+
* drop ruby 2.3
|
6
|
+
|
7
|
+
## 5.6.0
|
8
|
+
* Allow multiple invisible recaptchas on a single page by setting custom selector
|
9
|
+
|
10
|
+
## 5.5.0
|
11
|
+
* add `recaptcha_reply` controller method for better debugging/inspection
|
12
|
+
|
13
|
+
## 5.4.1
|
14
|
+
* fix v2 vs 'data' postfix
|
15
|
+
|
16
|
+
## 5.4.0
|
17
|
+
* added 'data' postfix to g-recaptcha-response attribute name to avoid collisions
|
18
|
+
|
3
19
|
## 5.3.0
|
4
20
|
* turbolinks support
|
5
21
|
|
data/README.md
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
# reCAPTCHA
|
2
3
|
[![Gem Version](https://badge.fury.io/rb/recaptcha.svg)](https://badge.fury.io/rb/recaptcha)
|
3
4
|
|
@@ -12,6 +13,23 @@ views you can use the `recaptcha_tags` method to embed the needed javascript, an
|
|
12
13
|
in your controllers with `verify_recaptcha` or `verify_recaptcha!`, which raises an error on
|
13
14
|
failure.
|
14
15
|
|
16
|
+
|
17
|
+
# Table of Contents
|
18
|
+
1. [Obtaining a key](#obtaining-a-key)
|
19
|
+
2. [Rails Installation](#rails-installation)
|
20
|
+
3. [Sinatra / Rack / Ruby Installation](#sinatra--rack--ruby-installation)
|
21
|
+
4. [reCAPTCHA V2 API & Usage](#recaptcha-v2-api-and-usage)
|
22
|
+
- [`recaptcha_tags`](#recaptcha_tags)
|
23
|
+
- [`verify_recaptcha`](#verify_recaptcha)
|
24
|
+
- [`invisible_recaptcha_tags`](#invisible_recaptcha_tags)
|
25
|
+
5. [reCAPTCHA V3 API & Usage](#recaptcha-v3-api-and-usage)
|
26
|
+
- [`recaptcha_v3`](#recaptcha_v3)
|
27
|
+
- [`verify_recaptcha` (use with v3)](#verify_recaptcha-use-with-v3)
|
28
|
+
- [`recaptcha_reply`](#recaptcha_reply)
|
29
|
+
6. [I18n Support](#i18n-support)
|
30
|
+
7. [Testing](#testing)
|
31
|
+
8. [Alternative API Key Setup](#alternative-api-key-setup)
|
32
|
+
|
15
33
|
## Obtaining a key
|
16
34
|
|
17
35
|
Go to the [reCAPTCHA admin console](https://www.google.com/recaptcha/admin) to obtain a reCAPTCHA API key.
|
@@ -71,6 +89,7 @@ else
|
|
71
89
|
render 'new'
|
72
90
|
end
|
73
91
|
```
|
92
|
+
Please note that this setup uses [`reCAPTCHA_v2`](#recaptcha-v2-api-and-usage). For a `recaptcha_v3` use, please refer to [`reCAPTCHA_v3 setup`](#examples).
|
74
93
|
|
75
94
|
## Sinatra / Rack / Ruby installation
|
76
95
|
|
@@ -119,7 +138,7 @@ The following options are available:
|
|
119
138
|
Any unrecognized options will be added as attributes on the generated tag.
|
120
139
|
|
121
140
|
You can also override the html attributes for the sizes of the generated `textarea` and `iframe`
|
122
|
-
elements, if CSS isn't your thing. Inspect the [source of `recaptcha_tags`](https://github.com/ambethia/recaptcha/blob/master/lib/recaptcha/
|
141
|
+
elements, if CSS isn't your thing. Inspect the [source of `recaptcha_tags`](https://github.com/ambethia/recaptcha/blob/master/lib/recaptcha/helpers.rb)
|
123
142
|
to see these options.
|
124
143
|
|
125
144
|
Note that you cannot submit/verify the same response token more than once or you will get a
|
@@ -147,7 +166,7 @@ Some of the options available:
|
|
147
166
|
| `:message` | Custom error message.
|
148
167
|
| `:secret_key` | Override the secret API key from the configuration.
|
149
168
|
| `:timeout` | The number of seconds to wait for reCAPTCHA servers before give up. (default: `3`)
|
150
|
-
| `:response` | Custom response parameter. (default: `params['g-recaptcha-response']`)
|
169
|
+
| `:response` | Custom response parameter. (default: `params['g-recaptcha-response-data']`)
|
151
170
|
| `:hostname` | Expected hostname or a callable that validates the hostname, see [domain validation](https://developers.google.com/recaptcha/docs/domain_validation) and [hostname](https://developers.google.com/recaptcha/docs/verify#api-response) docs. (default: `nil`, but can be changed by setting `config.hostname`)
|
152
171
|
| `:env` | Current environment. The request to verify will be skipped if the environment is specified in configuration under `skip_verify_env`
|
153
172
|
|
@@ -278,7 +297,7 @@ threshold:
|
|
278
297
|
<% if @show_checkbox_recaptcha %>
|
279
298
|
<%= recaptcha_tags %>
|
280
299
|
<% else %>
|
281
|
-
<%= recaptcha_v3(action: 'login') %>
|
300
|
+
<%= recaptcha_v3(action: 'login', site_key: ENV['RECAPTCHA_SITE_KEY_V3']) %>
|
282
301
|
<% end %>
|
283
302
|
…
|
284
303
|
```
|
@@ -286,7 +305,7 @@ threshold:
|
|
286
305
|
```ruby
|
287
306
|
# app/controllers/sessions_controller.rb
|
288
307
|
def create
|
289
|
-
success = verify_recaptcha(action: 'login', minimum_score: 0.5)
|
308
|
+
success = verify_recaptcha(action: 'login', minimum_score: 0.5, secret_key: ENV['RECAPTCHA_SECRET_KEY_V3'])
|
290
309
|
checkbox_success = verify_recaptcha unless success
|
291
310
|
if success || checkbox_success
|
292
311
|
# Perform action
|
@@ -344,7 +363,7 @@ function). This lets you include `recaptcha_v3` within a `<form>` tag and have i
|
|
344
363
|
submit the token as part of the form submission.
|
345
364
|
|
346
365
|
Note: reCAPTCHA actually already adds its own hidden tag, like `<textarea
|
347
|
-
id="g-recaptcha-response-100000" name="g-recaptcha-response" class="g-recaptcha-response">`,
|
366
|
+
id="g-recaptcha-response-data-100000" name="g-recaptcha-response-data" class="g-recaptcha-response">`,
|
348
367
|
immediately ater the reCAPTCHA badge in the bottom right of the page — but since it is not inside of
|
349
368
|
any `<form>` element, and since it already passes the token to the callback, this hidden `textarea`
|
350
369
|
isn't helpful to us.
|
@@ -353,7 +372,7 @@ If you need to submit the response token to the server in a different way than v
|
|
353
372
|
submit, such as via [Ajax](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) or [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API),
|
354
373
|
then you can either:
|
355
374
|
1. just extract the token out of the hidden `<input>` or `<textarea>` (both of which will have a
|
356
|
-
predictable name/id), like `document.getElementById('g-recaptcha-response-my-action').value`, or
|
375
|
+
predictable name/id), like `document.getElementById('g-recaptcha-response-data-my-action').value`, or
|
357
376
|
2. write and specify a custom `callback` function. You may also want to pass `element: false` if you
|
358
377
|
don't have a use for the hidden input element.
|
359
378
|
|
@@ -388,8 +407,8 @@ but only accepts the following options:
|
|
388
407
|
| `:action` | The name of the [reCAPTCHA action](https://developers.google.com/recaptcha/docs/v3#actions). Actions may only contain alphanumeric characters and slashes, and must not be user-specific. |
|
389
408
|
| `:nonce` | Optional. Sets nonce attribute for script. Can be generated via `SecureRandom.base64(32)`. (default: `nil`) |
|
390
409
|
| `:callback` | Name of callback function to call with the token. When `element` is `:input`, this defaults to a function named `setInputWithRecaptchaResponseTokenFor#{sanitize_action(action)}` that sets the value of the hidden input to the token. |
|
391
|
-
| `:id` | Specify a unique `id` attribute for the `<input>` element if using `element: :input`. (default: `"g-recaptcha-response-"` + `action`) |
|
392
|
-
| `:name` | Specify a unique `name` attribute for the `<input>` element if using `element: :input`. (default: `g-recaptcha-response[action]`) |
|
410
|
+
| `:id` | Specify a unique `id` attribute for the `<input>` element if using `element: :input`. (default: `"g-recaptcha-response-data-"` + `action`) |
|
411
|
+
| `:name` | Specify a unique `name` attribute for the `<input>` element if using `element: :input`. (default: `g-recaptcha-response-data[action]`) |
|
393
412
|
| `:script` | Same as setting both `:inline_script` and `:external_script`. (default: `true`). |
|
394
413
|
| `:inline_script` | If `true`, adds an inline script tag that calls `grecaptcha.execute` for the given `site_key` and `action` and calls the `callback` with the resulting response token. Pass `false` if you want to handle calling `grecaptcha.execute` yourself. (default: `true`) |
|
395
414
|
| `:element` | The element to render, if any (default: `:input`)<br/>`:input`: Renders a hidden `<input type="hidden">` tag. The value of this will be set to the response token by the default `setInputWithRecaptchaResponseTokenFor{action}` callback.<br/>`false`: Doesn't render any tag. You'll have to add a custom callback that does something with the token. |
|
@@ -435,11 +454,27 @@ result_b = verify_recaptcha(action: 'b')
|
|
435
454
|
```
|
436
455
|
|
437
456
|
Because the response tokens for multiple actions may be submitted together in the same request, they
|
438
|
-
are passed as a hash under `params['g-recaptcha-response']` with the action as the key.
|
457
|
+
are passed as a hash under `params['g-recaptcha-response-data']` with the action as the key.
|
439
458
|
|
440
459
|
It is recommended to pass `external_script: false` on all but one of the calls to
|
441
460
|
`recaptcha` since you only need to include the script tag once for a given `site_key`.
|
442
461
|
|
462
|
+
## `recaptcha_reply`
|
463
|
+
|
464
|
+
After `verify_recaptcha` has been called, you can call `recaptcha_reply` to get the raw reply from recaptcha. This can allow you to get the exact score returned by recaptcha should you need it.
|
465
|
+
|
466
|
+
```ruby
|
467
|
+
if verify_recaptcha(action: 'login')
|
468
|
+
redirect_to @user
|
469
|
+
else
|
470
|
+
score = recaptcha_reply['score']
|
471
|
+
Rails.logger.warn("User #{@user.id} was denied login because of a recaptcha score of #{score}")
|
472
|
+
render 'new'
|
473
|
+
end
|
474
|
+
```
|
475
|
+
|
476
|
+
`recaptcha_reply` will return `nil` if the the reply was not yet fetched.
|
477
|
+
|
443
478
|
## I18n support
|
444
479
|
|
445
480
|
reCAPTCHA supports the I18n gem (it comes with English translations)
|
data/lib/recaptcha.rb
CHANGED
@@ -65,10 +65,16 @@ module Recaptcha
|
|
65
65
|
verify_hash['remoteip'] = options[:remote_ip] if options.key?(:remote_ip)
|
66
66
|
|
67
67
|
reply = api_verification(verify_hash, timeout: options[:timeout])
|
68
|
-
reply['success'].to_s == 'true' &&
|
68
|
+
success = reply['success'].to_s == 'true' &&
|
69
69
|
hostname_valid?(reply['hostname'], options[:hostname]) &&
|
70
70
|
action_valid?(reply['action'], options[:action]) &&
|
71
71
|
score_above_threshold?(reply['score'], options[:minimum_score])
|
72
|
+
|
73
|
+
if options[:with_reply] == true
|
74
|
+
return success, reply
|
75
|
+
else
|
76
|
+
return success
|
77
|
+
end
|
72
78
|
end
|
73
79
|
|
74
80
|
def self.hostname_valid?(hostname, validation)
|
@@ -24,7 +24,9 @@ module Recaptcha
|
|
24
24
|
options = options.merge(remote_ip: remoteip.to_s) if remoteip
|
25
25
|
end
|
26
26
|
|
27
|
-
|
27
|
+
success, @_recaptcha_reply =
|
28
|
+
Recaptcha.verify_via_api_call(recaptcha_response, options.merge(with_reply: true))
|
29
|
+
success
|
28
30
|
end
|
29
31
|
|
30
32
|
if verified
|
@@ -58,6 +60,10 @@ module Recaptcha
|
|
58
60
|
verify_recaptcha(options) || raise(VerifyError)
|
59
61
|
end
|
60
62
|
|
63
|
+
def recaptcha_reply
|
64
|
+
@_recaptcha_reply if defined?(@_recaptcha_reply)
|
65
|
+
end
|
66
|
+
|
61
67
|
def recaptcha_error(model, attribute, message)
|
62
68
|
if model
|
63
69
|
model.errors.add(attribute, message)
|
@@ -70,12 +76,13 @@ module Recaptcha
|
|
70
76
|
request.respond_to?(:format) && request.format == :html && respond_to?(:flash)
|
71
77
|
end
|
72
78
|
|
73
|
-
# Extracts response token from params. params['g-recaptcha-response']
|
74
|
-
#
|
75
|
-
# the
|
79
|
+
# Extracts response token from params. params['g-recaptcha-response-data'] for recaptcha_v3 or
|
80
|
+
# params['g-recaptcha-response'] for recaptcha_tags and invisible_recaptcha_tags and should
|
81
|
+
# either be a string or a hash with the action name(s) as keys. If it is a hash, then `action`
|
82
|
+
# is used as the key.
|
76
83
|
# @return [String] A response token if one was passed in the params; otherwise, `''`
|
77
84
|
def recaptcha_response_token(action = nil)
|
78
|
-
response_param = params['g-recaptcha-response']
|
85
|
+
response_param = params['g-recaptcha-response-data'] || params['g-recaptcha-response']
|
79
86
|
if response_param&.respond_to?(:to_h) # Includes ActionController::Parameters
|
80
87
|
response_param[action].to_s
|
81
88
|
else
|
data/lib/recaptcha/helpers.rb
CHANGED
@@ -10,8 +10,8 @@ module Recaptcha
|
|
10
10
|
def self.recaptcha_v3(options = {})
|
11
11
|
site_key = options[:site_key] ||= Recaptcha.configuration.site_key!
|
12
12
|
action = options.delete(:action) || raise(Recaptcha::RecaptchaError, 'action is required')
|
13
|
-
id = options.delete(:id) || "g-recaptcha-response-" + dasherize_action(action)
|
14
|
-
name = options.delete(:name) || "g-recaptcha-response[#{action}]"
|
13
|
+
id = options.delete(:id) || "g-recaptcha-response-data-" + dasherize_action(action)
|
14
|
+
name = options.delete(:name) || "g-recaptcha-response-data[#{action}]"
|
15
15
|
turbolinks = options.delete(:turbolinks)
|
16
16
|
options[:render] = site_key
|
17
17
|
options[:script_async] ||= false
|
@@ -271,6 +271,7 @@ module Recaptcha
|
|
271
271
|
private_class_method def self.default_callback(options = {})
|
272
272
|
nonce = options[:nonce]
|
273
273
|
nonce_attr = " nonce='#{nonce}'" if nonce
|
274
|
+
selector_attr = options[:id] ? "##{options[:id]}" : ".g-recaptcha"
|
274
275
|
|
275
276
|
<<-HTML
|
276
277
|
<script#{nonce_attr}>
|
@@ -283,9 +284,9 @@ module Recaptcha
|
|
283
284
|
return curEle.nodeName === 'FORM' ? curEle : null
|
284
285
|
};
|
285
286
|
|
286
|
-
var
|
287
|
-
if (
|
288
|
-
var form = closestForm(
|
287
|
+
var el = document.querySelector("#{selector_attr}")
|
288
|
+
if (!!el) {
|
289
|
+
var form = closestForm(el);
|
289
290
|
if (form) {
|
290
291
|
form.submit();
|
291
292
|
}
|
data/lib/recaptcha/version.rb
CHANGED
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.7.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: 2021-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -155,6 +155,7 @@ files:
|
|
155
155
|
- lib/recaptcha/railtie.rb
|
156
156
|
- lib/recaptcha/version.rb
|
157
157
|
- rails/locales/en.yml
|
158
|
+
- rails/locales/fr.yml
|
158
159
|
homepage: http://github.com/ambethia/recaptcha
|
159
160
|
licenses:
|
160
161
|
- MIT
|
@@ -168,14 +169,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
168
169
|
requirements:
|
169
170
|
- - ">="
|
170
171
|
- !ruby/object:Gem::Version
|
171
|
-
version: 2.
|
172
|
+
version: 2.4.0
|
172
173
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
173
174
|
requirements:
|
174
175
|
- - ">="
|
175
176
|
- !ruby/object:Gem::Version
|
176
177
|
version: '0'
|
177
178
|
requirements: []
|
178
|
-
rubygems_version: 3.
|
179
|
+
rubygems_version: 3.1.3
|
179
180
|
signing_key:
|
180
181
|
specification_version: 4
|
181
182
|
summary: Helpers for the reCAPTCHA API
|