Skip to content

Instantly share code, notes, and snippets.

@bensheldon
Created November 27, 2023 01:37
Show Gist options
  • Save bensheldon/104bded9b838c83914747542770cc1f0 to your computer and use it in GitHub Desktop.
Save bensheldon/104bded9b838c83914747542770cc1f0 to your computer and use it in GitHub Desktop.
diff --git a/app/controllers/account/registrations_controller.rb b/app/controllers/account/registrations_controller.rb
index 376f20a77..a554c9f8d 100644
--- a/app/controllers/account/registrations_controller.rb
+++ b/app/controllers/account/registrations_controller.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
module Account
class RegistrationsController < Devise::RegistrationsController
+ before_action :reject_spam, only: :create
+
# GET /resource
def new
super do |_resource|
@@ -49,5 +51,14 @@ def after_inactive_sign_up_path_for(_resource)
flash.discard :notice # don't set a flash message, use template below
after_registration_path
end
+
+ private
+
+ def reject_spam
+ honeypot_value = params.delete(HONEYPOT_FIELD_NAME)
+ if honeypot_value.present?
+ render :new, status: :bad_request, alert: "Something went wrong. Please contact us."
+ end
+ end
end
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index f721d94e6..0501cffd2 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
class ApplicationController < ActionController::Base
VISITOR_COOKIE_NAME = :_dayoftheshirt_visitor
+ HONEYPOT_FIELD_NAME = 'form_context_content'
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 776fb83c2..71b33a3a8 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -17,6 +17,10 @@ def human_order(order)
end
end
+ def honeypot_tag
+ label_tag ApplicationController::HONEYPOT_FIELD_NAME, '', style: 'display: none;', value: ''
+ end
+
def form_errors_for(model)
return unless model.errors.any?
diff --git a/app/views/account/registrations/_signup_form.slim b/app/views/account/registrations/_signup_form.slim
deleted file mode 100644
index e788cae8c..000000000
--- a/app/views/account/registrations/_signup_form.slim
+++ /dev/null
@@ -1,8 +0,0 @@
-= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { role: 'form' }) do |f|
- = form_errors_for resource
- .form-group class=local_assigns[:form_group_class]
- = f.label :email, class: 'control-label'
- = f.email_field :email, class: 'form-control',
- placeholder: 'Your email address'
-
- = f.submit 'Sign up', class: "btn btn-block #{local_assigns.fetch(:button_class, 'btn-primary')}"
diff --git a/app/views/account/registrations/new.html.slim b/app/views/account/registrations/new.html.slim
index e3a391f76..11f274390 100644
--- a/app/views/account/registrations/new.html.slim
+++ b/app/views/account/registrations/new.html.slim
@@ -2,7 +2,14 @@
.row
.col-sm-6.col-sm-push-6
h2.header-top Sign up
- = render 'signup_form', button_class: 'btn-success btn-lg', form_group_class: 'form-group-lg'
+ = form_for(resource, as: resource_name, url: registration_path(resource_name), html: {role: 'form'}) do |f|
+ = honeypot_tag
+ = form_errors_for resource
+ .form-group class='form-group-lg'
+ = f.label :email, class: 'control-label'
+ = f.email_field :email, class: 'form-control',
+ placeholder: 'Your email address'
+ = f.submit 'Sign up', class: "btn btn-block btn-success btn-lg"
br
p.text-center
' Already have an account?
diff --git a/app/views/shared/_signup_form.slim b/app/views/shared/_signup_form.slim
deleted file mode 100644
index 63973abf5..000000000
--- a/app/views/shared/_signup_form.slim
+++ /dev/null
@@ -1,6 +0,0 @@
-= form_for(User.new, as: :user, url: registration_path(:user), html: { role: 'form', class: 'form-inline' }) do |f|
- .form-group
- => f.label :email, class: 'control-label'
- => f.email_field :email, class: 'form-control',
- placeholder: 'Your email address'
- =< f.submit 'Sign up', class: "btn btn-primary"
diff --git a/app/views/shirts/index.html.slim b/app/views/shirts/index.html.slim
index 221fadb1a..3f19709b6 100644
--- a/app/views/shirts/index.html.slim
+++ b/app/views/shirts/index.html.slim
@@ -21,6 +21,7 @@ ruby:
br
.col-xs-10.col-xs-push-1.col-sm-6.col-sm-push-3.col-md-4.col-md-push-4
= form_for(User.new, url: registration_path(:user), html: { role: 'form' }) do |f|
+ = honeypot_tag
.input-group
= f.label :email, class: 'control-label sr-only'
= f.email_field :email, class: 'form-control input-ghost input-rounded-left',
diff --git a/spec/controllers/account/registrations_controller_spec.rb b/spec/controllers/account/registrations_controller_spec.rb
index 37572b161..801e58a94 100644
--- a/spec/controllers/account/registrations_controller_spec.rb
+++ b/spec/controllers/account/registrations_controller_spec.rb
@@ -25,6 +25,18 @@
expect(user.visitor_created_at).to be_within(1.second).of visitor_created_at
expect(user.last_seen_at).to be_within(1.second).of visitor_last_seen_at
end
+
+ context 'when honeypot field has value' do
+ it 'returns returns a 400 error' do
+ user_params = {
+ email: 'test@example.com',
+ }
+
+ post :create, params: { user: user_params, form_context_content: 'spam' }
+ expect(response).to have_http_status :bad_request
+ expect(response).to render_template :new
+ end
+ end
end
describe '#edit' do
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment