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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: adcc7a846c1b2cbac386af0946cd3c810803860f85ca363e5453582354c618b0
4
- data.tar.gz: b1ac10dd569bc7220b81505c9c6565d3db900a3c737ed1c184dcd1c96a12c963
3
+ metadata.gz: ec76ff47d12ef3388c2a45d56850272fff3675c9f59619a09b55c918f70b5494
4
+ data.tar.gz: 697f0a4d41ffab63c6eb5b7d7b81c1f5ac2b1305f27bb84b5fccc421bcd38e2c
5
5
  SHA512:
6
- metadata.gz: 8f9f6271ee715f1fbe543ed1b27cc8088678f5da8326718ad60587128e550fbb9073558fa147a4b608469da82af4cfd86ee255c39a7f69e0bd6b1d590ac109d8
7
- data.tar.gz: 94fbd105e5b6f1cf23fd23cb5dac6040d9e642d5110beae4b9982c6a232f24323ed9ab145b3aa9ef7f6d5786537a20ea03dfacde5638c5f82d5921999c398bd7
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/client_helper.rb)
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
- Recaptcha.verify_via_api_call(recaptcha_response, options)
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'] should either be a
74
- # string or a hash with the action name(s) as keys. If it is a hash, then `action` is used as
75
- # the key.
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
@@ -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 eles = document.getElementsByClassName('g-recaptcha');
287
- if (eles.length > 0) {
288
- var form = closestForm(eles[0]);
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
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Recaptcha
4
- VERSION = '5.3.0'
4
+ VERSION = '5.7.0'
5
5
  end
@@ -0,0 +1,5 @@
1
+ fr:
2
+ recaptcha:
3
+ errors:
4
+ verification_failed: La vérification reCAPTCHA a échoué, veuillez essayer à nouveau.
5
+ recaptcha_unreachable: Oops, nous n'avons pas vu valider votre réponse reCAPTCHA. Veuillez essayer à nouveau.
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.3.0
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: 2020-01-10 00:00:00.000000000 Z
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.3.0
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.0.3
179
+ rubygems_version: 3.1.3
179
180
  signing_key:
180
181
  specification_version: 4
181
182
  summary: Helpers for the reCAPTCHA API