invisible_captcha 2.1.0 → 2.3.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: f15e5223696c06e82c8ab6182a4396a9e4e4bf3acd6e425296e60cc6b49cb225
4
- data.tar.gz: e35b51231012ae92b236f81eb1966a16ea3c7b02862d03977bf23478d968538d
3
+ metadata.gz: 8421f23e2c4ca4f1512efe6f0ac5b7d538c21fae25c94dae1eb12080bcc7bff2
4
+ data.tar.gz: d80bbba59b964e84f677620a2c24a5047744a95733805981583034e3629034a4
5
5
  SHA512:
6
- metadata.gz: ccc4299595595e513fa8f8eb472233b83fa334608b3cd4fcba3d1316b8f1819d83e7cc3d2678dce0ac954c52a4b90ecf0643424d0358cd8dd3412c4aa04ac391
7
- data.tar.gz: 1fcceba58cb21d931e6d8f7f49a3a1649230628442e18f3664a80d5ac983dbec0bc5caeeda17cacc748bfbfabce93bd189f695bc0d123d4bd2ef0d94a20cdb3e
6
+ metadata.gz: 94f28d33d89e5dcfa741d97c34c4a42645a5d3f668238653341cd402c1e1e3bfbf8d2c42f5bc6d9d8bda3815d3e7036c0dae13965691e7409ce5df1ff5763bee
7
+ data.tar.gz: 2a187357840766a3eae1c40f032015c38f07a2b12955c9bfc82f95251b81138a6eab8e69ccd0adbfb9e5f13c095a541e869f2b3d5672e29a75b893253702965e
@@ -12,7 +12,7 @@ jobs:
12
12
  fail-fast: false
13
13
  matrix:
14
14
  ruby: ["2.7", "3.0", "3.1", "3.2"]
15
- gemfile: [rails_6.0, rails_6.1, rails_7.0]
15
+ gemfile: [rails_6.0, rails_6.1, rails_7.0, rails_7.1]
16
16
  exclude:
17
17
  - ruby: "3.1"
18
18
  gemfile: rails_6.0
