feat(support#create): block with invisible captcha [avoid painful captcha]
This commit is contained in:
parent
ec6c71beea
commit
252eee272b
9 changed files with 87 additions and 42 deletions
1
Gemfile
1
Gemfile
|
@ -47,6 +47,7 @@ gem 'i18n_data'
|
||||||
gem 'i18n-tasks', require: false
|
gem 'i18n-tasks', require: false
|
||||||
gem 'iban-tools'
|
gem 'iban-tools'
|
||||||
gem 'image_processing'
|
gem 'image_processing'
|
||||||
|
gem 'invisible_captcha'
|
||||||
gem 'json_schemer'
|
gem 'json_schemer'
|
||||||
gem 'jwt'
|
gem 'jwt'
|
||||||
gem 'kaminari', '1.2.1' # Pagination
|
gem 'kaminari', '1.2.1' # Pagination
|
||||||
|
|
|
@ -369,6 +369,8 @@ GEM
|
||||||
image_processing (1.12.1)
|
image_processing (1.12.1)
|
||||||
mini_magick (>= 4.9.5, < 5)
|
mini_magick (>= 4.9.5, < 5)
|
||||||
ruby-vips (>= 2.0.17, < 3)
|
ruby-vips (>= 2.0.17, < 3)
|
||||||
|
invisible_captcha (2.0.0)
|
||||||
|
rails (>= 5.0)
|
||||||
ipaddress (0.8.3)
|
ipaddress (0.8.3)
|
||||||
jquery-rails (4.4.0)
|
jquery-rails (4.4.0)
|
||||||
rails-dom-testing (>= 1, < 3)
|
rails-dom-testing (>= 1, < 3)
|
||||||
|
@ -838,6 +840,7 @@ DEPENDENCIES
|
||||||
i18n_data
|
i18n_data
|
||||||
iban-tools
|
iban-tools
|
||||||
image_processing
|
image_processing
|
||||||
|
invisible_captcha
|
||||||
json_schemer
|
json_schemer
|
||||||
jwt
|
jwt
|
||||||
kaminari (= 1.2.1)
|
kaminari (= 1.2.1)
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
class SupportController < ApplicationController
|
class SupportController < ApplicationController
|
||||||
|
invisible_captcha only: [:create], on_spam: :redirect_to_root
|
||||||
|
|
||||||
def index
|
def index
|
||||||
setup_context
|
setup_context
|
||||||
end
|
end
|
||||||
|
@ -92,4 +94,8 @@ class SupportController < ApplicationController
|
||||||
def email
|
def email
|
||||||
current_user&.email || params[:email]
|
current_user&.email || params[:email]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def redirect_to_root
|
||||||
|
redirect_to root_path, alert: t('invisible_captcha.custom_message')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,6 +25,9 @@
|
||||||
= label_tag :type do
|
= label_tag :type do
|
||||||
= t('.your_question')
|
= t('.your_question')
|
||||||
= hidden_field_tag :type, params[:type]
|
= hidden_field_tag :type, params[:type]
|
||||||
|
|
||||||
|
= invisible_captcha
|
||||||
|
|
||||||
%dl
|
%dl
|
||||||
- @options.each do |(question, question_type, link)|
|
- @options.each do |(question, question_type, link)|
|
||||||
%dt
|
%dt
|
||||||
|
|
|
@ -122,3 +122,5 @@ API_EDUCATION_URL="https://data.education.gouv.fr/api/records/1.0"
|
||||||
|
|
||||||
# Clé de chriffrement des données sensibles en base
|
# Clé de chriffrement des données sensibles en base
|
||||||
ENCRYPTION_SERVICE_SALT=""
|
ENCRYPTION_SERVICE_SALT=""
|
||||||
|
|
||||||
|
INVISIBLE_CAPTCHA_SECRET="kikooloool"
|
||||||
|
|
12
config/initializers/invisible_captcha.rb
Normal file
12
config/initializers/invisible_captcha.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
InvisibleCaptcha.setup do |config|
|
||||||
|
# config.honeypots << ['more', 'fake', 'attribute', 'names']
|
||||||
|
# config.visual_honeypots = false
|
||||||
|
# config.timestamp_threshold = 2
|
||||||
|
config.timestamp_enabled = !Rails.env.test?
|
||||||
|
# config.injectable_styles = false
|
||||||
|
config.spinner_enabled = !Rails.env.test?
|
||||||
|
|
||||||
|
# Leave these unset if you want to use I18n (see below)
|
||||||
|
# config.sentence_for_humans = 'If you are a human, ignore this field'
|
||||||
|
# config.timestamp_error_message = 'Sorry, that was too quick! Please resubmit.'
|
||||||
|
end
|
|
@ -30,6 +30,9 @@
|
||||||
# available at http://guides.rubyonrails.org/i18n.html.
|
# available at http://guides.rubyonrails.org/i18n.html.
|
||||||
|
|
||||||
en:
|
en:
|
||||||
|
invisible_captcha:
|
||||||
|
custom_message: 'If you are a human, ignore this field'
|
||||||
|
|
||||||
help: 'Help'
|
help: 'Help'
|
||||||
utils:
|
utils:
|
||||||
'yes': Yes
|
'yes': Yes
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
# available at http://guides.rubyonrails.org/i18n.html.
|
# available at http://guides.rubyonrails.org/i18n.html.
|
||||||
|
|
||||||
fr:
|
fr:
|
||||||
|
invisible_captcha:
|
||||||
|
custom_message: 'Si vous êtes un humain, veuillez ignorer ce champs'
|
||||||
|
|
||||||
help: 'Aide'
|
help: 'Aide'
|
||||||
utils:
|
utils:
|
||||||
'yes': Oui
|
'yes': Oui
|
||||||
|
|
|
@ -51,30 +51,11 @@ describe SupportController, type: :controller do
|
||||||
|
|
||||||
describe "send form" do
|
describe "send form" do
|
||||||
subject do
|
subject do
|
||||||
post :create, params: { subject: 'bonjour', text: 'un message' }
|
post :create, params: params
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates a conversation on HelpScout' do
|
context "when invisible captcha is ignored" do
|
||||||
expect_any_instance_of(Helpscout::FormAdapter).to receive(:send_form).and_return(true)
|
let(:params) { { subject: 'bonjour', text: 'un message' } }
|
||||||
|
|
||||||
expect { subject }.to change(Commentaire, :count).by(0)
|
|
||||||
|
|
||||||
expect(flash[:notice]).to match('Votre message a été envoyé.')
|
|
||||||
expect(response).to redirect_to root_path(formulaire_contact_general_submitted: true)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when a drafted dossier is mentionned' do
|
|
||||||
let(:dossier) { create(:dossier) }
|
|
||||||
let(:user) { dossier.user }
|
|
||||||
|
|
||||||
subject do
|
|
||||||
post :create, params: {
|
|
||||||
dossier_id: dossier.id,
|
|
||||||
type: Helpscout::FormAdapter::TYPE_INSTRUCTION,
|
|
||||||
subject: 'bonjour',
|
|
||||||
text: 'un message'
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'creates a conversation on HelpScout' do
|
it 'creates a conversation on HelpScout' do
|
||||||
expect_any_instance_of(Helpscout::FormAdapter).to receive(:send_form).and_return(true)
|
expect_any_instance_of(Helpscout::FormAdapter).to receive(:send_form).and_return(true)
|
||||||
|
@ -84,33 +65,64 @@ describe SupportController, type: :controller do
|
||||||
expect(flash[:notice]).to match('Votre message a été envoyé.')
|
expect(flash[:notice]).to match('Votre message a été envoyé.')
|
||||||
expect(response).to redirect_to root_path(formulaire_contact_general_submitted: true)
|
expect(response).to redirect_to root_path(formulaire_contact_general_submitted: true)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
context 'when a submitted dossier is mentionned' do
|
context 'when a drafted dossier is mentionned' do
|
||||||
let(:dossier) { create(:dossier, :en_construction) }
|
let(:dossier) { create(:dossier) }
|
||||||
let(:user) { dossier.user }
|
let(:user) { dossier.user }
|
||||||
|
|
||||||
subject do
|
subject do
|
||||||
post :create, params: {
|
post :create, params: {
|
||||||
dossier_id: dossier.id,
|
dossier_id: dossier.id,
|
||||||
type: Helpscout::FormAdapter::TYPE_INSTRUCTION,
|
type: Helpscout::FormAdapter::TYPE_INSTRUCTION,
|
||||||
subject: 'bonjour',
|
subject: 'bonjour',
|
||||||
text: 'un message'
|
text: 'un message'
|
||||||
}
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates a conversation on HelpScout' do
|
||||||
|
expect_any_instance_of(Helpscout::FormAdapter).to receive(:send_form).and_return(true)
|
||||||
|
|
||||||
|
expect { subject }.to change(Commentaire, :count).by(0)
|
||||||
|
|
||||||
|
expect(flash[:notice]).to match('Votre message a été envoyé.')
|
||||||
|
expect(response).to redirect_to root_path(formulaire_contact_general_submitted: true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'posts the message to the dossier messagerie' do
|
context 'when a submitted dossier is mentionned' do
|
||||||
expect_any_instance_of(Helpscout::FormAdapter).not_to receive(:send_form)
|
let(:dossier) { create(:dossier, :en_construction) }
|
||||||
|
let(:user) { dossier.user }
|
||||||
|
|
||||||
expect { subject }.to change(Commentaire, :count).by(1)
|
subject do
|
||||||
|
post :create, params: {
|
||||||
|
dossier_id: dossier.id,
|
||||||
|
type: Helpscout::FormAdapter::TYPE_INSTRUCTION,
|
||||||
|
subject: 'bonjour',
|
||||||
|
text: 'un message'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
expect(Commentaire.last.email).to eq(user.email)
|
it 'posts the message to the dossier messagerie' do
|
||||||
expect(Commentaire.last.dossier).to eq(dossier)
|
expect_any_instance_of(Helpscout::FormAdapter).not_to receive(:send_form)
|
||||||
expect(Commentaire.last.body).to include('[bonjour]')
|
|
||||||
expect(Commentaire.last.body).to include('un message')
|
|
||||||
|
|
||||||
expect(flash[:notice]).to match('Votre message a été envoyé sur la messagerie de votre dossier.')
|
expect { subject }.to change(Commentaire, :count).by(1)
|
||||||
expect(response).to redirect_to messagerie_dossier_path(dossier)
|
|
||||||
|
expect(Commentaire.last.email).to eq(user.email)
|
||||||
|
expect(Commentaire.last.dossier).to eq(dossier)
|
||||||
|
expect(Commentaire.last.body).to include('[bonjour]')
|
||||||
|
expect(Commentaire.last.body).to include('un message')
|
||||||
|
|
||||||
|
expect(flash[:notice]).to match('Votre message a été envoyé sur la messagerie de votre dossier.')
|
||||||
|
expect(response).to redirect_to messagerie_dossier_path(dossier)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when invisible captcha is filled" do
|
||||||
|
let(:params) { { subject: 'bonjour', text: 'un message', InvisibleCaptcha.honeypots.sample => 'boom' } }
|
||||||
|
it 'does not create a conversation on HelpScout' do
|
||||||
|
expect { subject }.not_to change(Commentaire, :count)
|
||||||
|
expect(flash[:alert]).to eq(I18n.t('invisible_captcha.custom_message'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue