invisible_captcha 0.12.2 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +8 -8
- data/CHANGELOG.md +6 -0
- data/Gemfile +2 -0
- data/README.md +67 -12
- data/Rakefile +2 -0
- data/invisible_captcha.gemspec +0 -1
- data/lib/invisible_captcha.rb +2 -0
- data/lib/invisible_captcha/controller_ext.rb +2 -0
- data/lib/invisible_captcha/form_helpers.rb +3 -1
- data/lib/invisible_captcha/railtie.rb +2 -0
- data/lib/invisible_captcha/version.rb +3 -1
- data/lib/invisible_captcha/view_helpers.rb +9 -1
- data/spec/controllers_spec.rb +4 -2
- data/spec/dummy/app/assets/config/manifest.js +2 -0
- data/spec/dummy/config/environments/test.rb +1 -1
- data/spec/invisible_captcha_spec.rb +2 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/view_helpers_spec.rb +12 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 22b983b8b83c0fb6eee4d4a97e3680c2c8e44c305c9181aee11e57f995f545e4
|
4
|
+
data.tar.gz: 97a7ec072f6158d49c0f65f73d3d8c6ee90725306ff0de87af5dd21ce1fc5184
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d77948f8fe547ccf52da9d92389f170ce43bdaab80cdcf246f80fde50db6773134c305e7edc0a162036f4c6d5a98f75342679dc7915c44ba37c727168d35f3f
|
7
|
+
data.tar.gz: 687063c83c44dbae9a65ba75664c8240e7915464738aea41b38bf4e089aab7945fc2b22dda64814bdab85b7ae241439d7dd8dfccfe56a3f16b26b6b9ee145ecf
|
data/.travis.yml
CHANGED
@@ -3,9 +3,9 @@ cache: bundler
|
|
3
3
|
sudo: false
|
4
4
|
rvm:
|
5
5
|
- ruby-head
|
6
|
-
- 2.6.
|
7
|
-
- 2.5.
|
8
|
-
- 2.4.
|
6
|
+
- 2.6.5
|
7
|
+
- 2.5.7
|
8
|
+
- 2.4.9
|
9
9
|
- 2.3.8
|
10
10
|
- 2.2.10
|
11
11
|
gemfile:
|
@@ -22,7 +22,7 @@ before_install:
|
|
22
22
|
- rvm @global do yes | gem install bundler -v '< 2'
|
23
23
|
matrix:
|
24
24
|
exclude:
|
25
|
-
- rvm: 2.4.
|
25
|
+
- rvm: 2.4.9
|
26
26
|
gemfile: gemfiles/rails_6.0.gemfile
|
27
27
|
- rvm: 2.3.8
|
28
28
|
gemfile: gemfiles/rails_6.0.gemfile
|
@@ -30,11 +30,11 @@ matrix:
|
|
30
30
|
gemfile: gemfiles/rails_6.0.gemfile
|
31
31
|
- rvm: ruby-head
|
32
32
|
gemfile: gemfiles/rails_3.2.gemfile
|
33
|
-
- rvm: 2.6.
|
33
|
+
- rvm: 2.6.5
|
34
34
|
gemfile: gemfiles/rails_3.2.gemfile
|
35
|
-
- rvm: 2.5.
|
35
|
+
- rvm: 2.5.7
|
36
36
|
gemfile: gemfiles/rails_3.2.gemfile
|
37
|
-
- rvm: 2.4.
|
37
|
+
- rvm: 2.4.9
|
38
38
|
gemfile: gemfiles/rails_3.2.gemfile
|
39
39
|
allow_failures:
|
40
|
-
- rvm: ruby-head
|
40
|
+
- rvm: ruby-head
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
+
## [0.13.0]
|
6
|
+
|
7
|
+
- Add support for the Content Security Policy nonce (#61)
|
8
|
+
- Freeze all strings (#60)
|
9
|
+
|
5
10
|
## [0.12.2]
|
6
11
|
|
7
12
|
- Allow new timestamp to be set during `on_timestamp_spam` callback (#53)
|
@@ -101,6 +106,7 @@ All notable changes to this project will be documented in this file.
|
|
101
106
|
|
102
107
|
- First version of controller filters
|
103
108
|
|
109
|
+
[0.13.0]: https://github.com/markets/invisible_captcha/compare/v0.12.2...v0.13.0
|
104
110
|
[0.12.2]: https://github.com/markets/invisible_captcha/compare/v0.12.1...v0.12.2
|
105
111
|
[0.12.1]: https://github.com/markets/invisible_captcha/compare/v0.12.0...v0.12.1
|
106
112
|
[0.12.0]: https://github.com/markets/invisible_captcha/compare/v0.11.0...v0.12.0
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -7,13 +7,13 @@
|
|
7
7
|
|
8
8
|
Invisible Captcha provides different techniques to protect your application against spambots.
|
9
9
|
|
10
|
-
The main protection is a solution based on the `honeypot` principle, which provides a better user experience
|
10
|
+
The main protection is a solution based on the `honeypot` principle, which provides a better user experience since there are no extra steps for real users, only for the bots.
|
11
11
|
|
12
12
|
Essentially, the strategy consists on adding an input field :honey_pot: into the form that:
|
13
13
|
|
14
14
|
- shouldn't be visible by the real users
|
15
15
|
- should be left empty by the real users
|
16
|
-
- will most be filled by spam bots
|
16
|
+
- will most likely be filled by spam bots
|
17
17
|
|
18
18
|
It also comes with a time-sensitive :hourglass: form submission.
|
19
19
|
|
@@ -47,7 +47,7 @@ class TopicsController < ApplicationController
|
|
47
47
|
end
|
48
48
|
```
|
49
49
|
|
50
|
-
This method will act as a `before_action` that triggers when spam is detected (honeypot field has some value). By default it responds with no content (only headers: `head(200)`). This is a good default, since the bot will surely read the response code and will think that it has achieved to submit the form properly. But, anyway, you
|
50
|
+
This method will act as a `before_action` that triggers when spam is detected (honeypot field has some value). By default, it responds with no content (only headers: `head(200)`). This is a good default, since the bot will surely read the response code and will think that it has achieved to submit the form properly. But, anyway, you can define your own callback by passing a method to the `on_spam` option:
|
51
51
|
|
52
52
|
```ruby
|
53
53
|
class TopicsController < ApplicationController
|
@@ -55,13 +55,13 @@ class TopicsController < ApplicationController
|
|
55
55
|
|
56
56
|
private
|
57
57
|
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
def your_spam_callback_method
|
59
|
+
redirect_to root_path
|
60
|
+
end
|
61
61
|
end
|
62
62
|
```
|
63
63
|
|
64
|
-
Note that is not mandatory to specify a `honeypot` attribute (
|
64
|
+
Note that it is not mandatory to specify a `honeypot` attribute (neither in the view nor in the controller). In this case, the engine will take a random field from `InvisibleCaptcha.honeypots`. So, if you're integrating it following this path, in your form:
|
65
65
|
|
66
66
|
```erb
|
67
67
|
<%= form_tag(new_contact_path) do |f| %>
|
@@ -69,12 +69,32 @@ Note that is not mandatory to specify a `honeypot` attribute (nor in the view, n
|
|
69
69
|
<% end %>
|
70
70
|
```
|
71
71
|
|
72
|
-
In
|
72
|
+
In your controller:
|
73
73
|
|
74
74
|
```
|
75
75
|
invisible_captcha only: [:new_contact]
|
76
76
|
```
|
77
77
|
|
78
|
+
`invisible_captcha` sends all messages to `flash[:error]`. For messages to appear on your pages, add `<%= flash[:error] %>` to `app/views/layouts/application.html.erb` (somewhere near the top of your `<body>` element):
|
79
|
+
|
80
|
+
```erb
|
81
|
+
<!DOCTYPE html>
|
82
|
+
<html>
|
83
|
+
<head>
|
84
|
+
<title>Yet another Rails app</title>
|
85
|
+
<%= stylesheet_link_tag "application", media: "all" %>
|
86
|
+
<%= javascript_include_tag "application" %>
|
87
|
+
<%= csrf_meta_tags %>
|
88
|
+
</head>
|
89
|
+
<body>
|
90
|
+
<%= flash[:error] %>
|
91
|
+
<%= yield %>
|
92
|
+
</body>
|
93
|
+
</html>
|
94
|
+
```
|
95
|
+
|
96
|
+
You can place `<%= flash[:error] %>` next to `:alert` and `:notice` message types, if you have them in your `app/views/layouts/application.html.erb`.
|
97
|
+
|
78
98
|
## Options and customization
|
79
99
|
|
80
100
|
This section contains a description of all plugin options and customizations.
|
@@ -145,6 +165,38 @@ You can also pass html options to the input:
|
|
145
165
|
<%= invisible_captcha :subtitle, :topic, id: "your_id", class: "your_class" %>
|
146
166
|
```
|
147
167
|
|
168
|
+
### Content Security Policy
|
169
|
+
|
170
|
+
If you're using a Content Security Policy (CSP) in your Rails app, you will need to generate a nonce on the server, and pass `nonce: true` attribute to the view helper. Uncomment the following lines in your `config/initializers/content_security_policy.rb` file:
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
# Be sure to restart your server when you modify this file.
|
174
|
+
|
175
|
+
# If you are using UJS then enable automatic nonce generation
|
176
|
+
Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
|
177
|
+
|
178
|
+
# Set the nonce only to specific directives
|
179
|
+
Rails.application.config.content_security_policy_nonce_directives = %w(style-src)
|
180
|
+
```
|
181
|
+
Note that if you are already generating nonce for scripts, you'd have to include `script-src` to `content_security_policy_nonce_directives` as well:
|
182
|
+
|
183
|
+
```ruby
|
184
|
+
Rails.application.config.content_security_policy_nonce_directives = %w(script-src style-src)
|
185
|
+
```
|
186
|
+
|
187
|
+
And in your view helper, you need to pass `nonce: true` to the `invisible_captcha` helper:
|
188
|
+
|
189
|
+
```erb
|
190
|
+
<%= invisible_captcha nonce: true %>
|
191
|
+
```
|
192
|
+
|
193
|
+
**WARNING:** Content Security Policy can break your site! If you already run a website with third-party scripts, styles, images, and fonts, it is highly recommended to enable CSP in report-only mode and observe warnings as they appear. Learn more at MDN:
|
194
|
+
|
195
|
+
* https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
|
196
|
+
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
|
197
|
+
|
198
|
+
Note that Content Security Policy only works on Rails 5.2 and up.
|
199
|
+
|
148
200
|
### I18n
|
149
201
|
|
150
202
|
`invisible_captcha` tries to use I18n when it's available by default. The keys it looks for are the following:
|
@@ -156,17 +208,20 @@ en:
|
|
156
208
|
timestamp_error_message: "Sorry, that was too quick! Please resubmit."
|
157
209
|
```
|
158
210
|
|
159
|
-
You can override the
|
211
|
+
You can override the English ones in your i18n config files as well as add new ones for other locales.
|
160
212
|
|
161
213
|
If you intend to use I18n with `invisible_captcha`, you _must not_ set `sentence_for_humans` or `timestamp_error_message` to strings in the setup phase.
|
162
214
|
|
163
215
|
## Testing your controllers
|
164
216
|
|
165
|
-
If you're encountering unexpected behaviour while testing controllers that use the `invisible_captcha` action filter, you may want to disable timestamp check for the test environment:
|
217
|
+
If you're encountering unexpected behaviour while testing controllers that use the `invisible_captcha` action filter, you may want to disable timestamp check for the test environment. Add the following snippet to the `config/initializers/invisible_captcha.rb` file:
|
166
218
|
|
167
219
|
```ruby
|
168
|
-
#
|
169
|
-
|
220
|
+
# Be sure to restart your server when you modify this file.
|
221
|
+
|
222
|
+
InvisibleCaptcha.setup do |config|
|
223
|
+
config.timestamp_enabled = !Rails.env.test?
|
224
|
+
end
|
170
225
|
```
|
171
226
|
|
172
227
|
Another option is to wait for the timestamp check to be valid:
|
data/Rakefile
CHANGED
data/invisible_captcha.gemspec
CHANGED
data/lib/invisible_captcha.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module InvisibleCaptcha
|
2
4
|
module ViewHelpers
|
3
5
|
# Builds the honeypot html
|
@@ -54,7 +56,13 @@ module InvisibleCaptcha
|
|
54
56
|
|
55
57
|
return if visible
|
56
58
|
|
57
|
-
|
59
|
+
nonce = if Rails.version >= '5.2'
|
60
|
+
content_security_policy_nonce if options[:nonce]
|
61
|
+
else
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
|
65
|
+
content_tag(:style, media: 'screen', nonce: nonce) do
|
58
66
|
".#{css_class} {#{InvisibleCaptcha.css_strategy}}"
|
59
67
|
end
|
60
68
|
end
|
data/spec/controllers_spec.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe InvisibleCaptcha::ControllerExt, type: :controller do
|
2
4
|
render_views
|
3
5
|
|
4
6
|
def switchable_post(action, params = {})
|
5
|
-
if
|
7
|
+
if Rails.version > '5'
|
6
8
|
post action, params: params
|
7
9
|
else
|
8
10
|
post action, params
|
@@ -10,7 +12,7 @@ RSpec.describe InvisibleCaptcha::ControllerExt, type: :controller do
|
|
10
12
|
end
|
11
13
|
|
12
14
|
def switchable_put(action, params = {})
|
13
|
-
if
|
15
|
+
if Rails.version > '5'
|
14
16
|
put action, params: params
|
15
17
|
else
|
16
18
|
put action, params
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
ENV['RAILS_ENV'] = 'test'
|
2
4
|
|
3
5
|
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
@@ -5,6 +7,9 @@ require 'rspec/rails'
|
|
5
7
|
require 'invisible_captcha'
|
6
8
|
|
7
9
|
RSpec.configure do |config|
|
10
|
+
if Rails.version >= '5.2'
|
11
|
+
config.include ActionDispatch::ContentSecurityPolicy::Request, type: :helper
|
12
|
+
end
|
8
13
|
config.disable_monkey_patching!
|
9
14
|
config.order = :random
|
10
15
|
config.expect_with :rspec
|
data/spec/view_helpers_spec.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe InvisibleCaptcha::ViewHelpers, type: :helper do
|
2
4
|
before(:each) do
|
3
5
|
allow(Time.zone).to receive(:now).and_return(Time.zone.parse('Feb 19 1986'))
|
4
6
|
allow(InvisibleCaptcha).to receive(:css_strategy).and_return("display:none;")
|
5
7
|
|
8
|
+
if Rails.version >= '5.2'
|
9
|
+
allow_any_instance_of(ActionDispatch::ContentSecurityPolicy::Request).to receive(:content_security_policy_nonce).and_return('123')
|
10
|
+
end
|
11
|
+
|
6
12
|
# to test content_for and provide
|
7
13
|
@view_flow = ActionView::OutputFlow.new
|
8
14
|
|
@@ -26,6 +32,12 @@ RSpec.describe InvisibleCaptcha::ViewHelpers, type: :helper do
|
|
26
32
|
expect(invisible_captcha(:subtitle, :topic, { class: 'foo_class' })).to match(/class="foo_class"/)
|
27
33
|
end
|
28
34
|
|
35
|
+
if Rails.version >= '5.2'
|
36
|
+
it 'with CSP nonce' do
|
37
|
+
expect(invisible_captcha(:subtitle, :topic, { nonce: true })).to match(/nonce="123"/)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
29
41
|
it 'generated html + styles' do
|
30
42
|
InvisibleCaptcha.honeypots = [:foo_id]
|
31
43
|
output = invisible_captcha.gsub("\"", "'")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: invisible_captcha
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc Anguera Insa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-11-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -113,6 +113,7 @@ files:
|
|
113
113
|
- spec/controllers_spec.rb
|
114
114
|
- spec/dummy/README.md
|
115
115
|
- spec/dummy/Rakefile
|
116
|
+
- spec/dummy/app/assets/config/manifest.js
|
116
117
|
- spec/dummy/app/assets/javascripts/application.js
|
117
118
|
- spec/dummy/app/assets/stylesheets/application.css
|
118
119
|
- spec/dummy/app/controllers/application_controller.rb
|
@@ -180,6 +181,7 @@ test_files:
|
|
180
181
|
- spec/controllers_spec.rb
|
181
182
|
- spec/dummy/README.md
|
182
183
|
- spec/dummy/Rakefile
|
184
|
+
- spec/dummy/app/assets/config/manifest.js
|
183
185
|
- spec/dummy/app/assets/javascripts/application.js
|
184
186
|
- spec/dummy/app/assets/stylesheets/application.css
|
185
187
|
- spec/dummy/app/controllers/application_controller.rb
|