invisible_captcha 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +35 -0
- data/Appraisals +9 -10
- data/CHANGELOG.md +6 -0
- data/README.md +12 -7
- data/Rakefile +1 -6
- data/gemfiles/rails_7.0.gemfile +7 -0
- data/invisible_captcha.gemspec +4 -1
- data/lib/invisible_captcha/controller_ext.rb +9 -7
- data/lib/invisible_captcha/form_helpers.rb +1 -1
- data/lib/invisible_captcha/version.rb +1 -1
- data/lib/invisible_captcha/view_helpers.rb +1 -1
- data/spec/controllers_spec.rb +47 -3
- data/spec/dummy/app/controllers/topics_controller.rb +12 -0
- data/spec/dummy/app/views/layouts/application.html.erb +1 -2
- data/spec/dummy/config/application.rb +0 -2
- data/spec/dummy/config/environments/development.rb +1 -4
- data/spec/dummy/config/environments/test.rb +1 -1
- data/spec/dummy/config/routes.rb +2 -0
- data/spec/dummy/{app/assets/stylesheets/application.css → public/styles.css} +9 -4
- data/spec/spec_helper.rb +7 -0
- metadata +54 -21
- data/.travis.yml +0 -18
- data/spec/dummy/app/assets/config/manifest.js +0 -2
- data/spec/dummy/app/assets/javascripts/application.js +0 -1
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/config/environments/production.rb +0 -86
- data/spec/dummy/lib/assets/.gitkeep +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f15e5223696c06e82c8ab6182a4396a9e4e4bf3acd6e425296e60cc6b49cb225
|
4
|
+
data.tar.gz: e35b51231012ae92b236f81eb1966a16ea3c7b02862d03977bf23478d968538d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ccc4299595595e513fa8f8eb472233b83fa334608b3cd4fcba3d1316b8f1819d83e7cc3d2678dce0ac954c52a4b90ecf0643424d0358cd8dd3412c4aa04ac391
|
7
|
+
data.tar.gz: 1fcceba58cb21d931e6d8f7f49a3a1649230628442e18f3664a80d5ac983dbec0bc5caeeda17cacc748bfbfabce93bd189f695bc0d123d4bd2ef0d94a20cdb3e
|
@@ -0,0 +1,35 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
name: CI
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
env:
|
10
|
+
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
|
11
|
+
strategy:
|
12
|
+
fail-fast: false
|
13
|
+
matrix:
|
14
|
+
ruby: ["2.7", "3.0", "3.1", "3.2"]
|
15
|
+
gemfile: [rails_6.0, rails_6.1, rails_7.0]
|
16
|
+
exclude:
|
17
|
+
- ruby: "3.1"
|
18
|
+
gemfile: rails_6.0
|
19
|
+
- ruby: "3.2"
|
20
|
+
gemfile: rails_6.0
|
21
|
+
include:
|
22
|
+
- ruby: "2.7"
|
23
|
+
gemfile: rails_5.2
|
24
|
+
- ruby: head
|
25
|
+
gemfile: rails_7.0
|
26
|
+
steps:
|
27
|
+
- uses: actions/checkout@v3
|
28
|
+
- uses: ruby/setup-ruby@v1
|
29
|
+
with:
|
30
|
+
ruby-version: ${{ matrix.ruby }}
|
31
|
+
bundler-cache: true
|
32
|
+
- run: bundle exec rspec
|
33
|
+
continue-on-error: ${{ endsWith(matrix.ruby, 'head') }}
|
34
|
+
- name: Upload coverage reports to Codecov
|
35
|
+
uses: codecov/codecov-action@v3
|
data/Appraisals
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
gem "rails", "~> 5.2.0"
|
1
|
+
%w(
|
2
|
+
7.0
|
3
|
+
6.1
|
4
|
+
6.0
|
5
|
+
5.2
|
6
|
+
).each do |version|
|
7
|
+
appraise "rails-#{version}" do
|
8
|
+
gem "rails", "~> #{version}.0"
|
9
|
+
end
|
11
10
|
end
|
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
|
+
## [2.1.0]
|
6
|
+
|
7
|
+
- Drop official support for EOL Rubies: 2.5 and 2.6
|
8
|
+
- Allow random honeypots to be scoped (#117)
|
9
|
+
|
5
10
|
## [2.0.0]
|
6
11
|
|
7
12
|
- New spinner, IP based, validation check (#89)
|
@@ -125,6 +130,7 @@ All notable changes to this project will be documented in this file.
|
|
125
130
|
|
126
131
|
- First version of controller filters
|
127
132
|
|
133
|
+
[2.1.0]: https://github.com/markets/invisible_captcha/compare/v2.0.0...v2.1.0
|
128
134
|
[2.0.0]: https://github.com/markets/invisible_captcha/compare/v1.1.0...v2.0.0
|
129
135
|
[1.1.0]: https://github.com/markets/invisible_captcha/compare/v1.0.1...v1.1.0
|
130
136
|
[1.0.1]: https://github.com/markets/invisible_captcha/compare/v1.0.0...v1.0.1
|
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# Invisible Captcha
|
2
2
|
|
3
3
|
[![Gem](https://img.shields.io/gem/v/invisible_captcha.svg?style=flat-square)](https://rubygems.org/gems/invisible_captcha)
|
4
|
-
[![Build Status](https://
|
4
|
+
[![Build Status](https://github.com/markets/invisible_captcha/workflows/CI/badge.svg)](https://github.com/markets/invisible_captcha/actions)
|
5
|
+
[![codecov](https://codecov.io/gh/markets/invisible_captcha/branch/master/graph/badge.svg?token=nADSa6rbhM)](https://codecov.io/gh/markets/invisible_captcha)
|
5
6
|
|
6
7
|
> Complete and flexible spam protection solution for Rails applications.
|
7
8
|
|
@@ -21,7 +22,7 @@ It also comes with:
|
|
21
22
|
|
22
23
|
## Installation
|
23
24
|
|
24
|
-
Invisible Captcha is tested against Rails `>= 5.2` and Ruby `>= 2.
|
25
|
+
Invisible Captcha is tested against Rails `>= 5.2` and Ruby `>= 2.7`.
|
25
26
|
|
26
27
|
Add this line to your Gemfile and then execute `bundle install`:
|
27
28
|
|
@@ -63,6 +64,8 @@ class TopicsController < ApplicationController
|
|
63
64
|
end
|
64
65
|
```
|
65
66
|
|
67
|
+
You should _not_ name your method `on_spam`, as this will collide with an internal method of the same name.
|
68
|
+
|
66
69
|
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:
|
67
70
|
|
68
71
|
```erb
|
@@ -97,6 +100,8 @@ invisible_captcha only: [:new_contact]
|
|
97
100
|
|
98
101
|
You can place `<%= flash[:error] %>` next to `:alert` and `:notice` message types, if you have them in your `app/views/layouts/application.html.erb`.
|
99
102
|
|
103
|
+
**NOTE:** This gem relies on data set by the backend, so in order to properly work, your forms should be rendered by Rails. Forms generated via JavaScript are not going to work well.
|
104
|
+
|
100
105
|
## Options and customization
|
101
106
|
|
102
107
|
This section contains a description of all plugin options and customizations.
|
@@ -106,13 +111,13 @@ This section contains a description of all plugin options and customizations.
|
|
106
111
|
You can customize:
|
107
112
|
|
108
113
|
- `sentence_for_humans`: text for real users if input field was visible. By default, it uses I18n (see below).
|
109
|
-
- `honeypots`: collection of default honeypots. Used by the view helper, called with no args, to generate a random honeypot field name. By default, a random collection is already generated. As the random collection is stored in memory, it will not work if you are running multiple Rails instances behind a load balancer
|
114
|
+
- `honeypots`: collection of default honeypots. Used by the view helper, called with no args, to generate a random honeypot field name. By default, a random collection is already generated. As the random collection is stored in memory, it will not work if you are running multiple Rails instances behind a load balancer (see [Multiple Rails instances](#multiple-rails-instances)). Beware that Chrome may ignore `autocomplete="off"`. Thus, consider not to use field names, which would be autocompleted, like for example `name`, `country`.
|
110
115
|
- `visual_honeypots`: make honeypots visible, also useful to test/debug your implementation.
|
111
116
|
- `timestamp_threshold`: fastest time (in seconds) to expect a human to submit the form (see [original article by Yoav Aner](https://blog.gingerlime.com/2012/simple-detection-of-comment-spam-in-rails/) outlining the idea). By default, 4 seconds. **NOTE:** It's recommended to deactivate the autocomplete feature to avoid false positives (`autocomplete="off"`).
|
112
117
|
- `timestamp_enabled`: option to disable the time threshold check at application level. Could be useful, for example, on some testing scenarios. By default, true.
|
113
118
|
- `timestamp_error_message`: flash error message thrown when form submitted quicker than the `timestamp_threshold` value. It uses I18n by default.
|
114
119
|
- `injectable_styles`: if enabled, you should call anywhere in your layout the following helper `<%= invisible_captcha_styles %>`. This allows you to inject styles, for example, in `<head>`. False by default, styles are injected inline with the honeypot.
|
115
|
-
- `spinner_enabled`: option to disable the IP spinner validation.
|
120
|
+
- `spinner_enabled`: option to disable the IP spinner validation. By default, true.
|
116
121
|
- `secret`: customize the secret key to encode some internal values. By default, it reads the environment variable `ENV['INVISIBLE_CAPTCHA_SECRET']` and fallbacks to random value. Be careful, if you are running multiple Rails instances behind a load balancer, use always the same value via the environment variable.
|
117
122
|
|
118
123
|
To change these defaults, add the following to an initializer (recommended `config/initializers/invisible_captcha.rb`):
|
@@ -206,7 +211,7 @@ The `data` passed to the subscriber is hash containing information about the req
|
|
206
211
|
|
207
212
|
```ruby
|
208
213
|
{
|
209
|
-
message: "
|
214
|
+
message: "Honeypot param 'subtitle' was present.",
|
210
215
|
remote_ip: '127.0.0.1',
|
211
216
|
user_agent: 'Chrome 77',
|
212
217
|
controller: 'users',
|
@@ -220,7 +225,7 @@ The `data` passed to the subscriber is hash containing information about the req
|
|
220
225
|
}
|
221
226
|
```
|
222
227
|
|
223
|
-
|
228
|
+
**NOTE:** `params` will be filtered according to your `Rails.application.config.filter_parameters` configuration, making them (probably) safe for logging. But always double-check that you're not inadvertently logging sensitive form data, like passwords and credit cards.
|
224
229
|
|
225
230
|
### Content Security Policy
|
226
231
|
|
@@ -247,7 +252,7 @@ And in your view helper, you need to pass `nonce: true` to the `invisible_captch
|
|
247
252
|
<%= invisible_captcha nonce: true %>
|
248
253
|
```
|
249
254
|
|
250
|
-
**
|
255
|
+
**NOTE:** 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:
|
251
256
|
|
252
257
|
* https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
|
253
258
|
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
|
data/Rakefile
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "bundler/gem_tasks"
|
4
|
-
require 'rspec/core/rake_task'
|
5
|
-
|
6
|
-
RSpec::Core::RakeTask.new(:spec)
|
7
|
-
|
8
|
-
task :default => :spec
|
9
4
|
|
10
5
|
desc 'Start development Rails app'
|
11
6
|
task :web do
|
@@ -16,4 +11,4 @@ task :web do
|
|
16
11
|
|
17
12
|
Dir.chdir(app_path)
|
18
13
|
exec("rails s -p #{port}")
|
19
|
-
end
|
14
|
+
end
|
data/invisible_captcha.gemspec
CHANGED
@@ -15,8 +15,11 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
16
16
|
spec.require_paths = ["lib"]
|
17
17
|
|
18
|
-
spec.add_dependency 'rails', '>= 5.
|
18
|
+
spec.add_dependency 'rails', '>= 5.2'
|
19
19
|
|
20
20
|
spec.add_development_dependency 'rspec-rails'
|
21
21
|
spec.add_development_dependency 'appraisal'
|
22
|
+
spec.add_development_dependency 'webrick'
|
23
|
+
spec.add_development_dependency 'simplecov'
|
24
|
+
spec.add_development_dependency 'simplecov-cobertura'
|
22
25
|
end
|
@@ -55,7 +55,7 @@ module InvisibleCaptcha
|
|
55
55
|
|
56
56
|
# Consider as spam if timestamp not in session, cause that means the form was not fetched at all
|
57
57
|
unless timestamp
|
58
|
-
warn_spam("
|
58
|
+
warn_spam("Timestamp not found in session.")
|
59
59
|
return true
|
60
60
|
end
|
61
61
|
|
@@ -64,7 +64,7 @@ module InvisibleCaptcha
|
|
64
64
|
|
65
65
|
# Consider as spam if form submitted too quickly
|
66
66
|
if time_to_submit < threshold
|
67
|
-
warn_spam("
|
67
|
+
warn_spam("Timestamp threshold not reached (took #{time_to_submit.to_i}s).")
|
68
68
|
return true
|
69
69
|
end
|
70
70
|
|
@@ -73,7 +73,7 @@ module InvisibleCaptcha
|
|
73
73
|
|
74
74
|
def spinner_spam?
|
75
75
|
if InvisibleCaptcha.spinner_enabled && params[:spinner] != session[:invisible_captcha_spinner]
|
76
|
-
warn_spam("
|
76
|
+
warn_spam("Spinner value mismatch")
|
77
77
|
return true
|
78
78
|
end
|
79
79
|
|
@@ -89,7 +89,7 @@ module InvisibleCaptcha
|
|
89
89
|
# - honeypot: params[:subtitle]
|
90
90
|
# - honeypot with scope: params[:topic][:subtitle]
|
91
91
|
if params[honeypot].present? || params.dig(scope, honeypot).present?
|
92
|
-
warn_spam("
|
92
|
+
warn_spam("Honeypot param '#{honeypot}' was present.")
|
93
93
|
return true
|
94
94
|
else
|
95
95
|
# No honeypot spam detected, remove honeypot from params to avoid UnpermittedParameters exceptions
|
@@ -98,8 +98,8 @@ module InvisibleCaptcha
|
|
98
98
|
end
|
99
99
|
else
|
100
100
|
InvisibleCaptcha.honeypots.each do |default_honeypot|
|
101
|
-
if params[default_honeypot].present?
|
102
|
-
warn_spam("
|
101
|
+
if params[default_honeypot].present? || params.dig(scope, default_honeypot).present?
|
102
|
+
warn_spam("Honeypot param '#{scope}.#{default_honeypot}' was present.")
|
103
103
|
return true
|
104
104
|
end
|
105
105
|
end
|
@@ -109,7 +109,9 @@ module InvisibleCaptcha
|
|
109
109
|
end
|
110
110
|
|
111
111
|
def warn_spam(message)
|
112
|
-
|
112
|
+
message = "[Invisible Captcha] Potential spam detected for IP #{request.remote_ip}. #{message}"
|
113
|
+
|
114
|
+
logger.warn(message)
|
113
115
|
|
114
116
|
ActiveSupport::Notifications.instrument(
|
115
117
|
'invisible_captcha.spam_detected',
|
@@ -57,7 +57,7 @@ module InvisibleCaptcha
|
|
57
57
|
concat label_tag(build_label_name(honeypot, scope), label)
|
58
58
|
concat text_field_tag(build_input_name(honeypot, scope), nil, default_honeypot_options.merge(options))
|
59
59
|
if InvisibleCaptcha.spinner_enabled
|
60
|
-
concat hidden_field_tag("spinner", session[:invisible_captcha_spinner])
|
60
|
+
concat hidden_field_tag("spinner", session[:invisible_captcha_spinner], id: nil)
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
data/spec/controllers_spec.rb
CHANGED
@@ -121,6 +121,50 @@ RSpec.describe InvisibleCaptcha::ControllerExt, type: :controller do
|
|
121
121
|
expect(response.body).to be_present
|
122
122
|
end
|
123
123
|
|
124
|
+
context 'with random honeypot' do
|
125
|
+
context 'auto-scoped' do
|
126
|
+
it 'passes with no spam' do
|
127
|
+
post :categorize, params: { topic: { title: 'foo' } }
|
128
|
+
|
129
|
+
expect(response.body).to be_present
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'fails with spam' do
|
133
|
+
post :categorize, params: { topic: { "#{InvisibleCaptcha.honeypots.sample}": 'foo' } }
|
134
|
+
|
135
|
+
expect(response.body).to be_blank
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'with no scope' do
|
140
|
+
it 'passes with no spam' do
|
141
|
+
post :categorize
|
142
|
+
|
143
|
+
expect(response.body).to be_present
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'fails with spam' do
|
147
|
+
post :categorize, params: { "#{InvisibleCaptcha.honeypots.sample}": 'foo' }
|
148
|
+
|
149
|
+
expect(response.body).to be_blank
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context 'with scope' do
|
154
|
+
it 'fails with spam' do
|
155
|
+
post :rename, params: { topic: { "#{InvisibleCaptcha.honeypots.sample}": 'foo' } }
|
156
|
+
|
157
|
+
expect(response.body).to be_blank
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'passes with no spam' do
|
161
|
+
post :rename, params: { topic: { title: 'foo' } }
|
162
|
+
|
163
|
+
expect(response.body).to be_blank
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
124
168
|
it 'allow a custom on_spam callback' do
|
125
169
|
put :update, params: { id: 1, topic: { subtitle: 'foo' } }
|
126
170
|
|
@@ -148,8 +192,8 @@ RSpec.describe InvisibleCaptcha::ControllerExt, type: :controller do
|
|
148
192
|
after { ActiveSupport::Notifications.unsubscribe(subscriber) }
|
149
193
|
|
150
194
|
it 'dispatches an `invisible_captcha.spam_detected` event' do
|
151
|
-
expect(dummy_handler).to receive(:handle_event).once.with(
|
152
|
-
message: "Invisible Captcha
|
195
|
+
expect(dummy_handler).to receive(:handle_event).once.with({
|
196
|
+
message: "[Invisible Captcha] Potential spam detected for IP 0.0.0.0. Honeypot param 'subtitle' was present.",
|
153
197
|
remote_ip: '0.0.0.0',
|
154
198
|
user_agent: 'Rails Testing',
|
155
199
|
controller: 'topics',
|
@@ -160,7 +204,7 @@ RSpec.describe InvisibleCaptcha::ControllerExt, type: :controller do
|
|
160
204
|
controller: 'topics',
|
161
205
|
action: 'create'
|
162
206
|
}
|
163
|
-
)
|
207
|
+
})
|
164
208
|
|
165
209
|
post :create, params: { topic: { subtitle: 'foo' } }
|
166
210
|
end
|
@@ -9,6 +9,10 @@ class TopicsController < ApplicationController
|
|
9
9
|
|
10
10
|
invisible_captcha honeypot: :subtitle, only: :copy, timestamp_enabled: false
|
11
11
|
|
12
|
+
invisible_captcha scope: :topic, only: :rename
|
13
|
+
|
14
|
+
invisible_captcha only: :categorize
|
15
|
+
|
12
16
|
def index
|
13
17
|
redirect_to new_topic_path
|
14
18
|
end
|
@@ -28,6 +32,14 @@ class TopicsController < ApplicationController
|
|
28
32
|
end
|
29
33
|
|
30
34
|
def update
|
35
|
+
redirect_to new_topic_path
|
36
|
+
end
|
37
|
+
|
38
|
+
def rename
|
39
|
+
end
|
40
|
+
|
41
|
+
def categorize
|
42
|
+
redirect_to new_topic_path
|
31
43
|
end
|
32
44
|
|
33
45
|
def publish
|
@@ -2,9 +2,7 @@ require File.expand_path('../boot', __FILE__)
|
|
2
2
|
|
3
3
|
require 'action_controller/railtie'
|
4
4
|
require 'action_view/railtie'
|
5
|
-
require 'action_mailer/railtie'
|
6
5
|
require 'active_model/railtie'
|
7
|
-
require 'sprockets/railtie'
|
8
6
|
|
9
7
|
# Require the gems listed in Gemfile, including any gems
|
10
8
|
# you've limited to :test, :development, or :production.
|
@@ -14,7 +14,7 @@ Dummy::Application.configure do
|
|
14
14
|
config.action_controller.perform_caching = false
|
15
15
|
|
16
16
|
# Don't care if the mailer can't send.
|
17
|
-
config.action_mailer.raise_delivery_errors = false
|
17
|
+
# config.action_mailer.raise_delivery_errors = false
|
18
18
|
|
19
19
|
# Print deprecation notices to the Rails logger.
|
20
20
|
config.active_support.deprecation = :log
|
@@ -31,9 +31,6 @@ Dummy::Application.configure do
|
|
31
31
|
# yet still be able to expire them through the digest params.
|
32
32
|
# config.assets.digest = true
|
33
33
|
|
34
|
-
# quiet assets
|
35
|
-
config.assets.quiet = true
|
36
|
-
|
37
34
|
# Adds additional error checking when serving assets at runtime.
|
38
35
|
# Checks for improperly declared sprockets dependencies.
|
39
36
|
# Raises helpful error messages.
|
@@ -30,7 +30,7 @@ Dummy::Application.configure do
|
|
30
30
|
# Tell Action Mailer not to deliver emails to the real world.
|
31
31
|
# The :test delivery method accumulates sent emails in the
|
32
32
|
# ActionMailer::Base.deliveries array.
|
33
|
-
config.action_mailer.delivery_method = :test
|
33
|
+
# config.action_mailer.delivery_method = :test
|
34
34
|
|
35
35
|
# Print deprecation notices to the stderr.
|
36
36
|
config.active_support.deprecation = :stderr
|
data/spec/dummy/config/routes.rb
CHANGED
@@ -8,8 +8,11 @@ h1 {
|
|
8
8
|
border-bottom: 3px solid;
|
9
9
|
}
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
a {
|
12
|
+
color: #000;
|
13
|
+
}
|
14
|
+
|
15
|
+
input, textarea {
|
13
16
|
border: 0;
|
14
17
|
margin-bottom: 1.5em;
|
15
18
|
}
|
@@ -19,7 +22,9 @@ input {
|
|
19
22
|
}
|
20
23
|
|
21
24
|
button {
|
22
|
-
|
25
|
+
color: #fff;
|
26
|
+
background-color: #000;
|
27
|
+
border: none;
|
23
28
|
border-radius: 0.25em;
|
24
29
|
height: 3em;
|
25
30
|
width: 10em;
|
@@ -28,4 +33,4 @@ button {
|
|
28
33
|
|
29
34
|
.errors {
|
30
35
|
color: darkred;
|
31
|
-
}
|
36
|
+
}
|
data/spec/spec_helper.rb
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
|
3
3
|
ENV['RAILS_ENV'] = 'test'
|
4
4
|
|
5
|
+
require 'simplecov'
|
6
|
+
if ENV['CI']
|
7
|
+
require 'simplecov-cobertura'
|
8
|
+
SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
|
9
|
+
end
|
10
|
+
SimpleCov.start
|
11
|
+
|
5
12
|
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
6
13
|
require 'rspec/rails'
|
7
14
|
require 'invisible_captcha'
|
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.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc Anguera Insa
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '5.
|
19
|
+
version: '5.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '5.
|
26
|
+
version: '5.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec-rails
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +52,48 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: webrick
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov-cobertura
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
55
97
|
description: Unobtrusive, flexible and complete spam protection for Rails applications
|
56
98
|
using honeypot strategy for better user experience.
|
57
99
|
email:
|
@@ -60,9 +102,9 @@ executables: []
|
|
60
102
|
extensions: []
|
61
103
|
extra_rdoc_files: []
|
62
104
|
files:
|
105
|
+
- ".github/workflows/ci.yml"
|
63
106
|
- ".gitignore"
|
64
107
|
- ".rspec"
|
65
|
-
- ".travis.yml"
|
66
108
|
- Appraisals
|
67
109
|
- CHANGELOG.md
|
68
110
|
- Gemfile
|
@@ -72,6 +114,7 @@ files:
|
|
72
114
|
- gemfiles/rails_5.2.gemfile
|
73
115
|
- gemfiles/rails_6.0.gemfile
|
74
116
|
- gemfiles/rails_6.1.gemfile
|
117
|
+
- gemfiles/rails_7.0.gemfile
|
75
118
|
- invisible_captcha.gemspec
|
76
119
|
- lib/invisible_captcha.rb
|
77
120
|
- lib/invisible_captcha/controller_ext.rb
|
@@ -82,13 +125,9 @@ files:
|
|
82
125
|
- spec/controllers_spec.rb
|
83
126
|
- spec/dummy/README.md
|
84
127
|
- spec/dummy/Rakefile
|
85
|
-
- spec/dummy/app/assets/config/manifest.js
|
86
|
-
- spec/dummy/app/assets/javascripts/application.js
|
87
|
-
- spec/dummy/app/assets/stylesheets/application.css
|
88
128
|
- spec/dummy/app/controllers/application_controller.rb
|
89
129
|
- spec/dummy/app/controllers/topics_controller.rb
|
90
130
|
- spec/dummy/app/helpers/application_helper.rb
|
91
|
-
- spec/dummy/app/mailers/.gitkeep
|
92
131
|
- spec/dummy/app/models/topic.rb
|
93
132
|
- spec/dummy/app/views/layouts/application.html.erb
|
94
133
|
- spec/dummy/app/views/topics/new.html.erb
|
@@ -101,7 +140,6 @@ files:
|
|
101
140
|
- spec/dummy/config/boot.rb
|
102
141
|
- spec/dummy/config/environment.rb
|
103
142
|
- spec/dummy/config/environments/development.rb
|
104
|
-
- spec/dummy/config/environments/production.rb
|
105
143
|
- spec/dummy/config/environments/test.rb
|
106
144
|
- spec/dummy/config/initializers/backtrace_silencers.rb
|
107
145
|
- spec/dummy/config/initializers/cookies_serializer.rb
|
@@ -114,12 +152,12 @@ files:
|
|
114
152
|
- spec/dummy/config/locales/en.yml
|
115
153
|
- spec/dummy/config/routes.rb
|
116
154
|
- spec/dummy/config/secrets.yml
|
117
|
-
- spec/dummy/lib/assets/.gitkeep
|
118
155
|
- spec/dummy/log/.gitkeep
|
119
156
|
- spec/dummy/public/404.html
|
120
157
|
- spec/dummy/public/422.html
|
121
158
|
- spec/dummy/public/500.html
|
122
159
|
- spec/dummy/public/favicon.ico
|
160
|
+
- spec/dummy/public/styles.css
|
123
161
|
- spec/invisible_captcha_spec.rb
|
124
162
|
- spec/spec_helper.rb
|
125
163
|
- spec/view_helpers_spec.rb
|
@@ -127,7 +165,7 @@ homepage: https://github.com/markets/invisible_captcha
|
|
127
165
|
licenses:
|
128
166
|
- MIT
|
129
167
|
metadata: {}
|
130
|
-
post_install_message:
|
168
|
+
post_install_message:
|
131
169
|
rdoc_options: []
|
132
170
|
require_paths:
|
133
171
|
- lib
|
@@ -142,21 +180,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
142
180
|
- !ruby/object:Gem::Version
|
143
181
|
version: '0'
|
144
182
|
requirements: []
|
145
|
-
rubygems_version: 3.
|
146
|
-
signing_key:
|
183
|
+
rubygems_version: 3.4.6
|
184
|
+
signing_key:
|
147
185
|
specification_version: 4
|
148
186
|
summary: Honeypot spam protection for Rails
|
149
187
|
test_files:
|
150
188
|
- spec/controllers_spec.rb
|
151
189
|
- spec/dummy/README.md
|
152
190
|
- spec/dummy/Rakefile
|
153
|
-
- spec/dummy/app/assets/config/manifest.js
|
154
|
-
- spec/dummy/app/assets/javascripts/application.js
|
155
|
-
- spec/dummy/app/assets/stylesheets/application.css
|
156
191
|
- spec/dummy/app/controllers/application_controller.rb
|
157
192
|
- spec/dummy/app/controllers/topics_controller.rb
|
158
193
|
- spec/dummy/app/helpers/application_helper.rb
|
159
|
-
- spec/dummy/app/mailers/.gitkeep
|
160
194
|
- spec/dummy/app/models/topic.rb
|
161
195
|
- spec/dummy/app/views/layouts/application.html.erb
|
162
196
|
- spec/dummy/app/views/topics/new.html.erb
|
@@ -169,7 +203,6 @@ test_files:
|
|
169
203
|
- spec/dummy/config/boot.rb
|
170
204
|
- spec/dummy/config/environment.rb
|
171
205
|
- spec/dummy/config/environments/development.rb
|
172
|
-
- spec/dummy/config/environments/production.rb
|
173
206
|
- spec/dummy/config/environments/test.rb
|
174
207
|
- spec/dummy/config/initializers/backtrace_silencers.rb
|
175
208
|
- spec/dummy/config/initializers/cookies_serializer.rb
|
@@ -182,12 +215,12 @@ test_files:
|
|
182
215
|
- spec/dummy/config/locales/en.yml
|
183
216
|
- spec/dummy/config/routes.rb
|
184
217
|
- spec/dummy/config/secrets.yml
|
185
|
-
- spec/dummy/lib/assets/.gitkeep
|
186
218
|
- spec/dummy/log/.gitkeep
|
187
219
|
- spec/dummy/public/404.html
|
188
220
|
- spec/dummy/public/422.html
|
189
221
|
- spec/dummy/public/500.html
|
190
222
|
- spec/dummy/public/favicon.ico
|
223
|
+
- spec/dummy/public/styles.css
|
191
224
|
- spec/invisible_captcha_spec.rb
|
192
225
|
- spec/spec_helper.rb
|
193
226
|
- spec/view_helpers_spec.rb
|
data/.travis.yml
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
cache: bundler
|
3
|
-
rvm:
|
4
|
-
- ruby-head
|
5
|
-
- 3.0.0
|
6
|
-
- 2.7.2
|
7
|
-
- 2.6.5
|
8
|
-
- 2.5.8
|
9
|
-
gemfile:
|
10
|
-
- gemfiles/rails_6.1.gemfile
|
11
|
-
- gemfiles/rails_6.0.gemfile
|
12
|
-
- gemfiles/rails_5.2.gemfile
|
13
|
-
matrix:
|
14
|
-
exclude:
|
15
|
-
- rvm: 3.0.0
|
16
|
-
gemfile: gemfiles/rails_5.2.gemfile
|
17
|
-
allow_failures:
|
18
|
-
- rvm: ruby-head
|
@@ -1 +0,0 @@
|
|
1
|
-
console.log('Hi from Invisible Captcha!');
|
File without changes
|
@@ -1,86 +0,0 @@
|
|
1
|
-
Rails.application.configure do
|
2
|
-
# Settings specified here will take precedence over those in config/application.rb.
|
3
|
-
|
4
|
-
# Code is not reloaded between requests.
|
5
|
-
config.cache_classes = true
|
6
|
-
|
7
|
-
# Eager load code on boot. This eager loads most of Rails and
|
8
|
-
# your application in memory, allowing both threaded web servers
|
9
|
-
# and those relying on copy on write to perform better.
|
10
|
-
# Rake tasks automatically ignore this option for performance.
|
11
|
-
config.eager_load = true
|
12
|
-
|
13
|
-
# Full error reports are disabled and caching is turned on.
|
14
|
-
config.consider_all_requests_local = false
|
15
|
-
config.action_controller.perform_caching = true
|
16
|
-
|
17
|
-
# Disable serving static files from the `/public` folder by default since
|
18
|
-
# Apache or NGINX already handles this.
|
19
|
-
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
|
20
|
-
|
21
|
-
# Compress JavaScripts and CSS.
|
22
|
-
config.assets.js_compressor = :uglifier
|
23
|
-
# config.assets.css_compressor = :sass
|
24
|
-
|
25
|
-
# Do not fallback to assets pipeline if a precompiled asset is missed.
|
26
|
-
config.assets.compile = false
|
27
|
-
|
28
|
-
# `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
|
29
|
-
|
30
|
-
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
|
31
|
-
# config.action_controller.asset_host = 'http://assets.example.com'
|
32
|
-
|
33
|
-
# Specifies the header that your server uses for sending files.
|
34
|
-
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
|
35
|
-
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
|
36
|
-
|
37
|
-
# Mount Action Cable outside main process or domain
|
38
|
-
# config.action_cable.mount_path = nil
|
39
|
-
# config.action_cable.url = 'wss://example.com/cable'
|
40
|
-
# config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
|
41
|
-
|
42
|
-
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
43
|
-
# config.force_ssl = true
|
44
|
-
|
45
|
-
# Use the lowest log level to ensure availability of diagnostic information
|
46
|
-
# when problems arise.
|
47
|
-
config.log_level = :debug
|
48
|
-
|
49
|
-
# Prepend all log lines with the following tags.
|
50
|
-
config.log_tags = [ :request_id ]
|
51
|
-
|
52
|
-
# Use a different cache store in production.
|
53
|
-
# config.cache_store = :mem_cache_store
|
54
|
-
|
55
|
-
# Use a real queuing backend for Active Job (and separate queues per environment)
|
56
|
-
# config.active_job.queue_adapter = :resque
|
57
|
-
# config.active_job.queue_name_prefix = "dummy_#{Rails.env}"
|
58
|
-
config.action_mailer.perform_caching = false
|
59
|
-
|
60
|
-
# Ignore bad email addresses and do not raise email delivery errors.
|
61
|
-
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
|
62
|
-
# config.action_mailer.raise_delivery_errors = false
|
63
|
-
|
64
|
-
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
|
65
|
-
# the I18n.default_locale when a translation cannot be found).
|
66
|
-
config.i18n.fallbacks = true
|
67
|
-
|
68
|
-
# Send deprecation notices to registered listeners.
|
69
|
-
config.active_support.deprecation = :notify
|
70
|
-
|
71
|
-
# Use default logging formatter so that PID and timestamp are not suppressed.
|
72
|
-
config.log_formatter = ::Logger::Formatter.new
|
73
|
-
|
74
|
-
# Use a different logger for distributed setups.
|
75
|
-
# require 'syslog/logger'
|
76
|
-
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
|
77
|
-
|
78
|
-
if ENV["RAILS_LOG_TO_STDOUT"].present?
|
79
|
-
logger = ActiveSupport::Logger.new(STDOUT)
|
80
|
-
logger.formatter = config.log_formatter
|
81
|
-
config.logger = ActiveSupport::TaggedLogging.new(logger)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Do not dump schema after migrations.
|
85
|
-
config.active_record.dump_schema_after_migration = false
|
86
|
-
end
|
File without changes
|