data/Appraisals CHANGED
@@ -1,4 +1,5 @@
1
1
  %w(
2
+ 7.1
2
3
  7.0
3
4
  6.1
4
5
  6.0
data/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [2.3.0]
6
+
7
+ - Run honeypot + spinner checks and their callback also if timestamp triggers but passes through (#132)
8
+ - Mark as spam requests with no spinner value (#134)
9
+
10
+ ## [2.2.0]
11
+
12
+ - Official support for Rails 7.1
13
+ - Fix flash message for `on_timestamp_spam` callback (#125)
14
+ - Fix potential error when lookup the honeypot parameter using (#128)
15
+
5
16
  ## [2.1.0]
6
17
 
7
18
  - Drop official support for EOL Rubies: 2.5 and 2.6
@@ -130,6 +141,8 @@ All notable changes to this project will be documented in this file.
130
141
 
131
142
  - First version of controller filters
132
143
 
144
+ [2.3.0]: https://github.com/markets/invisible_captcha/compare/v2.2.0...v2.3.0
145
+ [2.2.0]: https://github.com/markets/invisible_captcha/compare/v2.1.0...v2.2.0
133
146
  [2.1.0]: https://github.com/markets/invisible_captcha/compare/v2.0.0...v2.1.0
134
147
  [2.0.0]: https://github.com/markets/invisible_captcha/compare/v1.1.0...v2.0.0
135
148
  [1.1.0]: https://github.com/markets/invisible_captcha/compare/v1.0.1...v1.1.0
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2012-2021 Marc Anguera Insa
1
+ Copyright 2012-2024 Marc Anguera Insa
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -287,7 +287,7 @@ end
287
287
  Another option is to wait for the timestamp check to be valid:
288
288
 
289
289
  ```ruby
290
- # Maybe in a before block
290
+ # Maybe inside a before block
291
291
  InvisibleCaptcha.init!
292
292
  InvisibleCaptcha.timestamp_threshold = 1
293
293
 
@@ -295,6 +295,26 @@ InvisibleCaptcha.timestamp_threshold = 1
295
295
  sleep InvisibleCaptcha.timestamp_threshold
296
296
  ```
297
297
 
298
+ If you're using the "random honeypot" approach, you may want to set a known honeypot:
299
+
300
+ ```ruby
301
+ config.honeypots = ['my_honeypot_field'] if Rails.env.test?
302
+ ```
303
+
304
+ And for the "spinner validation" check, you may want to disable it:
305
+
306
+ ```ruby
307
+ config.spinner_enabled = !Rails.env.test?
308
+ ```
309
+
310
+ Or alternativelly, you should send a valid spinner value along your requests:
311
+
312
+ ```ruby
313
+ # RSpec example
314
+ session[:invisible_captcha_spinner] = '32ab649161f9f6faeeb323746de1a25d'
315
+ post :create, params: { topic: { title: 'foo' }, spinner: '32ab649161f9f6faeeb323746de1a25d' }
316
+ ```
317
+
298
318
  ## Contribute
299
319
 
300
320
  Any kind of idea, feedback or bug report are welcome! Open an [issue](https://github.com/markets/invisible_captcha/issues) or send a [pull request](https://github.com/markets/invisible_captcha/pulls).
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 7.1.0"
6
+
7
+ gemspec path: "../"
@@ -21,7 +21,10 @@ module InvisibleCaptcha
21
21
  def detect_spam(options = {})
22
22
  if timestamp_spam?(options)
23
23
  on_timestamp_spam(options)
24
- elsif honeypot_spam?(options) || spinner_spam?
24
+ return if performed?
25
+ end
26
+
27
+ if honeypot_spam?(options) || spinner_spam?
25
28
  on_spam(options)
26
29
  end
27
30
  end
@@ -30,7 +33,8 @@ module InvisibleCaptcha
30
33
  if action = options[:on_timestamp_spam]
31
34
  send(action)
32
35
  else
33
- redirect_back(fallback_location: root_path, flash: { error: InvisibleCaptcha.timestamp_error_message })
36
+ flash[:error] = InvisibleCaptcha.timestamp_error_message
37
+ redirect_back(fallback_location: root_path)
34
38
  end
35
39
  end
36
40
 
@@ -72,7 +76,7 @@ module InvisibleCaptcha
72
76
  end
73
77
 
74
78
  def spinner_spam?
75
- if InvisibleCaptcha.spinner_enabled && params[:spinner] != session[:invisible_captcha_spinner]
79
+ if InvisibleCaptcha.spinner_enabled && (params[:spinner].blank? || params[:spinner] != session[:invisible_captcha_spinner])
76
80
  warn_spam("Spinner value mismatch")
77
81
  return true
78
82
  end
@@ -88,7 +92,7 @@ module InvisibleCaptcha
88
92
  # If honeypot is defined for this controller-action, search for:
89
93
  # - honeypot: params[:subtitle]
90
94
  # - honeypot with scope: params[:topic][:subtitle]
91
- if params[honeypot].present? || params.dig(scope, honeypot).present?
95
+ if params[honeypot].present? || (params[scope] && params[scope][honeypot].present?)
92
96
  warn_spam("Honeypot param '#{honeypot}' was present.")
93
97
  return true
94
98
  else
@@ -98,7 +102,7 @@ module InvisibleCaptcha
98
102
  end
99
103
  else
100
104
  InvisibleCaptcha.honeypots.each do |default_honeypot|
101
- if params[default_honeypot].present? || params.dig(scope, default_honeypot).present?
105
+ if params[default_honeypot].present? || (params[scope] && params[scope][default_honeypot].present?)
102
106
  warn_spam("Honeypot param '#{scope}.#{default_honeypot}' was present.")
103
107
  return true
104
108
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module InvisibleCaptcha
4
- VERSION = "2.1.0"
4
+ VERSION = "2.3.0"
5
5
  end
@@ -71,6 +71,12 @@ RSpec.describe InvisibleCaptcha::ControllerExt, type: :controller do
71
71
  .to be_present
72
72
  end
73
73
 
74
+ it 'runs on_spam callback if on_timestamp_spam callback is defined but passes' do
75
+ put :test_passthrough, params: { id: 1, topic: { title: 'bar', subtitle: 'foo' } }
76
+
77
+ expect(response.status).to eq(204)
78
+ end
79
+
74
80
  context 'successful submissions' do
75
81
  it 'passes if submission on or after timestamp_threshold' do
76
82
  sleep InvisibleCaptcha.timestamp_threshold
@@ -84,7 +90,7 @@ RSpec.describe InvisibleCaptcha::ControllerExt, type: :controller do
84
90
  }
85
91
 
86
92
  expect(flash[:error]).not_to be_present
87
- expect(response.body).to be_present
93
+ expect(response.body).to redirect_to(new_topic_path)
88
94
 
89
95
  # Make sure session is cleared
90
96
  expect(session[:invisible_captcha_timestamp]).to be_nil
@@ -96,7 +102,13 @@ RSpec.describe InvisibleCaptcha::ControllerExt, type: :controller do
96
102
  post :publish, params: { id: 1 }
97
103
 
98
104
  expect(flash[:error]).not_to be_present
99
- expect(response.body).to be_present
105
+ expect(response.body).to redirect_to(new_topic_path)
106
+ end
107
+
108
+ it 'passes if on_timestamp_spam doesn\'t perform' do
109
+ put :test_passthrough, params: { id: 1, topic: { title: 'bar' } }
110
+
111
+ expect(response.body).to redirect_to(new_topic_path)
100
112
  end
101
113
  end
102
114
  end
@@ -126,13 +138,13 @@ RSpec.describe InvisibleCaptcha::ControllerExt, type: :controller do
126
138
  it 'passes with no spam' do
127
139
  post :categorize, params: { topic: { title: 'foo' } }
128
140
 
129
- expect(response.body).to be_present
141
+ expect(response.body).to redirect_to(new_topic_path)
130
142
  end
131
143
 
132
144
  it 'fails with spam' do
133
145
  post :categorize, params: { topic: { "#{InvisibleCaptcha.honeypots.sample}": 'foo' } }
134
146
 
135
- expect(response.body).to be_blank
147
+ expect(response.body).not_to redirect_to(new_topic_path)
136
148
  end
137
149
  end
138
150
 
@@ -140,13 +152,13 @@ RSpec.describe InvisibleCaptcha::ControllerExt, type: :controller do
140
152
  it 'passes with no spam' do
141
153
  post :categorize
142
154
 
143
- expect(response.body).to be_present
155
+ expect(response.body).to redirect_to(new_topic_path)
144
156
  end
145
157
 
146
158
  it 'fails with spam' do
147
159
  post :categorize, params: { "#{InvisibleCaptcha.honeypots.sample}": 'foo' }
148
160
 
149
- expect(response.body).to be_blank
161
+ expect(response.body).not_to redirect_to(new_topic_path)
150
162
  end
151
163
  end
152
164
 
@@ -13,6 +13,10 @@ class TopicsController < ApplicationController
13
13
 
14
14
  invisible_captcha only: :categorize
15
15
 
16
+ invisible_captcha honeypot: :subtitle, only: :test_passthrough,
17
+ on_spam: :catching_on_spam_callback,
18
+ on_timestamp_spam: :on_timestamp_spam_callback_with_passthrough
19
+
16
20
  def index
17
21
  redirect_to new_topic_path
18
22
  end
@@ -56,6 +60,10 @@ class TopicsController < ApplicationController
56
60
  end
57
61
  end
58
62
 
63
+ def test_passthrough
64
+ redirect_to new_topic_path
65
+ end
66
+
59
67
  private
60
68
 
61
69
  def custom_callback
@@ -65,4 +73,12 @@ class TopicsController < ApplicationController
65
73
  def custom_timestamp_callback
66
74
  head(204)
67
75
  end
76
+
77
+ def on_timestamp_spam_callback_with_passthrough
78
+ end
79
+
80
+ def catching_on_spam_callback
81
+ head(204)
82
+ end
83
+
68
84
  end
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title>Dummy</title>
4
+ <title>InvisibleCaptcha Demo</title>
5
5
  <%= stylesheet_link_tag "/styles.css" %>
6
6
  <%= csrf_meta_tags %>
7
7
  <%= invisible_captcha_styles %>
@@ -24,5 +24,11 @@
24
24
  <% end %>
25
25
 
26
26
  <%= yield %>
27
+
28
+ <footer>
29
+ Running on
30
+ <b>Ruby <%= RUBY_VERSION %></b> and
31
+ <b>Rails <%= Rails.version %></b>
32
+ </footer>
27
33
  </body>
28
34
  </html>
@@ -4,6 +4,7 @@ Rails.application.routes.draw do
4
4
  post :rename, on: :collection
5
5
  post :categorize, on: :collection
6
6
  post :copy, on: :collection
7
+ post :test_passthrough, on: :collection
7
8
  end
8
9
 
9
10
  root to: 'topics#new'
@@ -31,6 +31,15 @@ button {
31
31
  font-size: 1em;
32
32
  }
33
33
 
34
+ footer {
35
+ position: fixed;
36
+ bottom: 0;
37
+ width: 100%;
38
+ padding: 1em 0;
39
+ font-size: 0.8em;
40
+ background-color: #ccc;
41
+ }
42
+
34
43
  .errors {
35
44
  color: darkred;
36
45
  }
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: 2.1.0
4
+ version: 2.3.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: 2023-03-12 00:00:00.000000000 Z
11
+ date: 2024-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -115,6 +115,7 @@ files:
115
115
  - gemfiles/rails_6.0.gemfile
116
116
  - gemfiles/rails_6.1.gemfile
117
117
  - gemfiles/rails_7.0.gemfile
118
+ - gemfiles/rails_7.1.gemfile
118
119
  - invisible_captcha.gemspec
119
120
  - lib/invisible_captcha.rb
120
121
  - lib/invisible_captcha/controller_ext.rb
@@ -180,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
181
  - !ruby/object:Gem::Version
181
182
  version: '0'
182
183
  requirements: []
183
- rubygems_version: 3.4.6
184
+ rubygems_version: 3.4.10
184
185
  signing_key:
185
186
  specification_version: 4
186
187
  summary: Honeypot spam protection for Rails