hcaptcha 7.0.1 → 7.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +63 -70
- data/lib/hcaptcha/helpers.rb +53 -43
- data/lib/hcaptcha/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4103929669b3b8601acea5112dcb3ce2008975be3c8609298ea387ef03d8195
|
4
|
+
data.tar.gz: 63402b16c6e3881ff5099c3c29f3c726801f7af6371abae7cf5d358fb2f9b5ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b12e0b36c8374214c5320d35883ebdd34046b4ccb2ec31fbdf206c9d24e59f1ec90ff06770ea6358c5aca83982fbb5ca923cc639a94ae3b3ffedf978d459c5c
|
7
|
+
data.tar.gz: 0264d37d64670c010827e0fd74eb5897e6f3741dde3d09dc0ee3d341de5831135b96787e7ca7e25803b0834799604f36a37582fcf1140fc2ede0b35f19357dd7
|
data/README.md
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
# hCaptcha
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/hcaptcha.svg)](https://badge.fury.io/rb/hcaptcha)
|
3
3
|
|
4
|
-
|
4
|
+
## Credits
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
* https://github.com/Retrospring/hcaptcha
|
7
|
+
* https://github.com/firstmoversadvantage/hcaptcha
|
8
|
+
* https://github.com/ambethia/recaptcha
|
9
|
+
|
10
|
+
## Overview
|
11
|
+
|
12
|
+
License: [MIT](http://creativecommons.org/licenses/MIT/)
|
13
|
+
Bugs: https://github.com/firstmoversadvantage/hcaptcha/issues
|
10
14
|
|
11
15
|
This gem provides helper methods for the [hCaptcha API](https://hcaptcha.com). In your
|
12
16
|
views you can use the `hcaptcha_tags` method to embed the needed javascript, and you can validate
|
@@ -18,27 +22,22 @@ Go to the [hCaptcha](https://hcaptcha.com/webmaster/signup) signup page to obtai
|
|
18
22
|
|
19
23
|
The hostname you set it to must be a real hostname, since hCaptcha validates it when you create it in the portal. For example, `example.fmadata.com` does not have a DNS record, but `mydomain.com` does. The DNS record doesn't need to point to your application though, it just has to exist - that's why we added the record into the local hosts file.
|
20
24
|
|
21
|
-
##
|
25
|
+
## Installation
|
22
26
|
|
23
|
-
|
24
|
-
|
27
|
+
FIrst, add the gem to your bundle:
|
28
|
+
```shell
|
29
|
+
bundle add hcaptcha
|
25
30
|
```
|
26
31
|
|
27
|
-
|
32
|
+
Then, set the following environment variables:
|
33
|
+
* `HCAPTCHA_SECRET_KEY`
|
34
|
+
* `HCAPTCHA_SITE_KEY`
|
28
35
|
|
29
|
-
|
36
|
+
> 💡 You should keep keys out of your codebase with external environment variables (using your shell's `export` command), Rails (< 5.2) [secrets](https://guides.rubyonrails.org/v5.1/security.html#custom-secrets), Rails (5.2+) [credentials](https://guides.rubyonrails.org/security.html#custom-credentials), the [dotenv](https://github.com/bkeepers/dotenv) or [figaro](https://github.com/laserlemon/figaro) gems, …
|
30
37
|
|
31
|
-
|
32
|
-
keys. See also the
|
33
|
-
[Configuration](https://www.rubydoc.info/github/ambethia/recaptcha/master/Recaptcha/Configuration)
|
34
|
-
documentation.
|
38
|
+
## Usage
|
35
39
|
|
36
|
-
|
37
|
-
export HCAPTCHA_SITE_KEY='6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
|
38
|
-
export HCAPTCHA_SECRET_KEY='6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
|
39
|
-
```
|
40
|
-
|
41
|
-
Add `hcaptcha_tags` to the forms you want to protect:
|
40
|
+
First, add `hcaptcha_tags` to the forms you want to protect:
|
42
41
|
|
43
42
|
```erb
|
44
43
|
<%= form_for @foo do |f| %>
|
@@ -60,26 +59,56 @@ else
|
|
60
59
|
end
|
61
60
|
```
|
62
61
|
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
If you are **not using Rails**, you should:
|
63
|
+
* `include Hcaptcha::Adapters::ViewMethods` where you need `recaptcha_tags`
|
64
|
+
* `include Hcaptcha::Adapters::ControllerMethods` where you need `verify_hcaptcha`
|
66
65
|
|
67
|
-
|
68
|
-
- set env variables
|
69
|
-
- `include Hcaptcha::Adapters::ViewMethods` where you need `recaptcha_tags`
|
70
|
-
- `include Hcaptcha::Adapters::ControllerMethods` where you need `verify_recaptcha`
|
66
|
+
### API details
|
71
67
|
|
72
|
-
|
73
|
-
## hCaptcha API and Usage
|
74
|
-
|
75
|
-
### `recaptcha_tags`
|
68
|
+
### `hcaptcha_tags(options = {})`
|
76
69
|
|
77
70
|
Use in your views to render the JavaScript widget.
|
78
71
|
|
72
|
+
Available options:
|
73
|
+
|
74
|
+
| Option | Description |
|
75
|
+
|-------------------------|-------------|
|
76
|
+
| `:badge` | _legacy, ignored_
|
77
|
+
| `:callback` | _see [official documentation](https://docs.hcaptcha.com/configuration)_
|
78
|
+
| `:chalexpired_callback` | _see [official documentation](https://docs.hcaptcha.com/configuration)_
|
79
|
+
| `:class` | Additional CSS classes added to `h-captcha` on the placeholder
|
80
|
+
| `:close_callback` | _see [official documentation](https://docs.hcaptcha.com/configuration)_
|
81
|
+
| `:error_callback` | _see [official documentation](https://docs.hcaptcha.com/configuration)_
|
82
|
+
| `:expired_callback` | _see [official documentation](https://docs.hcaptcha.com/configuration)_
|
83
|
+
| `:external_script` | _alias for `:script` option_
|
84
|
+
| `:hl` | _see [official documentation](https://docs.hcaptcha.com/configuration) and [available language codes](https://docs.hcaptcha.com/languages)_
|
85
|
+
| `:open_callback` | _see [official documentation](https://docs.hcaptcha.com/configuration)_
|
86
|
+
| `:nonce` | Add a `nonce="…"` attribute to the `<script>` tag
|
87
|
+
| `:onload` | _see [official documentation](https://docs.hcaptcha.com/configuration)_
|
88
|
+
| `:recaptchacompat` | _see [official documentation](https://docs.hcaptcha.com/configuration)_
|
89
|
+
| `:render` | _see [official documentation](https://docs.hcaptcha.com/configuration)_
|
90
|
+
| `:script_async` | Add `async` attribute to the `<script>` tag (default: `true`)
|
91
|
+
| `:script_defer` | Add `defer` attribute to the `<script>` tag (default: `true`)
|
92
|
+
| `:script` | Generate the `<script>` tag (default: `true`)
|
93
|
+
| `:site_key` | Set hCaptcha Site Key (overrides `HCAPTCHA_SITE_KEY` environment variable)
|
94
|
+
| `:size` | _see [official documentation](https://docs.hcaptcha.com/configuration)_
|
95
|
+
| `:stoken` | _legacy, raises an exception_
|
96
|
+
| `:ssl` | _legacy, raises an exception_
|
97
|
+
| `:theme` | _see [official documentation](https://docs.hcaptcha.com/configuration)_ (default: `:dark`)
|
98
|
+
| `:type` | _legacy, ignored_
|
99
|
+
| `:ui` | _legacy, ignored_
|
100
|
+
|
101
|
+
> ℹ️ Unkown options will be passed directly as attributes to the placeholder element.
|
102
|
+
>
|
103
|
+
> For example, `hcaptcha_tags(foo: "bar")` will generate the default script tag and the following placeholder tag:
|
104
|
+
> ```html
|
105
|
+
> <div class="h-captcha" data-sitekey="…" foo="bar"></div>
|
106
|
+
> ```
|
107
|
+
|
79
108
|
### `verify_recaptcha`
|
80
109
|
|
81
110
|
This method returns `true` or `false` after processing the response token from the hCaptcha widget.
|
82
|
-
This is usually called from your controller
|
111
|
+
This is usually called from your controller.
|
83
112
|
|
84
113
|
Passing in the ActiveRecord object via `model: object` is optional. If you pass a `model`—and the
|
85
114
|
captcha fails to verify—an error will be added to the object for you to use (available as
|
@@ -120,41 +149,5 @@ en:
|
|
120
149
|
By default, hCaptcha is skipped in "test" and "cucumber" env. To enable it during test:
|
121
150
|
|
122
151
|
```ruby
|
123
|
-
|
124
|
-
```
|
125
|
-
|
126
|
-
## Alternative API key setup
|
127
|
-
|
128
|
-
### Recaptcha.configure
|
129
|
-
|
130
|
-
```ruby
|
131
|
-
# config/initializers/recaptcha.rb
|
132
|
-
Recaptcha.configure do |config|
|
133
|
-
config.site_key = '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
|
134
|
-
config.secret_key = '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
|
135
|
-
# Uncomment the following line if you are using a proxy server:
|
136
|
-
# config.proxy = 'http://myproxy.com.au:8080'
|
137
|
-
end
|
138
|
-
```
|
139
|
-
|
140
|
-
### Recaptcha.with_configuration
|
141
|
-
|
142
|
-
For temporary overwrites (not thread safe).
|
143
|
-
|
144
|
-
```ruby
|
145
|
-
Recaptcha.with_configuration(site_key: '12345') do
|
146
|
-
# Do stuff with the overwritten site_key.
|
147
|
-
end
|
148
|
-
```
|
149
|
-
|
150
|
-
### Per call
|
151
|
-
|
152
|
-
Pass in keys as options at runtime, for code base with multiple hCaptcha setups:
|
153
|
-
|
154
|
-
```ruby
|
155
|
-
recaptcha_tags site_key: '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
|
156
|
-
|
157
|
-
# and
|
158
|
-
|
159
|
-
verify_recaptcha secret_key: '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
|
160
|
-
```
|
152
|
+
Hcaptcha.configuration.skip_verify_env.delete("test")
|
153
|
+
```
|
data/lib/hcaptcha/helpers.rb
CHANGED
@@ -6,6 +6,13 @@ module Hcaptcha
|
|
6
6
|
hcaptcha_unreachable: 'Oops, we failed to validate your hCaptcha response. Please try again.',
|
7
7
|
verification_failed: 'hCaptcha verification failed, please try again.'
|
8
8
|
}.freeze
|
9
|
+
DEFAULT_OPTIONS = {
|
10
|
+
external_script: true,
|
11
|
+
script: true,
|
12
|
+
script_async: true,
|
13
|
+
script_defer: true,
|
14
|
+
theme: :dark
|
15
|
+
}.freeze
|
9
16
|
|
10
17
|
def self.hcaptcha(options)
|
11
18
|
if options.key?(:stoken)
|
@@ -15,13 +22,7 @@ module Hcaptcha
|
|
15
22
|
raise(HcaptchaError, "SSL is now always true. Please remove 'ssl' from your calls to hcaptcha_tags.")
|
16
23
|
end
|
17
24
|
|
18
|
-
html
|
19
|
-
html << %(<div #{tag_attributes}></div>\n)
|
20
|
-
|
21
|
-
html << <<-HTML
|
22
|
-
<div class="h-captcha" data-sitekey="#{Hcaptcha.configuration.site_key!}" data-theme="dark"></div>
|
23
|
-
HTML
|
24
|
-
|
25
|
+
html = generate_tags(options)
|
25
26
|
html.respond_to?(:html_safe) ? html.html_safe : html
|
26
27
|
end
|
27
28
|
|
@@ -40,54 +41,63 @@ module Hcaptcha
|
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
43
|
-
private_class_method def self.
|
44
|
-
html = +''
|
45
|
-
attributes = {}
|
46
|
-
|
44
|
+
private_class_method def self.generate_tags(options)
|
47
45
|
options = options.dup
|
48
|
-
|
49
|
-
|
50
|
-
hl = options.delete(:hl)
|
51
|
-
onload = options.delete(:onload)
|
52
|
-
render = options.delete(:render)
|
53
|
-
script_async = options.delete(:script_async)
|
54
|
-
script_defer = options.delete(:script_defer)
|
55
|
-
nonce = options.delete(:nonce)
|
56
|
-
skip_script = (options.delete(:script) == false) || (options.delete(:external_script) == false)
|
57
|
-
ui = options.delete(:ui)
|
58
|
-
|
59
|
-
data_attribute_keys = [:badge, :theme, :type, :callback, :expired_callback, :error_callback, :size]
|
60
|
-
data_attribute_keys << :tabindex unless ui == :button
|
61
|
-
data_attributes = {}
|
62
|
-
data_attribute_keys.each do |data_attribute|
|
63
|
-
value = options.delete(data_attribute)
|
64
|
-
data_attributes["data-#{data_attribute.to_s.tr('_', '-')}"] = value if value
|
46
|
+
DEFAULT_OPTIONS.each do |name, value|
|
47
|
+
options[name] = value unless options.key?(name)
|
65
48
|
end
|
49
|
+
generate_script_tag(options) + generate_placeholder_tag(options)
|
50
|
+
end
|
66
51
|
|
67
|
-
|
68
|
-
|
52
|
+
private_class_method def self.generate_script_tag(options)
|
53
|
+
# Forge script URL
|
54
|
+
url = Hcaptcha.configuration.api_server_url
|
69
55
|
query_params = hash_to_query(
|
70
|
-
hl: hl,
|
71
|
-
onload: onload,
|
72
|
-
|
56
|
+
hl: options.delete(:hl),
|
57
|
+
onload: options.delete(:onload),
|
58
|
+
recaptchacompat: options.delete(:recaptchacompat),
|
59
|
+
render: options.delete(:render)
|
73
60
|
)
|
74
|
-
|
75
|
-
|
76
|
-
|
61
|
+
url += "?#{query_params}" unless query_params.empty?
|
62
|
+
|
63
|
+
# Forge additional attributes
|
64
|
+
nonce = options.delete(:nonce)
|
77
65
|
nonce_attr = " nonce='#{nonce}'" if nonce
|
78
|
-
|
79
|
-
|
80
|
-
|
66
|
+
async_attr = "async" if options.delete(:script_async)
|
67
|
+
defer_attr = "defer" if options.delete(:script_defer)
|
68
|
+
additional_attributes = [async_attr, defer_attr, nonce_attr].compact.join(" ")
|
81
69
|
|
82
|
-
|
83
|
-
attributes["class"] = "hcaptcha #{class_attribute}"
|
84
|
-
tag_attributes = attributes.merge(options).map { |k, v| %(#{k}="#{v}") }.join(" ")
|
70
|
+
return "" if options.delete(:script) == false || options.delete(:external_script) == false
|
85
71
|
|
86
|
-
|
72
|
+
%(<script src="#{url}" #{additional_attributes}></script>)
|
73
|
+
end
|
74
|
+
|
75
|
+
private_class_method def self.generate_placeholder_tag(options)
|
76
|
+
attributes = {}
|
77
|
+
|
78
|
+
# Forge data-* attributes
|
79
|
+
%i[
|
80
|
+
callback close_callback error_callback chalexpired_callback
|
81
|
+
expired_callback open_callback size tabindex theme
|
82
|
+
].each do |data_attribute|
|
83
|
+
value = options.delete(data_attribute)
|
84
|
+
attributes["data-#{data_attribute.to_s.tr('_', '-')}"] = value if value
|
85
|
+
end
|
86
|
+
attributes["data-sitekey"] = options.delete(:site_key) || Hcaptcha.configuration.site_key!
|
87
|
+
|
88
|
+
# Forge CSS classes
|
89
|
+
attributes["class"] = "h-captcha #{options.delete(:class)}"
|
90
|
+
|
91
|
+
# Remaining options will be added as attributes on the tag.
|
92
|
+
%(<div #{html_attributes(attributes)} #{html_attributes(options)}></div>)
|
87
93
|
end
|
88
94
|
|
89
95
|
private_class_method def self.hash_to_query(hash)
|
90
96
|
hash.delete_if { |_, val| val.nil? || val.empty? }.to_a.map { |pair| pair.join('=') }.join('&')
|
91
97
|
end
|
98
|
+
|
99
|
+
private_class_method def self.html_attributes(hash)
|
100
|
+
hash.map { |k, v| %(#{k}="#{v}") }.join(" ")
|
101
|
+
end
|
92
102
|
end
|
93
103
|
end
|
data/lib/hcaptcha/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hcaptcha
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.0
|
4
|
+
version: 7.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christopher Harrison
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|