recaptcha 5.2.0 → 5.5.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: 94a9b4a77081e448fdd8183dbbbbfd2dd7cf797508e84ee2e37830a9398fd6d1
4
- data.tar.gz: 3761a642f1b421fd554303de7bab636bc69296df1f62c1c76fe987ecc617971f
3
+ metadata.gz: ba681f9321310ca16bb41dc622bf7051c30df10ec000582f9dd8d29310e21136
4
+ data.tar.gz: 8d9a3a4a7adb2ea830f17ace469e6b475d4d5c633c6988cd04dd56a7fd70e414
5
5
  SHA512:
6
- metadata.gz: 07d9a1f2fff0d745a59eb0e28d23879a22203037971ed1d3311b39bccf1b34f8120ab58a2cd7e05fabd7037ab2ad0e3d5882f3335d103c9f27145026deef19a6
7
- data.tar.gz: 2b2b799c18f2dd81346213d74c1d62729e241de41ab2f19c2b3ec04d57534f8adb5fd4922d7a219d0f8c916e63a842d0802ba4364f84d7388de7d4736ec90e46
6
+ metadata.gz: efba5551493debe23617c41db429c224f51a4d0253274cf6fe28c5e384d78f4bd374ba3ad3132c2009cb2df9813266ac3a90eabd9a019aa7d48ee3999f2451e3
7
+ data.tar.gz: 1dfd4f2281c8f6902b1c70ca0d272d0d2f671d9062669f147cfb38416ee771e7348ff131c8fd957c1e8674b7d83ad3f3c79f6c306a7779638b4481000534f695
@@ -1,5 +1,11 @@
1
1
  ## Next
2
2
 
3
+ ## 5.3.0
4
+ * turbolinks support
5
+
6
+ ## 5.2.0
7
+ * remove dependency on rails methods
8
+
3
9
  ## 5.1.0
4
10
  * Added default translations for rails/i18n
5
11
  * use recaptcha.net for the script tag
data/README.md CHANGED
@@ -147,7 +147,7 @@ Some of the options available:
147
147
  | `:message` | Custom error message.
148
148
  | `:secret_key` | Override the secret API key from the configuration.
149
149
  | `: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']`)
150
+ | `:response` | Custom response parameter. (default: `params['g-recaptcha-response-data']`)
151
151
  | `: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
152
  | `:env` | Current environment. The request to verify will be skipped if the environment is specified in configuration under `skip_verify_env`
153
153
 
@@ -344,7 +344,7 @@ function). This lets you include `recaptcha_v3` within a `<form>` tag and have i
344
344
  submit the token as part of the form submission.
345
345
 
346
346
  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">`,
347
+ id="g-recaptcha-response-data-100000" name="g-recaptcha-response-data" class="g-recaptcha-response">`,
348
348
  immediately ater the reCAPTCHA badge in the bottom right of the page — but since it is not inside of
349
349
  any `<form>` element, and since it already passes the token to the callback, this hidden `textarea`
350
350
  isn't helpful to us.
@@ -353,7 +353,7 @@ If you need to submit the response token to the server in a different way than v
353
353
  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
354
  then you can either:
355
355
  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
356
+ predictable name/id), like `document.getElementById('g-recaptcha-response-data-my-action').value`, or
357
357
  2. write and specify a custom `callback` function. You may also want to pass `element: false` if you
358
358
  don't have a use for the hidden input element.
359
359
 
@@ -388,11 +388,12 @@ but only accepts the following options:
388
388
  | `: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
389
  | `:nonce` | Optional. Sets nonce attribute for script. Can be generated via `SecureRandom.base64(32)`. (default: `nil`) |
390
390
  | `: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]`) |
391
+ | `:id` | Specify a unique `id` attribute for the `<input>` element if using `element: :input`. (default: `"g-recaptcha-response-data-"` + `action`) |
392
+ | `:name` | Specify a unique `name` attribute for the `<input>` element if using `element: :input`. (default: `g-recaptcha-response-data[action]`) |
393
393
  | `:script` | Same as setting both `:inline_script` and `:external_script`. (default: `true`). |
394
394
  | `: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
395
  | `: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. |
396
+ | `:turbolinks` | If `true`, calls the js function which executes reCAPTCHA after all the dependencies have been loaded. This cannot be used with the js param `:onload`. This makes reCAPTCHAv3 usable with turbolinks. |
396
397
 
