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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5011fee9db065c86faf1507c11e0d3000ad61e19d05e7102e8bcf3750abcd52f
4
- data.tar.gz: bd104ffe4aeb3436c1d365a293c66f80d9d2e42c543b009ea596ac83d9a84db2
3
+ metadata.gz: 22b983b8b83c0fb6eee4d4a97e3680c2c8e44c305c9181aee11e57f995f545e4
4
+ data.tar.gz: 97a7ec072f6158d49c0f65f73d3d8c6ee90725306ff0de87af5dd21ce1fc5184
5
5
  SHA512:
6
- metadata.gz: e1c5608b8671bfef9edfec01531f575fe3a83c12a00dd72090a772686f2fef56ab6436e323dc7ca7daa1b82d30764ca03a2f89d6727145f593d377d1c057fe51
7
- data.tar.gz: 811827be3f2a2bd4a18a1004377605c8db09c1279658371d2191e27226afd6557235c8747a5c39ec82a65bc443bb4590dcced9fff96d8be4fba946d21a07a50d
6
+ metadata.gz: 1d77948f8fe547ccf52da9d92389f170ce43bdaab80cdcf246f80fde50db6773134c305e7edc0a162036f4c6d5a98f75342679dc7915c44ba37c727168d35f3f
7
+ data.tar.gz: 687063c83c44dbae9a65ba75664c8240e7915464738aea41b38bf4e089aab7945fc2b22dda64814bdab85b7ae241439d7dd8dfccfe56a3f16b26b6b9ee145ecf
@@ -3,9 +3,9 @@ cache: bundler
3
3
  sudo: false
4
4
  rvm:
5
5
  - ruby-head
6
- - 2.6.2
7
- - 2.5.5
8
- - 2.4.5
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.5
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.2
33
+ - rvm: 2.6.5
34
34
  gemfile: gemfiles/rails_3.2.gemfile
35
- - rvm: 2.5.5
35
+ - rvm: 2.5.7
36
36
  gemfile: gemfiles/rails_3.2.gemfile
37
- - rvm: 2.4.5
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
@@ -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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  gemspec
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, since there is no extra steps for real users, but for the bots.
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 are able to define your own callback by passing a method to the `on_spam` option:
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
- def your_spam_callback_method
59
- redirect_to root_path
60
- end
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 (nor 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:
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 you controller:
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 english ones in your own i18n config files as well as add new ones for other locales.
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
- # test/test_helper.rb, spec/rails_helper.rb, ...
169
- InvisibleCaptcha.timestamp_enabled = false
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
  require 'rspec/core/rake_task'
3
5
 
@@ -22,4 +22,3 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency 'test-unit', '~> 3.0'
23
23
  spec.add_development_dependency 'byebug'
24
24
  end
25
-
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'invisible_captcha/version'
2
4
  require 'invisible_captcha/controller_ext'
3
5
  require 'invisible_captcha/view_helpers'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module InvisibleCaptcha
2
4
  module ControllerExt
3
5
  module ClassMethods
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module InvisibleCaptcha
2
4
  module FormHelpers
3
5
  def invisible_captcha(honeypot, options = {})
4
6
  @template.invisible_captcha(honeypot, self.object_name, options)
5
7
  end
6
8
  end
7
- end
9
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module InvisibleCaptcha
2
4
  class Railtie < Rails::Railtie
3
5
  initializer 'invisible_captcha.rails_integration' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module InvisibleCaptcha
2
- VERSION = "0.12.2"
4
+ VERSION = "0.13.0"
3
5
  end
@@ -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
- content_tag(:style, media: 'screen') do
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
@@ -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 ::Rails::VERSION::STRING > '5'
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 ::Rails::VERSION::STRING > '5'
15
+ if Rails.version > '5'
14
16
  put action, params: params
15
17
  else
16
18
  put action, params
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts .js
2
+ //= link_directory ../stylesheets .css
@@ -39,4 +39,4 @@ Dummy::Application.configure do
39
39
 
40
40
  # Print deprecation notices to the stderr.
41
41
  config.active_support.deprecation = :stderr
42
- end
42
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe InvisibleCaptcha do
2
4
  it 'initialize with defaults' do
3
5
  InvisibleCaptcha.init!
@@ -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
@@ -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.12.2
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-08-27 00:00:00.000000000 Z
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