mirror of https://github.com/Siphonay/mastodon
add optional registration verification with hCaptcha
This commit is contained in:
parent
9c61dadc0d
commit
3d9f99a883
|
@ -290,3 +290,9 @@ STREAMING_CLUSTER_NUM=1
|
||||||
# Only allow federation with whitelisted domains, see
|
# Only allow federation with whitelisted domains, see
|
||||||
# https://docs.joinmastodon.org/admin/config/#whitelist_mode
|
# https://docs.joinmastodon.org/admin/config/#whitelist_mode
|
||||||
# WHITELIST_MODE=true
|
# WHITELIST_MODE=true
|
||||||
|
|
||||||
|
# Optional hCaptcha verification on user signup
|
||||||
|
# If the feature is enabled and no keys are specified here, dummy keys will be used and no actual verification will be taking place.
|
||||||
|
# HCAPTCHA_ENABLED=
|
||||||
|
# HCAPTCHA_SITE_KEY=
|
||||||
|
# HCAPTCHA_SECRET_KEY=
|
2
Gemfile
2
Gemfile
|
@ -100,6 +100,8 @@ gem 'tzinfo-data', '~> 1.2019'
|
||||||
gem 'webpacker', '~> 4.2'
|
gem 'webpacker', '~> 4.2'
|
||||||
gem 'webpush'
|
gem 'webpush'
|
||||||
|
|
||||||
|
gem 'hcaptcha', git: 'https://github.com/firstmoversadvantage/hcaptcha', ref: 'e65246bea49374566a9dbaead59fdb35b46b086d', require: 'hcaptcha/rails'
|
||||||
|
|
||||||
gem 'json-ld'
|
gem 'json-ld'
|
||||||
gem 'json-ld-preloaded', '~> 3.1'
|
gem 'json-ld-preloaded', '~> 3.1'
|
||||||
gem 'rdf-normalize', '~> 0.4'
|
gem 'rdf-normalize', '~> 0.4'
|
||||||
|
|
|
@ -28,6 +28,13 @@ GIT
|
||||||
specs:
|
specs:
|
||||||
nilsimsa (1.1.2)
|
nilsimsa (1.1.2)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: https://github.com/firstmoversadvantage/hcaptcha
|
||||||
|
revision: e65246bea49374566a9dbaead59fdb35b46b086d
|
||||||
|
ref: e65246bea49374566a9dbaead59fdb35b46b086d
|
||||||
|
specs:
|
||||||
|
hcaptcha (6.0.1)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
|
@ -704,6 +711,7 @@ DEPENDENCIES
|
||||||
fuubar (~> 2.5)
|
fuubar (~> 2.5)
|
||||||
goldfinger (~> 2.1)
|
goldfinger (~> 2.1)
|
||||||
hamlit-rails (~> 0.2)
|
hamlit-rails (~> 0.2)
|
||||||
|
hcaptcha
|
||||||
health_check!
|
health_check!
|
||||||
hiredis (~> 0.6)
|
hiredis (~> 0.6)
|
||||||
htmlentities (~> 4.3)
|
htmlentities (~> 4.3)
|
||||||
|
|
|
@ -37,6 +37,7 @@ module Admin
|
||||||
@keybase_integration = Setting.enable_keybase
|
@keybase_integration = Setting.enable_keybase
|
||||||
@spam_check_enabled = Setting.spam_check_enabled
|
@spam_check_enabled = Setting.spam_check_enabled
|
||||||
@trends_enabled = Setting.trends
|
@trends_enabled = Setting.trends
|
||||||
|
@hcaptcha_enabled = ENV['HCAPTCHA_ENABLED'] == 'true'
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -21,13 +21,14 @@ class Api::V1::AccountsController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
token = AppSignUpService.new.call(doorkeeper_token.application, account_params)
|
not_found
|
||||||
response = Doorkeeper::OAuth::TokenResponse.new(token)
|
# token = AppSignUpService.new.call(doorkeeper_token.application, account_params)
|
||||||
|
# response = Doorkeeper::OAuth::TokenResponse.new(token)
|
||||||
|
|
||||||
headers.merge!(response.headers)
|
# headers.merge!(response.headers)
|
||||||
|
|
||||||
self.response_body = Oj.dump(response.body)
|
# self.response_body = Oj.dump(response.body)
|
||||||
self.status = response.status
|
# self.status = response.status
|
||||||
end
|
end
|
||||||
|
|
||||||
def follow
|
def follow
|
||||||
|
|
|
@ -12,6 +12,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
before_action :set_body_classes, only: [:new, :create, :edit, :update]
|
before_action :set_body_classes, only: [:new, :create, :edit, :update]
|
||||||
before_action :require_not_suspended!, only: [:update]
|
before_action :require_not_suspended!, only: [:update]
|
||||||
before_action :set_cache_headers, only: [:edit, :update]
|
before_action :set_cache_headers, only: [:edit, :update]
|
||||||
|
before_action :check_captcha, only: [:create]
|
||||||
|
|
||||||
skip_before_action :require_functional!, only: [:edit, :update]
|
skip_before_action :require_functional!, only: [:edit, :update]
|
||||||
|
|
||||||
|
@ -93,6 +94,15 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def check_captcha
|
||||||
|
if ENV['HCAPTCHA_ENABLED'] == 'true' && !verify_hcaptcha
|
||||||
|
self.resource = resource_class.new sign_up_params
|
||||||
|
resource.validate
|
||||||
|
flash[:alert] = Hcaptcha::Helpers.to_error_message(:verification_failed)
|
||||||
|
respond_with_navigational(resource) { render :new }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def set_pack
|
def set_pack
|
||||||
use_pack %w(edit update).include?(action_name) ? 'admin' : 'auth'
|
use_pack %w(edit update).include?(action_name) ? 'admin' : 'auth'
|
||||||
end
|
end
|
||||||
|
|
|
@ -148,4 +148,5 @@ module ApplicationHelper
|
||||||
json = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(state_params), serializer: InitialStateSerializer).to_json
|
json = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(state_params), serializer: InitialStateSerializer).to_json
|
||||||
content_tag(:script, json_escape(json).html_safe, id: 'initial-state', type: 'application/json')
|
content_tag(:script, json_escape(json).html_safe, id: 'initial-state', type: 'application/json')
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -230,6 +230,10 @@ code {
|
||||||
.input:last-child {
|
.input:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.h-captcha {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.fields-row {
|
.fields-row {
|
||||||
|
|
|
@ -239,6 +239,10 @@ code {
|
||||||
.input:last-child {
|
.input:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.h-captcha {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.fields-row {
|
.fields-row {
|
||||||
|
|
|
@ -18,6 +18,10 @@
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :agreement, as: :boolean, wrapper: :with_label, label: t('auth.checkbox_agreement_html', rules_path: about_more_path, terms_path: terms_path), disabled: closed_registrations?
|
= f.input :agreement, as: :boolean, wrapper: :with_label, label: t('auth.checkbox_agreement_html', rules_path: about_more_path, terms_path: terms_path), disabled: closed_registrations?
|
||||||
|
|
||||||
|
- if ENV['HCAPTCHA_ENABLED'] == 'true'
|
||||||
|
.fields-group
|
||||||
|
= hcaptcha_tags
|
||||||
|
|
||||||
.actions
|
.actions
|
||||||
= f.button :button, sign_up_message, type: :submit, class: 'button button-primary', disabled: closed_registrations?
|
= f.button :button, sign_up_message, type: :submit, class: 'button button-primary', disabled: closed_registrations?
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,8 @@
|
||||||
= feature_hint('PAM', @pam_enabled)
|
= feature_hint('PAM', @pam_enabled)
|
||||||
%li
|
%li
|
||||||
= feature_hint(t('admin.dashboard.hidden_service'), @hidden_service)
|
= feature_hint(t('admin.dashboard.hidden_service'), @hidden_service)
|
||||||
|
%li
|
||||||
|
= feature_hint(t('admin.dashboard.feature_hcaptcha'), @hcaptcha_enabled)
|
||||||
|
|
||||||
.dashboard__widgets__trends
|
.dashboard__widgets__trends
|
||||||
%div
|
%div
|
||||||
|
|
|
@ -35,6 +35,10 @@
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :agreement, as: :boolean, wrapper: :with_label, label: whitelist_mode? ? t('auth.checkbox_agreement_without_rules_html', terms_path: terms_path) : t('auth.checkbox_agreement_html', rules_path: about_more_path, terms_path: terms_path)
|
= f.input :agreement, as: :boolean, wrapper: :with_label, label: whitelist_mode? ? t('auth.checkbox_agreement_without_rules_html', terms_path: terms_path) : t('auth.checkbox_agreement_html', rules_path: about_more_path, terms_path: terms_path)
|
||||||
|
|
||||||
|
- if ENV['HCAPTCHA_ENABLED'] == 'true'
|
||||||
|
.fields-group
|
||||||
|
= hcaptcha_tags
|
||||||
|
|
||||||
.actions
|
.actions
|
||||||
= f.button :button, @invite.present? ? t('auth.register') : sign_up_message, type: :submit
|
= f.button :button, @invite.present? ? t('auth.register') : sign_up_message, type: :submit
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@ if Rails.env.production?
|
||||||
attachments_host = nil
|
attachments_host = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
hcaptcha_hosts = ["https://hcaptcha.com", "https://*.hcaptcha.com"]
|
||||||
|
|
||||||
data_hosts << attachments_host unless attachments_host.nil?
|
data_hosts << attachments_host unless attachments_host.nil?
|
||||||
|
|
||||||
if ENV['PAPERCLIP_ROOT_URL']
|
if ENV['PAPERCLIP_ROOT_URL']
|
||||||
|
@ -31,12 +33,12 @@ if Rails.env.production?
|
||||||
p.base_uri :none
|
p.base_uri :none
|
||||||
p.default_src :none
|
p.default_src :none
|
||||||
p.frame_ancestors :none
|
p.frame_ancestors :none
|
||||||
p.script_src :self, assets_host
|
p.script_src :self, assets_host, *hcaptcha_hosts
|
||||||
p.font_src :self, assets_host
|
p.font_src :self, assets_host
|
||||||
p.img_src :self, :data, :blob, *data_hosts
|
p.img_src :self, :data, :blob, *data_hosts
|
||||||
p.style_src :self, :unsafe_inline, assets_host
|
p.style_src :self, :unsafe_inline, assets_host, *hcaptcha_hosts
|
||||||
p.media_src :self, :data, *data_hosts
|
p.media_src :self, :data, *data_hosts
|
||||||
p.frame_src :self, :https
|
p.frame_src :self, :https, *hcaptcha_hosts
|
||||||
p.child_src :self, :blob, assets_host
|
p.child_src :self, :blob, assets_host
|
||||||
p.worker_src :self, :blob, assets_host
|
p.worker_src :self, :blob, assets_host
|
||||||
p.connect_src :self, :blob, :data, Rails.configuration.x.streaming_api_base_url, *data_hosts
|
p.connect_src :self, :blob, :data, Rails.configuration.x.streaming_api_base_url, *data_hosts
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Hcaptcha.configure do |config|
|
||||||
|
config.site_key = ENV.fetch('HCAPTCHA_SITE_KEY') { '10000000-ffff-ffff-ffff-000000000001' }
|
||||||
|
config.secret_key = ENV.fetch('HCAPTCHA_SECRET_KEY') { '0x0000000000000000000000000000000000000000' }
|
||||||
|
end
|
|
@ -324,6 +324,7 @@ en:
|
||||||
backlog: backlogged jobs
|
backlog: backlogged jobs
|
||||||
config: Configuration
|
config: Configuration
|
||||||
feature_deletions: Account deletions
|
feature_deletions: Account deletions
|
||||||
|
feature_hcaptcha: hCaptcha
|
||||||
feature_invites: Invite links
|
feature_invites: Invite links
|
||||||
feature_profile_directory: Profile directory
|
feature_profile_directory: Profile directory
|
||||||
feature_registrations: Registrations
|
feature_registrations: Registrations
|
||||||
|
@ -542,6 +543,8 @@ en:
|
||||||
deletion:
|
deletion:
|
||||||
desc_html: Allow anyone to delete their account
|
desc_html: Allow anyone to delete their account
|
||||||
title: Open account deletion
|
title: Open account deletion
|
||||||
|
errors:
|
||||||
|
captcha_fail: Captcha verification failed
|
||||||
min_invite_role:
|
min_invite_role:
|
||||||
disabled: No one
|
disabled: No one
|
||||||
title: Allow invitations by
|
title: Allow invitations by
|
||||||
|
|
Loading…
Reference in New Issue