397
398
  [JavaScript resource (api.js) parameters](https://developers.google.com/recaptcha/docs/invisible#js_param):
398
399
 
@@ -434,11 +435,27 @@ result_b = verify_recaptcha(action: 'b')
434
435
  ```
435
436
 
436
437
  Because the response tokens for multiple actions may be submitted together in the same request, they
437
- are passed as a hash under `params['g-recaptcha-response']` with the action as the key.
438
+ are passed as a hash under `params['g-recaptcha-response-data']` with the action as the key.
438
439
 
439
440
  It is recommended to pass `external_script: false` on all but one of the calls to
440
441
  `recaptcha` since you only need to include the script tag once for a given `site_key`.
441
442
 
443
+ ## `recaptcha_reply`
444
+
445
+ 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.
446
+
447
+ ```ruby
448
+ if verify_recaptcha(action: 'login')
449
+ redirect_to @user
450
+ else
451
+ score = recaptcha_reply['score']
452
+ Rails.logger.warn("User #{@user.id} was denied login because of a recaptcha score of #{score}")
453
+ render 'new'
454
+ end
455
+ ```
456
+
457
+ `recaptcha_reply` will return `nil` if the the reply was not yet fetched.
458
+
442
459
  ## I18n support
443
460
 
444
461
  reCAPTCHA supports the I18n gem (it comes with English translations)
@@ -501,4 +518,3 @@ verify_recaptcha secret_key: '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
501
518
  - Check out the [wiki](https://github.com/ambethia/recaptcha/wiki) and leave whatever you found valuable there.
502
519
  - [Add multiple widgets to the same page](https://github.com/ambethia/recaptcha/wiki/Add-multiple-widgets-to-the-same-page)
503
520
  - [Use Recaptcha with Devise](https://github.com/plataformatec/devise/wiki/How-To:-Use-Recaptcha-with-Devise)
504
-
@@ -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,9 @@ 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
+ turbolinks = options.delete(:turbolinks)
15
16
  options[:render] = site_key
16
17
  options[:script_async] ||= false
17
18
  options[:script_defer] ||= false
@@ -22,8 +23,13 @@ module Recaptcha
22
23
  end
23
24
  options[:class] = "g-recaptcha-response #{options[:class]}"
24
25
 
26
+ if turbolinks
27
+ options[:onload] = recaptcha_v3_execute_function_name(action)
28
+ end
25
29
  html, tag_attributes = components(options)
26
- if recaptcha_v3_inline_script?(options)
30
+ if turbolinks
31
+ html << recaptcha_v3_onload_script(site_key, action, callback, id, options)
32
+ elsif recaptcha_v3_inline_script?(options)
27
33
  html << recaptcha_v3_inline_script(site_key, action, callback, id, options)
28
34
  end
29
35
  case element
@@ -181,7 +187,6 @@ module Recaptcha
181
187
  function #{recaptcha_v3_execute_function_name(action)}() {
182
188
  grecaptcha.ready(function() {
183
189
  grecaptcha.execute('#{site_key}', {action: '#{action}'}).then(function(token) {
184
- //console.log('#{id}', token)
185
190
  #{callback}('#{id}', token)
186
191
  });
187
192
  });
@@ -205,6 +210,24 @@ module Recaptcha
205
210
  HTML
206
211
  end
207
212
 
213
+ private_class_method def self.recaptcha_v3_onload_script(site_key, action, callback, id, options = {})
214
+ nonce = options[:nonce]
215
+ nonce_attr = " nonce='#{nonce}'" if nonce
216
+
217
+ <<-HTML
218
+ <script#{nonce_attr}>
219
+ function #{recaptcha_v3_execute_function_name(action)}() {
220
+ grecaptcha.ready(function() {
221
+ grecaptcha.execute('#{site_key}', {action: '#{action}'}).then(function(token) {
222
+ #{callback}('#{id}', token)
223
+ });
224
+ });
225
+ };
226
+ #{recaptcha_v3_define_default_callback(callback) if recaptcha_v3_define_default_callback?(callback, action, options)}
227
+ </script>
228
+ HTML
229
+ end
230
+
208
231
  private_class_method def self.recaptcha_v3_inline_script?(options)
209
232
  !Recaptcha.skip_env?(options[:env]) &&
210
233
  options[:script] != false &&
@@ -217,7 +240,6 @@ module Recaptcha
217
240
  var element = document.getElementById(id);
218
241
  element.value = token;
219
242
  }
220
- </script>
221
243
  HTML
222
244
  end
223
245
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Recaptcha
4
- VERSION = '5.2.0'
4
+ VERSION = '5.5.0'
5
5
  end
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.2.0
4
+ version: 5.5.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: 2019-10-09 00:00:00.000000000 Z
11
+ date: 2020-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json