Add server rules to sign-up flow (#19296)
This commit is contained in:
parent
26f2586b62
commit
679274465b
6 changed files with 101 additions and 30 deletions
|
@ -14,6 +14,8 @@ 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 :set_rules, only: :new
|
||||||
|
before_action :require_rules_acceptance!, only: :new
|
||||||
before_action :set_registration_form_time, only: :new
|
before_action :set_registration_form_time, only: :new
|
||||||
|
|
||||||
skip_before_action :require_functional!, only: [:edit, :update]
|
skip_before_action :require_functional!, only: [:edit, :update]
|
||||||
|
@ -55,7 +57,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
|
|
||||||
def configure_sign_up_params
|
def configure_sign_up_params
|
||||||
devise_parameter_sanitizer.permit(:sign_up) do |u|
|
devise_parameter_sanitizer.permit(:sign_up) do |u|
|
||||||
u.permit({ account_attributes: [:username], invite_request_attributes: [:text] }, :email, :password, :password_confirmation, :invite_code, :agreement, :website, :confirm_password)
|
u.permit({ account_attributes: [:username, :display_name], invite_request_attributes: [:text] }, :email, :password, :password_confirmation, :invite_code, :agreement, :website, :confirm_password)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -138,6 +140,18 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
forbidden if current_account.suspended?
|
forbidden if current_account.suspended?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_rules
|
||||||
|
@rules = Rule.ordered
|
||||||
|
end
|
||||||
|
|
||||||
|
def require_rules_acceptance!
|
||||||
|
return if @rules.empty? || (session[:accept_token].present? && params[:accept] == session[:accept_token])
|
||||||
|
|
||||||
|
@accept_token = session[:accept_token] = SecureRandom.hex
|
||||||
|
|
||||||
|
set_locale { render :rules }
|
||||||
|
end
|
||||||
|
|
||||||
def set_cache_headers
|
def set_cache_headers
|
||||||
response.headers['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate'
|
response.headers['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate'
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,11 +9,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo-container {
|
.logo-container {
|
||||||
margin: 100px auto 50px;
|
margin: 50px auto;
|
||||||
|
|
||||||
@media screen and (max-width: 500px) {
|
|
||||||
margin: 40px auto 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -6,9 +6,10 @@ code {
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-container {
|
.form-container {
|
||||||
max-width: 400px;
|
max-width: 450px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
margin: 0 auto;
|
padding-bottom: 50px;
|
||||||
|
margin: 50px auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.indicator-icon {
|
.indicator-icon {
|
||||||
|
@ -124,13 +125,34 @@ code {
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
color: #d9e1e8;
|
font-size: 28px;
|
||||||
font-size: 20px;
|
line-height: 33px;
|
||||||
line-height: 28px;
|
font-weight: 700;
|
||||||
font-weight: 400;
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lead {
|
||||||
|
font-size: 17px;
|
||||||
|
line-height: 22px;
|
||||||
|
color: $secondary-text-color;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rules-list {
|
||||||
|
list-style: decimal;
|
||||||
|
font-size: 17px;
|
||||||
|
line-height: 22px;
|
||||||
|
font-weight: 500;
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
padding: 0.5em 1em !important;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
border-color: lighten($ui-base-color, 8%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.hint {
|
.hint {
|
||||||
color: $darker-text-color;
|
color: $darker-text-color;
|
||||||
|
|
||||||
|
@ -461,6 +483,11 @@ code {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stacked-actions {
|
||||||
|
margin-top: 30px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
button,
|
button,
|
||||||
.button,
|
.button,
|
||||||
.block-button {
|
.block-button {
|
||||||
|
@ -512,6 +539,16 @@ code {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button.button-tertiary {
|
||||||
|
padding: 9px;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
= render partial: 'shared/og', locals: { description: description_for_sign_up }
|
= render partial: 'shared/og', locals: { description: description_for_sign_up }
|
||||||
|
|
||||||
= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { novalidate: false }) do |f|
|
= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { novalidate: false }) do |f|
|
||||||
|
%h1.title= t('auth.sign_up.title', domain: site_hostname)
|
||||||
|
%p.lead= t('auth.sign_up.preamble')
|
||||||
|
|
||||||
= render 'shared/error_messages', object: resource
|
= render 'shared/error_messages', object: resource
|
||||||
|
|
||||||
- if @invite.present? && @invite.autofollow?
|
- if @invite.present? && @invite.autofollow?
|
||||||
|
@ -12,20 +15,14 @@
|
||||||
%p.hint= t('invites.invited_by')
|
%p.hint= t('invites.invited_by')
|
||||||
= render 'application/card', account: @invite.user.account
|
= render 'application/card', account: @invite.user.account
|
||||||
|
|
||||||
|
.fields-group
|
||||||
= f.simple_fields_for :account do |ff|
|
= f.simple_fields_for :account do |ff|
|
||||||
.fields-group
|
= ff.input :display_name, wrapper: :with_label, label: false, required: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.display_name'), :autocomplete => 'off', placeholder: t('simple_form.labels.defaults.display_name') }
|
||||||
= ff.input :username, wrapper: :with_label, autofocus: true, label: t('simple_form.labels.defaults.username'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username'), :autocomplete => 'off', pattern: '[a-zA-Z0-9_]+', maxlength: 30 }, append: "@#{site_hostname}", hint: t('simple_form.hints.defaults.username', domain: site_hostname)
|
= ff.input :username, wrapper: :with_label, label: false, required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username'), :autocomplete => 'off', placeholder: t('simple_form.labels.defaults.username'), pattern: '[a-zA-Z0-9_]+', maxlength: 30 }, append: "@#{site_hostname}", hint: false
|
||||||
|
= f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email'), :autocomplete => 'off' }, hint: false
|
||||||
.fields-group
|
= f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'new-password', :minlength => User.password_length.first, :maxlength => User.password_length.last }, hint: false
|
||||||
= f.input :email, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email'), :autocomplete => 'off' }
|
= f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password'), :autocomplete => 'new-password' }, hint: false
|
||||||
|
= f.input :confirm_password, as: :string, placeholder: t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), required: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), :autocomplete => 'off' }, hint: false
|
||||||
.fields-group
|
|
||||||
= f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off', :minlength => User.password_length.first, :maxlength => User.password_length.last }
|
|
||||||
|
|
||||||
.fields-group
|
|
||||||
= f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password'), :autocomplete => 'off' }
|
|
||||||
= f.input :confirm_password, as: :string, wrapper: :with_label, label: t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), required: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), :autocomplete => 'off' }
|
|
||||||
|
|
||||||
= f.input :website, as: :url, wrapper: :with_label, label: t('simple_form.labels.defaults.honeypot', label: 'Website'), required: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.honeypot', label: 'Website'), :autocomplete => 'off' }
|
= f.input :website, as: :url, wrapper: :with_label, label: t('simple_form.labels.defaults.honeypot', label: 'Website'), required: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.honeypot', label: 'Website'), :autocomplete => 'off' }
|
||||||
|
|
||||||
- if approved_registrations? && !@invite.present?
|
- if approved_registrations? && !@invite.present?
|
||||||
|
@ -33,10 +30,12 @@
|
||||||
= f.simple_fields_for :invite_request, resource.invite_request || resource.build_invite_request do |invite_request_fields|
|
= f.simple_fields_for :invite_request, resource.invite_request || resource.build_invite_request do |invite_request_fields|
|
||||||
= invite_request_fields.input :text, as: :text, wrapper: :with_block_label, required: Setting.require_invite_text
|
= invite_request_fields.input :text, as: :text, wrapper: :with_block_label, required: Setting.require_invite_text
|
||||||
|
|
||||||
|
|
||||||
|
= hidden_field_tag :accept, params[:accept]
|
||||||
= f.input :invite_code, as: :hidden
|
= f.input :invite_code, as: :hidden
|
||||||
|
|
||||||
.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), required: true
|
= f.input :agreement, as: :boolean, wrapper: :with_label, label: t('auth.privacy_policy_agreement_html', rules_path: about_more_path, privacy_policy_path: privacy_policy_path), required: true
|
||||||
|
|
||||||
.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
|
||||||
|
|
20
app/views/auth/registrations/rules.html.haml
Normal file
20
app/views/auth/registrations/rules.html.haml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
- content_for :page_title do
|
||||||
|
= t('auth.register')
|
||||||
|
|
||||||
|
- content_for :header_tags do
|
||||||
|
= render partial: 'shared/og', locals: { description: description_for_sign_up }
|
||||||
|
|
||||||
|
.simple_form
|
||||||
|
%h1.title= t('auth.rules.title')
|
||||||
|
%p.lead= t('auth.rules.preamble', domain: site_hostname)
|
||||||
|
|
||||||
|
%ol.rules-list
|
||||||
|
- @rules.each do |rule|
|
||||||
|
%li
|
||||||
|
.rules-list__text= rule.text
|
||||||
|
|
||||||
|
.stacked-actions
|
||||||
|
= link_to t('auth.rules.accept'), new_user_registration_path(accept: @accept_token), class: 'button'
|
||||||
|
= link_to t('auth.rules.back'), root_path, class: 'button button-tertiary'
|
||||||
|
|
||||||
|
.form-footer= render 'auth/shared/links'
|
|
@ -1001,10 +1001,8 @@ en:
|
||||||
warning: Be very careful with this data. Never share it with anyone!
|
warning: Be very careful with this data. Never share it with anyone!
|
||||||
your_token: Your access token
|
your_token: Your access token
|
||||||
auth:
|
auth:
|
||||||
apply_for_account: Request an invite
|
apply_for_account: Get on waitlist
|
||||||
change_password: Password
|
change_password: Password
|
||||||
checkbox_agreement_html: I agree to the <a href="%{rules_path}" target="_blank">server rules</a> and <a href="%{terms_path}" target="_blank">terms of service</a>
|
|
||||||
checkbox_agreement_without_rules_html: I agree to the <a href="%{terms_path}" target="_blank">terms of service</a>
|
|
||||||
delete_account: Delete account
|
delete_account: Delete account
|
||||||
delete_account_html: If you wish to delete your account, you can <a href="%{path}">proceed here</a>. You will be asked for confirmation.
|
delete_account_html: If you wish to delete your account, you can <a href="%{path}">proceed here</a>. You will be asked for confirmation.
|
||||||
description:
|
description:
|
||||||
|
@ -1023,6 +1021,7 @@ en:
|
||||||
migrate_account: Move to a different account
|
migrate_account: Move to a different account
|
||||||
migrate_account_html: If you wish to redirect this account to a different one, you can <a href="%{path}">configure it here</a>.
|
migrate_account_html: If you wish to redirect this account to a different one, you can <a href="%{path}">configure it here</a>.
|
||||||
or_log_in_with: Or log in with
|
or_log_in_with: Or log in with
|
||||||
|
privacy_policy_agreement_html: I have read and agree to the <a href="%{privacy_policy_path}" target="_blank">privacy policy</a>
|
||||||
providers:
|
providers:
|
||||||
cas: CAS
|
cas: CAS
|
||||||
saml: SAML
|
saml: SAML
|
||||||
|
@ -1030,12 +1029,18 @@ en:
|
||||||
registration_closed: "%{instance} is not accepting new members"
|
registration_closed: "%{instance} is not accepting new members"
|
||||||
resend_confirmation: Resend confirmation instructions
|
resend_confirmation: Resend confirmation instructions
|
||||||
reset_password: Reset password
|
reset_password: Reset password
|
||||||
|
rules:
|
||||||
|
preamble: These are set and enforced by the %{domain} moderators.
|
||||||
|
title: Some ground rules.
|
||||||
security: Security
|
security: Security
|
||||||
set_new_password: Set new password
|
set_new_password: Set new password
|
||||||
setup:
|
setup:
|
||||||
email_below_hint_html: If the below e-mail address is incorrect, you can change it here and receive a new confirmation e-mail.
|
email_below_hint_html: If the below e-mail address is incorrect, you can change it here and receive a new confirmation e-mail.
|
||||||
email_settings_hint_html: The confirmation e-mail was sent to %{email}. If that e-mail address is not correct, you can change it in account settings.
|
email_settings_hint_html: The confirmation e-mail was sent to %{email}. If that e-mail address is not correct, you can change it in account settings.
|
||||||
title: Setup
|
title: Setup
|
||||||
|
sign_up:
|
||||||
|
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:
|
status:
|
||||||
account_status: Account status
|
account_status: Account status
|
||||||
confirming: Waiting for e-mail confirmation to be completed.
|
confirming: Waiting for e-mail confirmation to be completed.
|
||||||
|
|
Loading…
Reference in a new issue