recaptcha 5.2.1 → 5.6.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: 1308b1cf9b9c14d9df6c9fe04eebfd241406e7afa31fbd522df8296ac7b0392a
4
- data.tar.gz: 9771326e251bbf449107fe8a3a3a9b52c8b0a3b2e99858c3867d9867b690408a
3
+ metadata.gz: 849f0b2edee6bde557c0bdab3802dfbc7528a5e777709a110b6c4f228842c1a1
4
+ data.tar.gz: ebf65ad28a50a06363bc7544df1ef2639aefebbeace7f15cd97fd1ffc047764c
5
5
  SHA512:
6
- metadata.gz: 5eaae94b79027b794a1baaa5e0c46bf976356fa90e3008d7452fc5b109b08ba79a4f48aaf2c6f24bbfd039f1ee5949d45db7c9b7a8ba98fe10776d241bc894d2
7
- data.tar.gz: a18343d8c7a9162c2963992af87471d5bdcebf3123a95bba777d4223a8cfb9af776c0fb2dca7c89b2d9e1214aa0a72ad707f9fe1c8e5a23c91c80a787232b942
6
+ metadata.gz: 68f606e91517a8062d7afe48e43d306383f4ef4c83ac4c61179f9ea58d38628230768865604a61758bfd3d5b0d1a2197a981b764169153e36ef0bcf7bedb86d9
7
+ data.tar.gz: c87318df857db04fb2485c73ba686d82f3d18ed87cc0db8f006bbe2f456179218aeb25b1477017b80240504329cc9d02acd9b09457ae927997a5b61dd6849228
@@ -1,5 +1,20 @@
1
1
  ## Next
2
2
 
3
+ ## 5.5.0
4
+ * add `recaptcha_reply` controller method for better debugging/inspection
5
+
6
+ ## 5.4.1
7
+ * fix v2 vs 'data' postfix
8
+
9
+ ## 5.4.0
10
+ * added 'data' postfix to g-recaptcha-response attribute name to avoid collisions
11
+
12
+ ## 5.3.0
13
+ * turbolinks support
14
+
15
+ ## 5.2.0
16
+ * remove dependency on rails methods
17
+
3
18
  ## 5.1.0
4
19
  * Added default translations for rails/i18n
5
20
  * use recaptcha.net for the script tag
data/README.md CHANGED
@@ -119,7 +119,7 @@ The following options are available:
119
119
  Any unrecognized options will be added as attributes on the generated tag.
120
120
 
121
121
  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)
122
+ 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
123
  to see these options.
124
124
 
125
125
  Note that you cannot submit/verify the same response token more than once or you will get a
@@ -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
 
@@ -278,7 +278,7 @@ threshold:
278
278
  <% if @show_checkbox_recaptcha %>
279
279
  <%= recaptcha_tags %>
280
280
  <% else %>
281
- <%= recaptcha_v3(action: 'login') %>
281
+ <%= recaptcha_v3(action: 'login', site_key: ENV['RECAPTCHA_SITE_KEY_V3']) %>
282
282
  <% end %>
283
283
 
284
284
  ```
@@ -286,7 +286,7 @@ threshold:
286
286
  ```ruby
287
287
  # app/controllers/sessions_controller.rb
288
288
  def create
289
- success = verify_recaptcha(action: 'login', minimum_score: 0.5)
289
+ success = verify_recaptcha(action: 'login', minimum_score: 0.5, secret_key: ENV['RECAPTCHA_SECRET_KEY_V3'])
290
290
  checkbox_success = verify_recaptcha unless success
291
291
  if success || checkbox_success
292
292
  # Perform action
@@ -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 &&
@@ -248,6 +271,7 @@ module Recaptcha
248
271
  private_class_method def self.default_callback(options = {})
249
272
  nonce = options[:nonce]
250
273
  nonce_attr = " nonce='#{nonce}'" if nonce
274
+ selector_attr = options[:id] ? "##{options[:id]}" : ".g-recaptcha"
251
275
 
252
276
  <<-HTML
253
277
  <script#{nonce_attr}>
@@ -260,9 +284,9 @@ module Recaptcha
260
284
  return curEle.nodeName === 'FORM' ? curEle : null
261
285
  };
262
286
 
263
- var eles = document.getElementsByClassName('g-recaptcha');
264
- if (eles.length > 0) {
265
- var form = closestForm(eles[0]);
287
+ var el = document.querySelector("#{selector_attr}")
288
+ if (!!el) {
289
+ var form = closestForm(el);
266
290
  if (form) {
267
291
  form.submit();
268
292
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Recaptcha
4
- VERSION = '5.2.1'
4
+ VERSION = '5.6.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.1
4
+ version: 5.6.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-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -175,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
175
175
  - !ruby/object:Gem::Version
176
176
  version: '0'
177
177
  requirements: []
178
- rubygems_version: 3.0.3
178
+ rubygems_version: 3.1.3
179
179
  signing_key:
180
180
  specification_version: 4
181
181
  summary: Helpers for the reCAPTCHA API