Implement custom message for signup approvals

This commit is contained in:
Emelia Smith 2024-09-02 18:30:21 +02:00
parent 02633d6ebb
commit 745c17e75e
No known key found for this signature in database
11 changed files with 96 additions and 18 deletions

View file

@ -7,6 +7,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
layout :determine_layout
before_action :set_invite, only: [:new, :create]
before_action :set_invite_reason_message, only: [:new, :create]
before_action :check_enabled_registrations, only: [:new, :create]
before_action :configure_sign_up_params, only: [:create]
before_action :set_sessions, only: [:edit, :update]
@ -115,6 +116,12 @@ class Auth::RegistrationsController < Devise::RegistrationsController
end
end
def set_invite_reason_message
# rubocop:disable Rails/OutputSafety
@invite_reason_message = markdown.render(Setting.require_invite_message).html_safe if Setting.require_invite_message.present?
# rubocop:enable Rails/OutputSafety
end
def determine_layout
%w(edit update).include?(action_name) ? 'admin' : 'auth'
end
@ -147,4 +154,8 @@ class Auth::RegistrationsController < Devise::RegistrationsController
def set_cache_headers
response.cache_control.replace(private: true, no_store: true)
end
def markdown
@markdown ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML, no_images: true, filter_html: true, safe_links_only: true)
end
end

View file

