+// We're choosing to wrap span with div to keep the changes local only to this tool bar.
+const WrapFormattedMessage = ({ children, ...props }) =>
{children}
;
+WrapFormattedMessage.propTypes = {
+ children: PropTypes.any,
+};
+
+
export default @connect(mapStateToProps)
@injectIntl
class Explore extends React.PureComponent {
@@ -47,7 +57,7 @@ class Explore extends React.PureComponent {
this.column = c;
}
- render () {
+ render() {
const { intl, multiColumn, isSearching } = this.props;
const { signedIn } = this.context.identity;
@@ -70,10 +80,10 @@ class Explore extends React.PureComponent {
) : (
-
-
-
- {signedIn && }
+
+
+
+ {signedIn && }
diff --git a/app/javascript/mastodon/features/ui/components/header.js b/app/javascript/mastodon/features/ui/components/header.js
index 4e109080ee7..bbb0ca1c624 100644
--- a/app/javascript/mastodon/features/ui/components/header.js
+++ b/app/javascript/mastodon/features/ui/components/header.js
@@ -35,7 +35,7 @@ class Header extends React.PureComponent {
if (signedIn) {
content = (
<>
- {location.pathname !== '/publish' && }
+ {location.pathname !== '/publish' && }
>
);
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index f7ea661d7d2..2b99ac502be 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -3989,7 +3989,7 @@
"descriptors": [
{
"defaultMessage": "Publish",
- "id": "compose_form.publish"
+ "id": "compose_form.publish_form"
},
{
"defaultMessage": "Sign in",
diff --git a/app/models/form/account_batch.rb b/app/models/form/account_batch.rb
index 5cfcf7205b0..473622edf4d 100644
--- a/app/models/form/account_batch.rb
+++ b/app/models/form/account_batch.rb
@@ -115,6 +115,10 @@ class Form::AccountBatch
authorize(account, :suspend?)
log_action(:suspend, account)
account.suspend!(origin: :local)
+ account.strikes.create!(
+ account: current_account,
+ action: :suspend
+ )
Admin::SuspensionWorker.perform_async(account.id)
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 0e8a87aea5a..0eb975dec7e 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -237,6 +237,11 @@ class User < ApplicationRecord
end
def functional?
+
+ functional_or_moved?
+ end
+
+ def functional_or_moved?
confirmed? && approved? && !disabled? && !account.suspended? && !account.memorial?
end
diff --git a/app/policies/email_domain_block_policy.rb b/app/policies/email_domain_block_policy.rb
index 1a0ddfa8777..0d167ea3e7d 100644
--- a/app/policies/email_domain_block_policy.rb
+++ b/app/policies/email_domain_block_policy.rb
@@ -5,6 +5,10 @@ class EmailDomainBlockPolicy < ApplicationPolicy
role.can?(:manage_blocks)
end
+ def show?
+ role.can?(:manage_blocks)
+ end
+
def create?
role.can?(:manage_blocks)
end
diff --git a/app/serializers/manifest_serializer.rb b/app/serializers/manifest_serializer.rb
index 5604325be41..48f3aa7a6a3 100644
--- a/app/serializers/manifest_serializer.rb
+++ b/app/serializers/manifest_serializer.rb
@@ -35,6 +35,7 @@ class ManifestSerializer < ActiveModel::Serializer
src: full_pack_url("media/icons/android-chrome-#{size}x#{size}.png"),
sizes: "#{size}x#{size}",
type: 'image/png',
+ purpose: 'any maskable',
}
end
end
diff --git a/app/services/verify_link_service.rb b/app/services/verify_link_service.rb
index 0a39d7f26ef..7496fe2d512 100644
--- a/app/services/verify_link_service.rb
+++ b/app/services/verify_link_service.rb
@@ -28,7 +28,7 @@ class VerifyLinkService < BaseService
links = Nokogiri::HTML(@body).xpath('//a[contains(concat(" ", normalize-space(@rel), " "), " me ")]|//link[contains(concat(" ", normalize-space(@rel), " "), " me ")]')
- if links.any? { |link| link['href'].downcase == @link_back.downcase }
+ if links.any? { |link| link['href']&.downcase == @link_back.downcase }
true
elsif links.empty?
false
@@ -38,6 +38,8 @@ class VerifyLinkService < BaseService
end
def link_redirects_back?(test_url)
+ return false if test_url.blank?
+
redirect_to_url = Request.new(:head, test_url, follow: false).perform do |res|
res.headers['Location']
end
diff --git a/app/views/application/_card.html.haml b/app/views/application/_card.html.haml
index 909d9ff818c..3d0e6b1dad6 100644
--- a/app/views/application/_card.html.haml
+++ b/app/views/application/_card.html.haml
@@ -13,4 +13,4 @@
%strong.emojify.p-name= display_name(account, custom_emojify: true)
%span
= acct(account)
- = fa_icon('lock', { :data => ({hidden: true} unless account.locked?)})
+ = fa_icon('lock', { data: ({hidden: true} unless account.locked?)})
diff --git a/app/views/auth/challenges/new.html.haml b/app/views/auth/challenges/new.html.haml
index ff4b7a506fc..4f21e4af6e7 100644
--- a/app/views/auth/challenges/new.html.haml
+++ b/app/views/auth/challenges/new.html.haml
@@ -5,7 +5,7 @@
= f.input :return_to, as: :hidden
.field-group
- = f.input :current_password, wrapper: :with_block_label, input_html: { :autocomplete => 'current-password', :autofocus => true }, label: t('challenge.prompt'), required: true
+ = f.input :current_password, wrapper: :with_block_label, input_html: { autocomplete: 'current-password', autofocus: true }, label: t('challenge.prompt'), required: true
.actions
= f.button :button, t('challenge.confirm'), type: :submit
diff --git a/app/views/auth/confirmations/new.html.haml b/app/views/auth/confirmations/new.html.haml
index 4a1bedaa423..a294d3cb5f8 100644
--- a/app/views/auth/confirmations/new.html.haml
+++ b/app/views/auth/confirmations/new.html.haml
@@ -5,7 +5,7 @@
= render 'shared/error_messages', object: resource
.fields-group
- = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, hint: false
+ = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, hint: false
.actions
= f.button :button, t('auth.resend_confirmation'), type: :submit
diff --git a/app/views/auth/passwords/edit.html.haml b/app/views/auth/passwords/edit.html.haml
index c7dbebe7565..b95a9b676bf 100644
--- a/app/views/auth/passwords/edit.html.haml
+++ b/app/views/auth/passwords/edit.html.haml
@@ -8,9 +8,9 @@
= f.input :reset_password_token, as: :hidden
.fields-group
- = f.input :password, wrapper: :with_label, autofocus: true, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'new-password', :minlength => User.password_length.first, :maxlength => User.password_length.last }, required: true
+ = f.input :password, wrapper: :with_label, autofocus: true, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, required: true
.fields-group
- = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'new-password' }, required: true
+ = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' }, required: true
.actions
= f.button :button, t('auth.set_new_password'), type: :submit
diff --git a/app/views/auth/passwords/new.html.haml b/app/views/auth/passwords/new.html.haml
index bae5b24ba8f..10ad108eafa 100644
--- a/app/views/auth/passwords/new.html.haml
+++ b/app/views/auth/passwords/new.html.haml
@@ -5,7 +5,7 @@
= render 'shared/error_messages', object: resource
.fields-group
- = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, hint: false
+ = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, hint: false
.actions
= f.button :button, t('auth.reset_password'), type: :submit
diff --git a/app/views/auth/registrations/_sessions.html.haml b/app/views/auth/registrations/_sessions.html.haml
index 5d993f574a9..c094dfd2557 100644
--- a/app/views/auth/registrations/_sessions.html.haml
+++ b/app/views/auth/registrations/_sessions.html.haml
@@ -18,7 +18,7 @@
%tr
%td
%span{ title: session.user_agent }<
- = fa_icon "#{session_device_icon(session)} fw", 'aria-label' => session_device_icon(session)
+ = fa_icon "#{session_device_icon(session)} fw", 'aria-label': session_device_icon(session)
= ' '
= t 'sessions.description', browser: t("sessions.browsers.#{session.browser}", default: "#{session.browser}"), platform: t("sessions.platforms.#{session.platform}", default: "#{session.platform}")
%td
diff --git a/app/views/auth/registrations/edit.html.haml b/app/views/auth/registrations/edit.html.haml
index c642c2293b9..60fd1635ef2 100644
--- a/app/views/auth/registrations/edit.html.haml
+++ b/app/views/auth/registrations/edit.html.haml
@@ -11,15 +11,15 @@
- if !use_seamless_external_login? || resource.encrypted_password.present?
.fields-row
.fields-row__column.fields-group.fields-row__column-6
- = f.input :email, wrapper: :with_label, input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, required: true, disabled: current_account.suspended?
+ = f.input :email, wrapper: :with_label, input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, required: true, disabled: current_account.suspended?
.fields-row__column.fields-group.fields-row__column-6
- = f.input :current_password, wrapper: :with_label, input_html: { 'aria-label' => t('simple_form.labels.defaults.current_password'), :autocomplete => 'current-password' }, required: true, disabled: current_account.suspended?, hint: false
+ = f.input :current_password, wrapper: :with_label, input_html: { 'aria-label': t('simple_form.labels.defaults.current_password'), autocomplete: 'current-password' }, required: true, disabled: current_account.suspended?, hint: false
.fields-row
.fields-row__column.fields-group.fields-row__column-6
- = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'new-password', :minlength => User.password_length.first, :maxlength => User.password_length.last }, hint: t('simple_form.hints.defaults.password'), disabled: current_account.suspended?
+ = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, hint: t('simple_form.hints.defaults.password'), disabled: current_account.suspended?
.fields-row__column.fields-group.fields-row__column-6
- = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'new-password' }, disabled: current_account.suspended?
+ = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' }, disabled: current_account.suspended?
.actions
= f.button :button, t('generic.save_changes'), type: :submit, class: 'button', disabled: current_account.suspended?
diff --git a/app/views/auth/registrations/new.html.haml b/app/views/auth/registrations/new.html.haml
index b1d52dd0c23..0d8fd800f96 100644
--- a/app/views/auth/registrations/new.html.haml
+++ b/app/views/auth/registrations/new.html.haml
@@ -17,13 +17,13 @@
.fields-group
= f.simple_fields_for :account do |ff|
- = 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, 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 => 'username' }, hint: false
- = 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 :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
- = 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' }
+ = 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, 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: 'username' }, hint: false
+ = 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 :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
+ = 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?
.fields-group
diff --git a/app/views/auth/sessions/new.html.haml b/app/views/auth/sessions/new.html.haml
index 943618e3902..304e3ab8490 100644
--- a/app/views/auth/sessions/new.html.haml
+++ b/app/views/auth/sessions/new.html.haml
@@ -8,11 +8,11 @@
= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
.fields-group
- if use_seamless_external_login?
- = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.username_or_email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.username_or_email') }, hint: false
+ = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.username_or_email'), input_html: { 'aria-label': t('simple_form.labels.defaults.username_or_email') }, hint: false
- else
- = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, hint: false
+ = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, hint: false
.fields-group
- = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'current-password' }, hint: false
+ = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.password'), input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'current-password' }, hint: false
.actions
= f.button :button, t('auth.login'), type: :submit
diff --git a/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml b/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml
index 82f95752750..094b502b177 100644
--- a/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml
+++ b/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml
@@ -5,7 +5,7 @@
%p.hint.authentication-hint= t('simple_form.hints.sessions.otp')
.fields-group
- = f.input :otp_attempt, type: :number, wrapper: :with_label, label: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label' => t('simple_form.labels.defaults.otp_attempt'), :autocomplete => 'one-time-code' }, autofocus: true
+ = f.input :otp_attempt, type: :number, wrapper: :with_label, label: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label': t('simple_form.labels.defaults.otp_attempt'), autocomplete: 'one-time-code' }, autofocus: true
.actions
= f.button :button, t('auth.login'), type: :submit
diff --git a/app/views/auth/setup/show.html.haml b/app/views/auth/setup/show.html.haml
index c14fed56f8b..1a6611ceb68 100644
--- a/app/views/auth/setup/show.html.haml
+++ b/app/views/auth/setup/show.html.haml
@@ -9,7 +9,7 @@
%p.hint= t('auth.setup.email_below_hint_html')
.fields-group
- = f.input :email, required: true, hint: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.email'), :autocomplete => 'off' }
+ = f.input :email, required: true, hint: false, input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'off' }
.actions
= f.submit t('admin.accounts.change_email.label'), class: 'button'
diff --git a/app/views/settings/deletes/show.html.haml b/app/views/settings/deletes/show.html.haml
index c08ee85b0b3..2e9785c8989 100644
--- a/app/views/settings/deletes/show.html.haml
+++ b/app/views/settings/deletes/show.html.haml
@@ -21,9 +21,9 @@
%hr.spacer/
- if current_user.encrypted_password.present?
- = f.input :password, wrapper: :with_block_label, input_html: { :autocomplete => 'current-password' }, hint: t('deletes.confirm_password')
+ = f.input :password, wrapper: :with_block_label, input_html: { autocomplete: 'current-password' }, hint: t('deletes.confirm_password')
- else
- = f.input :username, wrapper: :with_block_label, input_html: { :autocomplete => 'off' }, hint: t('deletes.confirm_username')
+ = f.input :username, wrapper: :with_block_label, input_html: { autocomplete: 'off' }, hint: t('deletes.confirm_username')
.actions
= f.button :button, t('deletes.proceed'), type: :submit, class: 'negative'
diff --git a/app/views/settings/migration/redirects/new.html.haml b/app/views/settings/migration/redirects/new.html.haml
index d7868e900d3..37008787997 100644
--- a/app/views/settings/migration/redirects/new.html.haml
+++ b/app/views/settings/migration/redirects/new.html.haml
@@ -19,9 +19,9 @@
.fields-row__column.fields-group.fields-row__column-6
- if current_user.encrypted_password.present?
- = f.input :current_password, wrapper: :with_block_label, input_html: { :autocomplete => 'current-password' }, required: true
+ = f.input :current_password, wrapper: :with_block_label, input_html: { autocomplete: 'current-password' }, required: true
- else
- = f.input :current_username, wrapper: :with_block_label, input_html: { :autocomplete => 'off' }, required: true
+ = f.input :current_username, wrapper: :with_block_label, input_html: { autocomplete: 'off' }, required: true
.actions
= f.button :button, t('migrations.set_redirect'), type: :submit, class: 'button button--destructive'
diff --git a/app/views/settings/migrations/show.html.haml b/app/views/settings/migrations/show.html.haml
index 1ecf7302a9f..31f7d5e58d7 100644
--- a/app/views/settings/migrations/show.html.haml
+++ b/app/views/settings/migrations/show.html.haml
@@ -48,9 +48,9 @@
.fields-row__column.fields-group.fields-row__column-6
- if current_user.encrypted_password.present?
- = f.input :current_password, wrapper: :with_block_label, input_html: { :autocomplete => 'current-password' }, required: true, disabled: on_cooldown?
+ = f.input :current_password, wrapper: :with_block_label, input_html: { autocomplete: 'current-password' }, required: true, disabled: on_cooldown?
- else
- = f.input :current_username, wrapper: :with_block_label, input_html: { :autocomplete => 'off' }, required: true, disabled: on_cooldown?
+ = f.input :current_username, wrapper: :with_block_label, input_html: { autocomplete: 'off' }, required: true, disabled: on_cooldown?
.actions
= f.button :button, t('migrations.proceed_with_move'), type: :submit, class: 'button button--destructive', disabled: on_cooldown?
diff --git a/app/views/settings/two_factor_authentication/confirmations/new.html.haml b/app/views/settings/two_factor_authentication/confirmations/new.html.haml
index 671237db573..43830ac27fb 100644
--- a/app/views/settings/two_factor_authentication/confirmations/new.html.haml
+++ b/app/views/settings/two_factor_authentication/confirmations/new.html.haml
@@ -12,7 +12,7 @@
%samp.qr-alternative__code= @new_otp_secret.scan(/.{4}/).join(' ')
.fields-group
- = f.input :otp_attempt, wrapper: :with_label, hint: t('otp_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }, required: true
+ = f.input :otp_attempt, wrapper: :with_label, hint: t('otp_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { autocomplete: 'off' }, required: true
.actions
= f.button :button, t('otp_authentication.enable'), type: :submit
diff --git a/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml b/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml
index c5a323ee50b..5ec0247577d 100644
--- a/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml
+++ b/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml
@@ -8,7 +8,7 @@
%p.hint= t('webauthn_credentials.description_html')
.fields_group
- = f.input :nickname, wrapper: :with_block_label, hint: t('webauthn_credentials.nickname_hint'), input_html: { :autocomplete => 'off' }, required: true
+ = f.input :nickname, wrapper: :with_block_label, hint: t('webauthn_credentials.nickname_hint'), input_html: { autocomplete: 'off' }, required: true
.actions
= f.button :button, t('webauthn_credentials.add'), class: 'js-webauthn', type: :submit
diff --git a/app/views/statuses/_detailed_status.html.haml b/app/views/statuses/_detailed_status.html.haml
index 619406d8976..bf498e33d54 100644
--- a/app/views/statuses/_detailed_status.html.haml
+++ b/app/views/statuses/_detailed_status.html.haml
@@ -15,12 +15,12 @@
= account_action_button(status.account)
- .status__content.emojify{ :data => ({ spoiler: current_account&.user&.setting_expand_spoilers ? 'expanded' : 'folded' } if status.spoiler_text?) }<
+ .status__content.emojify{ data: ({ spoiler: current_account&.user&.setting_expand_spoilers ? 'expanded' : 'folded' } if status.spoiler_text?) }<
- if status.spoiler_text?
%p<
%span.p-summary> #{prerender_custom_emojis(h(status.spoiler_text), status.emojis)}
%button.status__content__spoiler-link= t('statuses.show_more')
- .e-content{ :lang => status.language }
+ .e-content{ lang: status.language }
= prerender_custom_emojis(status_content_format(status), status.emojis)
- if status.preloadable_poll
diff --git a/app/views/statuses/_simple_status.html.haml b/app/views/statuses/_simple_status.html.haml
index 1e37b6cf3aa..ecbabf34cf6 100644
--- a/app/views/statuses/_simple_status.html.haml
+++ b/app/views/statuses/_simple_status.html.haml
@@ -27,12 +27,12 @@
%span.display-name__account
= acct(status.account)
= fa_icon('lock') if status.account.locked?
- .status__content.emojify{ :data => ({ spoiler: current_account&.user&.setting_expand_spoilers ? 'expanded' : 'folded' } if status.spoiler_text?) }<
+ .status__content.emojify{ data: ({ spoiler: current_account&.user&.setting_expand_spoilers ? 'expanded' : 'folded' } if status.spoiler_text?) }<
- if status.spoiler_text?
%p<
%span.p-summary> #{prerender_custom_emojis(h(status.spoiler_text), status.emojis)}
%button.status__content__spoiler-link= t('statuses.show_more')
- .e-content{ :lang => status.language }<
+ .e-content{ lang: status.language }<
= prerender_custom_emojis(status_content_format(status), status.emojis)
- if status.preloadable_poll
diff --git a/chart/Chart.yaml b/chart/Chart.yaml
index 7080095f2de..8d67e55ebe4 100644
--- a/chart/Chart.yaml
+++ b/chart/Chart.yaml
@@ -15,12 +15,12 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
-version: 2.3.0
+version: 3.0.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
-appVersion: v3.5.3
+appVersion: v4.0.2
dependencies:
- name: elasticsearch
diff --git a/config/environments/production.rb b/config/environments/production.rb
index c50ece2f996..8e2f0cc7fc7 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -116,18 +116,18 @@ Rails.application.configure do
end
config.action_mailer.smtp_settings = {
- :port => ENV['SMTP_PORT'],
- :address => ENV['SMTP_SERVER'],
- :user_name => ENV['SMTP_LOGIN'].presence,
- :password => ENV['SMTP_PASSWORD'].presence,
- :domain => ENV['SMTP_DOMAIN'] || ENV['LOCAL_DOMAIN'],
- :authentication => ENV['SMTP_AUTH_METHOD'] == 'none' ? nil : ENV['SMTP_AUTH_METHOD'] || :plain,
- :ca_file => ENV['SMTP_CA_FILE'].presence || '/etc/ssl/certs/ca-certificates.crt',
- :openssl_verify_mode => ENV['SMTP_OPENSSL_VERIFY_MODE'],
- :enable_starttls => enable_starttls,
- :enable_starttls_auto => enable_starttls_auto,
- :tls => ENV['SMTP_TLS'].presence && ENV['SMTP_TLS'] == 'true',
- :ssl => ENV['SMTP_SSL'].presence && ENV['SMTP_SSL'] == 'true',
+ port: ENV['SMTP_PORT'],
+ address: ENV['SMTP_SERVER'],
+ user_name: ENV['SMTP_LOGIN'].presence,
+ password: ENV['SMTP_PASSWORD'].presence,
+ domain: ENV['SMTP_DOMAIN'] || ENV['LOCAL_DOMAIN'],
+ authentication: ENV['SMTP_AUTH_METHOD'] == 'none' ? nil : ENV['SMTP_AUTH_METHOD'] || :plain,
+ ca_file: ENV['SMTP_CA_FILE'].presence || '/etc/ssl/certs/ca-certificates.crt',
+ openssl_verify_mode: ENV['SMTP_OPENSSL_VERIFY_MODE'],
+ enable_starttls: enable_starttls,
+ enable_starttls_auto: enable_starttls_auto,
+ tls: ENV['SMTP_TLS'].presence && ENV['SMTP_TLS'] == 'true',
+ ssl: ENV['SMTP_SSL'].presence && ENV['SMTP_SSL'] == 'true',
}
config.action_mailer.delivery_method = ENV.fetch('SMTP_DELIVERY_METHOD', 'smtp').to_sym
diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb
index 84b649f5c10..43aac5769f1 100644
--- a/config/initializers/doorkeeper.rb
+++ b/config/initializers/doorkeeper.rb
@@ -98,9 +98,19 @@ Doorkeeper.configure do
:'admin:read',
:'admin:read:accounts',
:'admin:read:reports',
+ :'admin:read:domain_allows',
+ :'admin:read:domain_blocks',
+ :'admin:read:ip_blocks',
+ :'admin:read:email_domain_blocks',
+ :'admin:read:canonical_email_blocks',
:'admin:write',
:'admin:write:accounts',
:'admin:write:reports',
+ :'admin:write:domain_allows',
+ :'admin:write:domain_blocks',
+ :'admin:write:ip_blocks',
+ :'admin:write:email_domain_blocks',
+ :'admin:write:canonical_email_blocks',
:crypto
# Change the way client credentials are retrieved from the request object.
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 2f766cef38c..1cc53dca4be 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -373,6 +373,8 @@ en:
add_new: Allow federation with domain
created_msg: Domain has been successfully allowed for federation
destroyed_msg: Domain has been disallowed from federation
+ export: Export
+ import: Import
undo: Disallow federation with domain
domain_blocks:
add_new: Add new domain block
@@ -382,15 +384,19 @@ en:
edit: Edit domain block
existing_domain_block: You have already imposed stricter limits on %{name}.
existing_domain_block_html: You have already imposed stricter limits on %{name}, you need to unblock it first.
+ export: Export
+ import: Import
new:
create: Create block
hint: The domain block will not prevent creation of account entries in the database, but will retroactively and automatically apply specific moderation methods on those accounts.
severity:
- desc_html: "Silence will make the account's posts invisible to anyone who isn't following them. Suspend will remove all of the account's content, media, and profile data. Use None if you just want to reject media files."
+ desc_html: "Limit will make posts from accounts at this domain invisible to anyone who isn't following them. Suspend will remove all content, media, and profile data for this domain's accounts from your server. Use None if you just want to reject media files."
noop: None
- silence: Silence
+ silence: Limit
suspend: Suspend
title: New domain block
+ no_domain_block_selected: No domain blocks were changed as none were selected
+ not_permitted: You are not permitted to perform this action
obfuscate: Obfuscate domain name
obfuscate_hint: Partially obfuscate the domain name in the list if advertising the list of domain limitations is enabled
private_comment: Private comment
@@ -422,6 +428,20 @@ en:
resolved_dns_records_hint_html: The domain name resolves to the following MX domains, which are ultimately responsible for accepting e-mail. Blocking an MX domain will block sign-ups from any e-mail address which uses the same MX domain, even if the visible domain name is different. Be careful not to block major e-mail providers.
resolved_through_html: Resolved through %{domain}
title: Blocked e-mail domains
+ export_domain_allows:
+ new:
+ title: Import domain allows
+ no_file: No file selected
+ export_domain_blocks:
+ import:
+ description_html: You are about to import a list of domain blocks. Please review this list very carefully, especially if you have not authored this list yourself.
+ existing_relationships_warning: Existing follow relationships
+ private_comment_description_html: 'To help you track where imported blocks come from, imported blocks will be created with the following private comment: %{comment}
'
+ private_comment_template: Imported from %{source} on %{date}
+ title: Import domain blocks
+ new:
+ title: Import domain blocks
+ no_file: No file selected
follow_recommendations:
description_html: "Follow recommendations help new users quickly find interesting content. When a user has not interacted with others enough to form personalized follow recommendations, these accounts are recommended instead. They are re-calculated on a daily basis from a mix of accounts with the highest recent engagements and highest local follower counts for a given language."
language: For language
@@ -914,7 +934,7 @@ en:
warning: Be very careful with this data. Never share it with anyone!
your_token: Your access token
auth:
- apply_for_account: Get on waitlist
+ apply_for_account: Request an account
change_password: Password
delete_account: Delete account
delete_account_html: If you wish to delete your account, you can proceed here. You will be asked for confirmation.
diff --git a/config/navigation.rb b/config/navigation.rb
index 4d2da7aa47a..aab72d27c49 100644
--- a/config/navigation.rb
+++ b/config/navigation.rb
@@ -23,7 +23,7 @@ SimpleNavigation::Configuration.run do |navigation|
n.item :relationships, safe_join([fa_icon('users fw'), t('settings.relationships')]), relationships_path, if: -> { current_user.functional? }
n.item :filters, safe_join([fa_icon('filter fw'), t('filters.index.title')]), filters_path, highlights_on: %r{/filters}, if: -> { current_user.functional? }
- n.item :statuses_cleanup, safe_join([fa_icon('history fw'), t('settings.statuses_cleanup')]), statuses_cleanup_path, if: -> { current_user.functional? }
+ n.item :statuses_cleanup, safe_join([fa_icon('history fw'), t('settings.statuses_cleanup')]), statuses_cleanup_path, if: -> { current_user.functional_or_moved? }
n.item :security, safe_join([fa_icon('lock fw'), t('settings.account')]), edit_user_registration_path do |s|
s.item :password, safe_join([fa_icon('lock fw'), t('settings.account_settings')]), edit_user_registration_path, highlights_on: %r{/auth/edit|/settings/delete|/settings/migration|/settings/aliases|/settings/login_activities|^/disputes}
diff --git a/spec/controllers/admin/statuses_controller_spec.rb b/spec/controllers/admin/statuses_controller_spec.rb
index 227688e2364..7f912c1c07b 100644
--- a/spec/controllers/admin/statuses_controller_spec.rb
+++ b/spec/controllers/admin/statuses_controller_spec.rb
@@ -41,7 +41,7 @@ describe Admin::StatusesController do
describe 'POST #batch' do
before do
- post :batch, params: { :account_id => account.id, action => '', :admin_status_batch_action => { status_ids: status_ids } }
+ post :batch, params: { account_id: account.id, action => '', admin_status_batch_action: { status_ids: status_ids } }
end
let(:status_ids) { [media_attached_status.id] }
diff --git a/spec/services/favourite_service_spec.rb b/spec/services/favourite_service_spec.rb
index 94a8111dd5c..9781f0d78b6 100644
--- a/spec/services/favourite_service_spec.rb
+++ b/spec/services/favourite_service_spec.rb
@@ -23,7 +23,7 @@ RSpec.describe FavouriteService, type: :service do
let(:status) { Fabricate(:status, account: bob) }
before do
- stub_request(:post, "http://example.com/inbox").to_return(:status => 200, :body => "", :headers => {})
+ stub_request(:post, "http://example.com/inbox").to_return(status: 200, body: "", headers: {})
subject.call(sender, status)
end
diff --git a/spec/services/follow_service_spec.rb b/spec/services/follow_service_spec.rb
index 88346ec54af..412c04d76b2 100644
--- a/spec/services/follow_service_spec.rb
+++ b/spec/services/follow_service_spec.rb
@@ -140,7 +140,7 @@ RSpec.describe FollowService, type: :service do
let(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox') }
before do
- stub_request(:post, "http://example.com/inbox").to_return(:status => 200, :body => "", :headers => {})
+ stub_request(:post, "http://example.com/inbox").to_return(status: 200, body: "", headers: {})
subject.call(sender, bob)
end
diff --git a/spec/services/verify_link_service_spec.rb b/spec/services/verify_link_service_spec.rb
index 3fc88e60e4b..52ba454cce3 100644
--- a/spec/services/verify_link_service_spec.rb
+++ b/spec/services/verify_link_service_spec.rb
@@ -76,7 +76,25 @@ RSpec.describe VerifyLinkService, type: :service do
context 'when a link does not contain a link back' do
let(:html) { '' }
- it 'marks the field as verified' do
+ it 'does not mark the field as verified' do
+ expect(field.verified?).to be false
+ end
+ end
+
+ context 'when link has no `href` attribute' do
+ let(:html) do
+ <<-HTML
+
+
+
+
+
+ Follow me on Mastodon
+
+ HTML
+ end
+
+ it 'does not mark the field as verified' do
expect(field.verified?).to be false
end
end
diff --git a/spec/views/statuses/show.html.haml_spec.rb b/spec/views/statuses/show.html.haml_spec.rb
index eeea2f6985a..ca5bb2ae873 100644
--- a/spec/views/statuses/show.html.haml_spec.rb
+++ b/spec/views/statuses/show.html.haml_spec.rb
@@ -4,7 +4,7 @@ require 'rails_helper'
describe 'statuses/show.html.haml', without_verify_partial_doubles: true do
before do
- double(:api_oembed_url => '')
+ double(api_oembed_url: '')
allow(view).to receive(:show_landing_strip?).and_return(true)
allow(view).to receive(:site_title).and_return('example site')
allow(view).to receive(:site_hostname).and_return('example.com')