Skip to content

Commit 0f4f066

Browse files
committed
WIP: feat(captcha): implement captcha validation hooks and integrate into registration process
1 parent 80fb95a commit 0f4f066

File tree

7 files changed

+77
-0
lines changed

7 files changed

+77
-0
lines changed

app/controllers/better_together/users/registrations_controller.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ def create
8080
return
8181
end
8282

83+
# Validate captcha if enabled by host application
84+
unless validate_captcha_if_enabled
85+
build_resource(sign_up_params)
86+
handle_captcha_validation_failure(resource)
87+
return
88+
end
89+
8390
ActiveRecord::Base.transaction do
8491
super do |user|
8592
handle_user_creation(user) if user.persisted?
@@ -104,6 +111,25 @@ def set_required_agreements
104111
@code_of_conduct_agreement = BetterTogether::Agreement.find_by(identifier: 'code_of_conduct')
105112
end
106113

114+
# Hook method for host applications to implement captcha validation
115+
# Override this method in host applications to add Turnstile or other captcha validation
116+
# @return [Boolean] true if captcha is valid or not enabled, false if validation fails
117+
def validate_captcha_if_enabled
118+
# Default implementation - no captcha validation
119+
# Host applications should override this method to implement their captcha logic
120+
true
121+
end
122+
123+
# Hook method for host applications to handle captcha validation failures
124+
# Override this method in host applications to customize error handling
125+
# @param resource [User] the user resource being created
126+
def handle_captcha_validation_failure(resource)
127+
# Default implementation - adds a generic error message
128+
resource.errors.add(:base, I18n.t('better_together.registrations.captcha_validation_failed',
129+
default: 'Security verification failed. Please try again.'))
130+
respond_with resource
131+
end
132+
107133
def after_sign_up_path_for(resource)
108134
# Redirect to event if signed up via event invitation
109135
return better_together.event_path(@event_invitation.event) if @event_invitation&.event
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<%# Override this partial in your host app to add additional fields to the registration form %>
2+
<%# Place custom form elements here (e.g., CAPTCHA, extra validation fields, etc.) %>
3+
<%# Available locals: form (form builder), resource (user resource being created) %>

app/views/devise/registrations/new.html.erb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@
130130
<% end %>
131131
<% end %>
132132

133+
<!-- Host App Extensible Content (e.g., CAPTCHA, additional fields) -->
134+
<%= render partial: 'devise/registrations/extra_registration_fields', locals: { form: f, resource: resource } %>
135+
133136
<!-- Submit Button -->
134137
<div class="text-center">
135138
<%= f.submit t('.sign_up'), class: 'btn btn-primary' %>

config/locales/en.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,6 +1721,7 @@ en:
17211721
agreements_must_accept: You must accept the Terms of Service and Privacy Policy
17221722
to continue.
17231723
agreements_required: You must accept the Privacy Policy and Terms of Service
1724+
captcha_validation_failed: Security verification failed. Please complete the security check and try again.
17241725
code_of_conduct:
17251726
label: I agree to the Code of Conduct
17261727
email:

config/locales/es.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,6 +1737,7 @@ es:
17371737
agreements_must_accept: You must accept the Terms of Service and Privacy Policy
17381738
to continue.
17391739
agreements_required: You must accept the Privacy Policy and Terms of Service
1740+
captcha_validation_failed: La verificación de seguridad falló. Por favor, completa la verificación de seguridad e inténtalo de nuevo.
17401741
code_of_conduct:
17411742
label: I agree to the Code of Conduct
17421743
email:

config/locales/fr.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,6 +1745,7 @@ fr:
17451745
agreements_must_accept: You must accept the Terms of Service and Privacy Policy
17461746
to continue.
17471747
agreements_required: You must accept the Privacy Policy and Terms of Service
1748+
captcha_validation_failed: La vérification de sécurité a échoué. Veuillez compléter la vérification de sécurité et réessayer.
17481749
code_of_conduct:
17491750
label: I agree to the Code of Conduct
17501751
email:
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails_helper'
4+
5+
RSpec.describe BetterTogether::Users::RegistrationsController, :skip_host_setup,
6+
type: :controller do
7+
include BetterTogether::CapybaraFeatureHelpers
8+
9+
routes { BetterTogether::Engine.routes }
10+
11+
before do
12+
configure_host_platform
13+
end
14+
15+
describe 'captcha hook methods', :no_auth do
16+
describe '#validate_captcha_if_enabled' do
17+
let(:controller_instance) { described_class.new }
18+
19+
it 'returns true by default (no captcha validation)' do
20+
expect(controller_instance.send(:validate_captcha_if_enabled)).to be true
21+
end
22+
end
23+
24+
describe '#handle_captcha_validation_failure' do
25+
let(:user) { build(:better_together_user) }
26+
let(:controller_instance) { described_class.new }
27+
28+
before do
29+
allow(controller_instance).to receive(:respond_with)
30+
end
31+
32+
it 'adds error to resource and calls respond_with' do
33+
controller_instance.send(:handle_captcha_validation_failure, user)
34+
35+
expect(user.errors[:base]).to include('Security verification failed. Please try again.')
36+
expect(controller_instance).to have_received(:respond_with).with(user)
37+
end
38+
end
39+
end
40+
41+
# Integration test for the complete captcha flow will be handled in feature specs
42+
end

0 commit comments

Comments
 (0)