@ -237,6 +237,20 @@ const onChangeRegistrationMode = (target: HTMLSelectElement) => {
} while (element && !element.classList.contains('fields-group'));
}
});
const requireInviteMessageInput = document.getElementById(
'form_admin_settings_require_invite_message',
);
if (requireInviteMessageInput instanceof HTMLTextAreaElement) {
const requireInviteMessageWrapper =
requireInviteMessageInput.closest('.input');
requireInviteMessageInput.disabled = !enabled;
if (enabled) {
requireInviteMessageWrapper?.classList.remove('disabled');
} else {
requireInviteMessageWrapper?.classList.add('disabled');
}
}
};
const convertUTCDateTimeToLocal = (value: string) => {

View file

@ -136,7 +136,7 @@ code {
font-size: 17px;
line-height: 22px;
color: $secondary-text-color;
margin-bottom: 30px;
margin-bottom: 20px;
&.invited-by {
margin-bottom: 15px;
@ -147,6 +147,36 @@ code {
}
}
.invite_reason_message {
font-size: 14px;
line-height: 20px;
color: $secondary-text-color;
margin-bottom: 20px;
p + p {
margin-top: 10px;
}
em {
font-style: italic;
}
a {
color: $highlight-text-color;
text-decoration: underline;
&:hover,
&:active,
&:focus {
text-decoration: none;
}
}
}
.user_invite_request_text {
margin-top: 10px;
}
.rules-list {
font-size: 17px;
line-height: 22px;
@ -987,7 +1017,8 @@ code {
.form_admin_settings_site_extended_description,
.form_admin_settings_site_terms,
.form_admin_settings_custom_css,
.form_admin_settings_closed_registrations_message {
.form_admin_settings_closed_registrations_message,
.form_admin_settings_require_invite_message {
textarea {
font-family: $font-monospace, monospace;
}

View file

@ -31,6 +31,7 @@ class Form::AdminSettings
show_domain_blocks_rationale
noindex
require_invite_text
require_invite_message
media_cache_retention_period
content_cache_retention_period
backups_retention_period
@ -83,6 +84,7 @@ class Form::AdminSettings
validates :show_domain_blocks_rationale, inclusion: { in: %w(disabled users all) }, if: -> { defined?(@show_domain_blocks_rationale) }
validates :media_cache_retention_period, :content_cache_retention_period, :backups_retention_period, numericality: { only_integer: true }, allow_blank: true, if: -> { defined?(@media_cache_retention_period) || defined?(@content_cache_retention_period) || defined?(@backups_retention_period) }
validates :site_short_description, length: { maximum: 200 }, if: -> { defined?(@site_short_description) }
validates :require_invite_message, length: { maximum: 500 }, if: -> { defined?(@require_invite_message) }
validates :status_page_url, url: true, allow_blank: true
validate :validate_site_uploads

View file

@ -102,7 +102,8 @@ class REST::InstanceSerializer < ActiveModel::Serializer
{
enabled: registrations_enabled?,
approval_required: Setting.registrations_mode == 'approved',
message: registrations_enabled? ? nil : registrations_message,
reason_required: registrations_require_reason?,
message: registrations_message,
url: ENV.fetch('SSO_ACCOUNT_SIGN_UP', nil),
}
end
@ -119,8 +120,16 @@ class REST::InstanceSerializer < ActiveModel::Serializer
Setting.registrations_mode != 'none' && !Rails.configuration.x.single_user_mode
end
def registrations_require_reason?
Setting.registrations_mode == 'approved' && Setting.require_invite_text?
end
def registrations_message
if registrations_enabled? == false
markdown.render(Setting.closed_registrations_message) if Setting.closed_registrations_message.present?
elsif registrations_require_reason?
markdown.render(Setting.require_invite_message) if Setting.require_invite_message.present?
end
end
def markdown

View file

@ -21,20 +21,25 @@
warning_hint: I18n.t('admin.settings.registrations_mode.warning_hint'),
wrapper: :with_label
.fields-row__column.fields-row__column-6.fields-group
= f.input :require_invite_text,
as: :boolean,
disabled: !approved_registrations?,
wrapper: :with_label
- if captcha_available?
.fields-group
.fields-row__column.fields-row__column-6.fields-group
= f.input :captcha_enabled,
as: :boolean,
hint: t('admin.settings.captcha_enabled.desc_html'),
label: t('admin.settings.captcha_enabled.title'),
wrapper: :with_label
.fields-group
= f.input :require_invite_message,
as: :text,
input_html: { rows: 2 },
wrapper: :with_block_label
= f.input :require_invite_text,
as: :boolean,
disabled: !approved_registrations?,
wrapper: :with_label
.fields-group
= f.input :closed_registrations_message,
as: :text,

View file

@ -56,6 +56,9 @@
- if approved_registrations? && @invite.blank?
%p.lead= t('auth.sign_up.manual_review', domain: site_hostname)
- if @invite_reason_message.present?
.invite_reason_message= @invite_reason_message
.fields-group
= f.simple_fields_for :invite_request, resource.invite_request || resource.build_invite_request do |invite_request_fields|
= invite_request_fields.input :text,

View file

@ -1086,7 +1086,7 @@ en-GB:
preamble_html: Log in with your <strong>%{domain}</strong> credentials. If your account is hosted on a different server, you will not be able to log in here.
title: Log in to %{domain}
sign_up:
manual_review: Sign-ups on %{domain} go through manual review by our moderators. To help us process your registration, write a bit about yourself and why you want an account on %{domain}.
manual_review: Sign-ups on %{domain} go through manual review by our moderators.
preamble: With an account on this Mastodon server, you'll be able to follow any other person on the network, regardless of where their account is hosted.
title: Let's get you set up on %{domain}.
status:

View file

@ -1144,7 +1144,7 @@ en:
preamble_html: Login with your <strong>%{domain}</strong> credentials. If your account is hosted on a different server, you will not be able to log in here.
title: Login to %{domain}
sign_up:
manual_review: Sign-ups on %{domain} go through manual review by our moderators. To help us process your registration, write a bit about yourself and why you want an account on %{domain}.
manual_review: Sign-ups on %{domain} go through manual review by our moderators.
preamble: With an account on this Mastodon server, you'll be able to follow any other person on the network, regardless of where their account is hosted.
title: Let's get you set up on %{domain}.
status:

View file

@ -89,6 +89,7 @@ en:
peers_api_enabled: A list of domain names this server has encountered in the fediverse. No data is included here about whether you federate with a given server, just that your server knows about it. This is used by services that collect statistics on federation in a general sense.
profile_directory: The profile directory lists all users who have opted-in to be discoverable.
require_invite_text: When sign-ups require manual approval, make the “Why do you want to join?” text input mandatory rather than optional
require_invite_message: Markdown is allowed, leave empty to disable. Is not localised for the user.
site_contact_email: How people can reach you for legal or support inquiries.
site_contact_username: How people can reach you on Mastodon.
site_extended_description: Any additional information that may be useful to visitors and your users. Can be structured with Markdown syntax.
@ -256,6 +257,7 @@ en:
profile_directory: Enable profile directory
registrations_mode: Who can sign-up
require_invite_text: Require a reason to join
require_invite_message: Message when approval is required for sign up
show_domain_blocks: Show domain blocks
show_domain_blocks_rationale: Show why domains were blocked
site_contact_email: Contact e-mail

View file

@ -36,6 +36,7 @@ defaults: &defaults
show_domain_blocks: 'disabled'
show_domain_blocks_rationale: 'disabled'
require_invite_text: false
require_invite_message: 'To help us process your registration, write a bit about yourself and why you want an account.'
backups_retention_period: 7
captcha_enabled: false