From 3b06175e8f5cb9d688e8ec376dbfd88abf5f3278 Mon Sep 17 00:00:00 2001 From: multiple creatures Date: Fri, 10 May 2019 03:48:11 -0500 Subject: Moderation: add `force sensitive` and `force unlisted` actions. Accounts: add federatable `adult content` tag. Handle from remote accounts as well. --- app/controllers/admin/accounts_controller.rb | 30 +++++++- app/controllers/admin/domain_blocks_controller.rb | 2 +- app/controllers/settings/profiles_controller.rb | 2 +- app/helpers/admin/action_logs_helper.rb | 6 +- app/helpers/stream_entries_helper.rb | 1 + .../glitch/features/account/components/header.js | 7 +- app/javascript/mastodon/locales/en.json | 1 + app/lib/activitypub/activity/create.rb | 3 + app/lib/activitypub/adapter.rb | 1 + app/models/account.rb | 26 +++++++ app/models/account_warning.rb | 2 +- app/models/admin/account_action.rb | 18 +++++ app/models/domain_block.rb | 26 ++++--- app/models/status.rb | 5 -- app/models/user.rb | 4 ++ app/policies/account_policy.rb | 16 +++++ app/serializers/activitypub/actor_serializer.rb | 12 +++- app/serializers/rest/account_serializer.rb | 3 +- .../activitypub/process_account_service.rb | 21 ++++-- app/services/block_domain_service.rb | 24 ++++++- app/services/post_status_service.rb | 7 +- app/services/unblock_domain_service.rb | 9 ++- app/views/admin/accounts/show.html.haml | 79 ++++++++++++---------- app/views/admin/domain_blocks/new.html.haml | 3 + app/views/settings/profiles/show.html.haml | 3 + 25 files changed, 239 insertions(+), 72 deletions(-) (limited to 'app') diff --git a/app/controllers/admin/accounts_controller.rb b/app/controllers/admin/accounts_controller.rb index 86bc3c8a2..d486a97ba 100644 --- a/app/controllers/admin/accounts_controller.rb +++ b/app/controllers/admin/accounts_controller.rb @@ -2,7 +2,7 @@ module Admin class AccountsController < BaseController - before_action :set_account, only: [:show, :redownload, :remove_avatar, :remove_header, :enable, :unsilence, :unsuspend, :memorialize, :approve, :reject] + before_action :set_account, only: [:show, :redownload, :remove_avatar, :remove_header, :enable, :allow_public, :allow_nonsensitive, :unsilence, :unsuspend, :memorialize, :approve, :reject] before_action :require_remote_account!, only: [:redownload] before_action :require_local_account!, only: [:enable, :memorialize, :approve, :reject] @@ -45,6 +45,34 @@ module Admin redirect_to admin_accounts_path(pending: '1') end + def force_sensitive + authorize @account, :force_sensitive? + @account.force_sensitive! + log_action :force_sensitive, @account + redirect_to admin_account_path(@account.id) + end + + def allow_nonsensitive + authorize @account, :allow_nonsensitive? + @account.allow_nonsensitive! + log_action :allow_nonsensitive, @account + redirect_to admin_account_path(@account.id) + end + + def force_unlisted + authorize @account, :force_unlisted? + @account.force_unlisted! + log_action :force_unlisted, @account + redirect_to admin_account_path(@account.id) + end + + def allow_public + authorize @account, :allow_public? + @account.allow_public! + log_action :allow_public, @account + redirect_to admin_account_path(@account.id) + end + def unsilence authorize @account, :unsilence? @account.unsilence! diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb index 71597763b..47c2daa7a 100644 --- a/app/controllers/admin/domain_blocks_controller.rb +++ b/app/controllers/admin/domain_blocks_controller.rb @@ -53,7 +53,7 @@ module Admin end def resource_params - params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports) + params.require(:domain_block).permit(:domain, :severity, :force_sensitive, :reject_media, :reject_reports) end end end diff --git a/app/controllers/settings/profiles_controller.rb b/app/controllers/settings/profiles_controller.rb index ac6635aea..e30079a0f 100644 --- a/app/controllers/settings/profiles_controller.rb +++ b/app/controllers/settings/profiles_controller.rb @@ -25,7 +25,7 @@ class Settings::ProfilesController < Settings::BaseController private def account_params - params.require(:account).permit(:display_name, :note, :avatar, :header, :replies, :locked, :hidden, :unlisted, :bot, :discoverable, fields_attributes: [:name, :value]) + params.require(:account).permit(:display_name, :note, :avatar, :header, :replies, :locked, :hidden, :unlisted, :adults_only, :bot, :discoverable, fields_attributes: [:name, :value]) end def set_account diff --git a/app/helpers/admin/action_logs_helper.rb b/app/helpers/admin/action_logs_helper.rb index e5fbb1500..93ce447a1 100644 --- a/app/helpers/admin/action_logs_helper.rb +++ b/app/helpers/admin/action_logs_helper.rb @@ -19,7 +19,7 @@ module Admin::ActionLogsHelper elsif log.target_type == 'User' && [:change_email].include?(log.action) log.recorded_changes.slice('email', 'unconfirmed_email') elsif log.target_type == 'DomainBlock' - log.recorded_changes.slice('severity', 'reject_media') + log.recorded_changes.slice('severity', 'reject_media', 'force_sensitive') elsif log.target_type == 'Status' && log.action == :update log.recorded_changes.slice('sensitive') end @@ -55,13 +55,13 @@ module Admin::ActionLogsHelper def class_for_log_icon(log) case log.action - when :enable, :unsuspend, :unsilence, :confirm, :promote, :resolve + when :enable, :allow_public, :allow_nonsensitive, :unsuspend, :unsilence, :confirm, :promote, :resolve 'positive' when :create opposite_verbs?(log) ? 'negative' : 'positive' when :update, :reset_password, :disable_2fa, :memorialize, :change_email 'neutral' - when :demote, :silence, :disable, :suspend, :remove_avatar, :remove_header, :reopen + when :demote, :force_sensitive, :force_unlisted, :silence, :disable, :suspend, :remove_avatar, :remove_header, :reopen 'negative' when :destroy opposite_verbs?(log) ? 'positive' : 'negative' diff --git a/app/helpers/stream_entries_helper.rb b/app/helpers/stream_entries_helper.rb index f3848f3be..8757518b4 100644 --- a/app/helpers/stream_entries_helper.rb +++ b/app/helpers/stream_entries_helper.rb @@ -38,6 +38,7 @@ module StreamEntriesHelper content_tag(:div, class: 'roles') do roles = [] roles << content_tag(:div, t('accounts.roles.bot'), class: 'account-role bot') if account.bot? + roles << content_tag(:div, t('accounts.roles.adults_only'), class: 'account-role adults-only') if account.adults_only? roles << content_tag(:div, t('accounts.roles.gentlies_kobolds'), class: 'account-role gentlies') if account&.user&.setting_gently_kobolds roles << content_tag(:div, t('accounts.roles.kobold'), class: 'account-role kobold') if account&.user&.setting_user_is_kobold diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js index 43c4f0d32..ef5915382 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.js +++ b/app/javascript/flavours/glitch/features/account/components/header.js @@ -189,7 +189,8 @@ class Header extends ImmutablePureComponent { const content = { __html: account.get('note_emojified') }; const displayNameHtml = { __html: account.get('display_name_html') }; const fields = account.get('fields'); - const badge = account.get('bot') ? (
) : null; + const badge_bot = account.get('bot') ? (
) : null; + const badge_ao = account.get('adults_only') ? (
) : null; const acct = account.get('acct').indexOf('@') === -1 && domain ? `${account.get('acct')}@${domain}` : account.get('acct'); return ( @@ -219,7 +220,7 @@ class Header extends ImmutablePureComponent {

- {badge} + {badge_ao}{badge_bot} @{acct} {lockedIcon}

@@ -243,7 +244,7 @@ class Header extends ImmutablePureComponent { {fields.map((pair, i) => (
- +
{pair.get('verified_at') && }
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index d85322223..d61dc27ad 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -1,6 +1,7 @@ { "account.add_or_remove_from_list": "Add or Remove from lists", "account.badges.bot": "Bot", + "account.badges.adults_only": "🔞 Adult content", "account.block": "Block @{name}", "account.block_domain": "Hide {domain}", "account.blocked": "Blocked", diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 5514d9a6e..f24cfffa8 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -34,6 +34,9 @@ class ActivityPub::Activity::Create < ActivityPub::Activity process_tags process_audience + @params[:visibility] = :unlisted if @params[:visibility] == :public && @account.force_unlisted? + @params[:sensitive] = true if @account.force_sensitive? + ApplicationRecord.transaction do @status = Status.create!(@params) attach_tags(@status) diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb index 9d940e4ef..4c0231ad7 100644 --- a/app/lib/activitypub/adapter.rb +++ b/app/lib/activitypub/adapter.rb @@ -19,6 +19,7 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base focal_point: { 'toot' => 'http://joinmastodon.org/ns#', 'focalPoint' => { '@container' => '@list', '@id' => 'toot:focalPoint' } }, identity_proof: { 'toot' => 'http://joinmastodon.org/ns#', 'IdentityProof' => 'toot:IdentityProof' }, blurhash: { 'toot' => 'http://joinmastodon.org/ns#', 'blurhash' => 'toot:blurhash' }, + adults_only: { 'schema' => 'http://schema.org#', 'suggestedMinAge' => 'schema:suggestedMinAge' } }.freeze def self.default_key_transform diff --git a/app/models/account.rb b/app/models/account.rb index 6e7cf3773..5f88a951f 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -48,6 +48,9 @@ # vars :jsonb not null # replies :boolean default(TRUE), not null # unlisted :boolean default(FALSE), not null +# force_unlisted :boolean default(FALSE), not null +# force_sensitive :boolean default(FALSE), not null +# adults_only :boolean default(FALSE), not null # class Account < ApplicationRecord @@ -120,6 +123,7 @@ class Account < ApplicationRecord :moderator?, :staff?, :locale, + :default_sensitive?, :hides_network?, :shows_application?, :always_local?, @@ -185,6 +189,28 @@ class Account < ApplicationRecord ResolveAccountService.new.call(acct) end + def force_unlisted! + transaction do + update!(force_unlisted: true) + Status.where(account_id: id, visibility: :public).in_batches.update_all(visibility: :unlisted) + end + end + + def force_sensitive! + transaction do + update!(force_sensitive: true) + Status.where(account_id: id, sensitive: false).in_batches.update_all(sensitive: true) + end + end + + def allow_public! + update!(force_unlisted: false) + end + + def allow_nonsensitive! + update!(force_sensitive: false) + end + def silenced? silenced_at.present? end diff --git a/app/models/account_warning.rb b/app/models/account_warning.rb index 157e6c04d..4e06cf3d0 100644 --- a/app/models/account_warning.rb +++ b/app/models/account_warning.rb @@ -13,7 +13,7 @@ # class AccountWarning < ApplicationRecord - enum action: %i(none disable silence suspend), _suffix: :action + enum action: %i(none disable force_sensitive force_unlisted silence suspend), _suffix: :action belongs_to :account, inverse_of: :account_warnings belongs_to :target_account, class_name: 'Account', inverse_of: :targeted_account_warnings diff --git a/app/models/admin/account_action.rb b/app/models/admin/account_action.rb index 84c3f880d..1ed464423 100644 --- a/app/models/admin/account_action.rb +++ b/app/models/admin/account_action.rb @@ -8,6 +8,8 @@ class Admin::AccountAction TYPES = %w( none disable + force_sensitive + force_unlisted silence suspend ).freeze @@ -56,6 +58,10 @@ class Admin::AccountAction case type when 'disable' handle_disable! + when 'force_sensitive' + handle_force_sensitive! + when 'force_unlisted' + handle_force_unlisted! when 'silence' handle_silence! when 'suspend' @@ -97,6 +103,18 @@ class Admin::AccountAction target_account.user&.disable! end + def handle_force_sensitive! + authorize(target_account, :force_sensitive?) + log_action(:force_sensitive, target_account.user) + target_account.force_sensitive! + end + + def handle_force_unlisted! + authorize(target_account, :force_unlisted?) + log_action(:force_unlisted, target_account.user) + target_account.force_unlisted! + end + def handle_silence! authorize(target_account, :silence?) log_action(:silence, target_account) diff --git a/app/models/domain_block.rb b/app/models/domain_block.rb index 84c08c158..c62ca3d8c 100644 --- a/app/models/domain_block.rb +++ b/app/models/domain_block.rb @@ -3,19 +3,20 @@ # # Table name: domain_blocks # -# id :bigint(8) not null, primary key -# domain :string default(""), not null -# created_at :datetime not null -# updated_at :datetime not null -# severity :integer default("silence") -# reject_media :boolean default(FALSE), not null -# reject_reports :boolean default(FALSE), not null +# id :bigint(8) not null, primary key +# domain :string default(""), not null +# created_at :datetime not null +# updated_at :datetime not null +# severity :integer default("noop") +# reject_media :boolean default(FALSE), not null +# reject_reports :boolean default(FALSE), not null +# force_sensitive :boolean default(FALSE), not null # class DomainBlock < ApplicationRecord include DomainNormalizable - enum severity: [:silence, :suspend, :noop] + enum severity: [:noop, :force_unlisted, :silence, :suspend] validates :domain, presence: true, uniqueness: true @@ -28,10 +29,15 @@ class DomainBlock < ApplicationRecord where(domain: domain, severity: :suspend).exists? end + def self.force_unlisted?(domain) + where(domain: domain, severity: :force_unlisted).exists? + end + def stricter_than?(other_block) return true if suspend? - return false if other_block.suspend? && (silence? || noop?) - return false if other_block.silence? && noop? + return false if other_block.suspend? && !suspend? + return false if other_block.silence? && (noop? || force_unlisted?) + return false if other_block.force_unlisted? && noop? (reject_media || !other_block.reject_media) && (reject_reports || !other_block.reject_reports) end diff --git a/app/models/status.rb b/app/models/status.rb index 0b26e4605..3c98369b1 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -40,8 +40,6 @@ class Status < ApplicationRecord # match both with and without U+FE0F (the emoji variation selector) LOCAL_ONLY_TOKENS = /(?:#!|\u{1f441}\ufe0f?)\u200b?\z/ - FORCE_SENSITIVE = ENV.fetch('FORCE_SENSITIVE', '').chomp.split(/\.?\s+/).freeze - FORCE_UNLISTED = ENV.fetch('FORCE_UNLISTED', '').chomp.split(/\.?\s+/).freeze # If `override_timestamps` is set at creation time, Snowflake ID creation # will be based on current time instead of `created_at` @@ -561,9 +559,6 @@ class Status < ApplicationRecord def set_visibility self.visibility = reblog.visibility if reblog? && visibility.nil? self.visibility = (account.locked? ? :private : :public) if visibility.nil? - self.visibility = :unlisted if visibility == :public && account.domain.in?(FORCE_UNLISTED) - self.sensitive = true if account.domain.in?(FORCE_SENSITIVE) - self.sensitive = false if sensitive.nil? end def set_locality diff --git a/app/models/user.rb b/app/models/user.rb index 5d67dc0d9..2bd039958 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -309,6 +309,10 @@ class User < ApplicationRecord @hide_captions ||= (settings.hide_captions || false) end + def default_sensitive? + @default_sensitive ||= settings.default_sensitive + end + def setting_default_privacy settings.default_privacy || 'public' end diff --git a/app/policies/account_policy.rb b/app/policies/account_policy.rb index 9c145979d..f3bda83db 100644 --- a/app/policies/account_policy.rb +++ b/app/policies/account_policy.rb @@ -29,6 +29,22 @@ class AccountPolicy < ApplicationPolicy staff? end + def force_unlisted? + staff? + end + + def allow_public? + staff? + end + + def force_sensitive? + staff? + end + + def allow_nonsensitive? + staff? + end + def redownload? admin? end diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb index 0644219fb..44dbc5ccb 100644 --- a/app/serializers/activitypub/actor_serializer.rb +++ b/app/serializers/activitypub/actor_serializer.rb @@ -6,7 +6,8 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer context :security context_extensions :manually_approves_followers, :featured, :also_known_as, - :moved_to, :property_value, :hashtag, :emoji, :identity_proof + :moved_to, :property_value, :hashtag, :emoji, :identity_proof, + :adults_only attributes :id, :type, :following, :followers, :inbox, :outbox, :featured, @@ -20,6 +21,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer attribute :moved_to, if: :moved? attribute :also_known_as, if: :also_known_as? + attribute :adults_only, if: :adults_only? class EndpointsSerializer < ActivityPub::Serializer include RoutingHelper @@ -66,6 +68,10 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer account_collection_url(object, :featured) end + def adults_only + 18 + end + def endpoints object end @@ -126,6 +132,10 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer !object.also_known_as.empty? end + def adults_only? + object.adults_only + end + class CustomEmojiSerializer < ActivityPub::EmojiSerializer end diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb index 574ccfc85..04df81225 100644 --- a/app/serializers/rest/account_serializer.rb +++ b/app/serializers/rest/account_serializer.rb @@ -5,7 +5,8 @@ class REST::AccountSerializer < ActiveModel::Serializer attributes :id, :username, :acct, :display_name, :locked, :bot, :created_at, :note, :url, :avatar, :avatar_static, :header, :header_static, - :followers_count, :following_count, :statuses_count, :replies + :followers_count, :following_count, :statuses_count, :replies, + :adults_only has_one :moved_to_account, key: :moved, serializer: REST::AccountSerializer, if: :moved_and_not_nested? has_many :emojis, serializer: REST::CustomEmojiSerializer diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index f36ab7d61..ee24718e1 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -48,11 +48,13 @@ class ActivityPub::ProcessAccountService < BaseService def create_account @account = Account.new - @account.username = @username - @account.domain = @domain - @account.private_key = nil - @account.suspended_at = domain_block.created_at if auto_suspend? - @account.silenced_at = domain_block.created_at if auto_silence? + @account.username = @username + @account.domain = @domain + @account.private_key = nil + @account.suspended_at = domain_block.created_at if auto_suspend? + @account.silenced_at = domain_block.created_at if auto_silence? + @account.force_unlisted = true if force_unlisted? + @account.force_sensitive = true if force_sensitive? end def update_account @@ -75,6 +77,7 @@ class ActivityPub::ProcessAccountService < BaseService @account.display_name = @json['name'] || '' @account.note = @json['summary'] || '' @account.locked = @json['manuallyApprovesFollowers'] || false + @account.adults_only = @json['suggestedMinAge'].to_i >= 18 @account.fields = property_values || {} @account.also_known_as = as_array(@json['alsoKnownAs'] || []).map { |item| value_or_id(item) } @account.actor_type = actor_type @@ -195,6 +198,14 @@ class ActivityPub::ProcessAccountService < BaseService domain_block&.silence? end + def auto_force_unlisted? + domain_block&.force_unlisted? + end + + def auto_force_sensitive? + domain_block&.force_sensitive? + end + def domain_block return @domain_block if defined?(@domain_block) @domain_block = DomainBlock.find_by(domain: @domain) diff --git a/app/services/block_domain_service.rb b/app/services/block_domain_service.rb index 497f0394b..154d00427 100644 --- a/app/services/block_domain_service.rb +++ b/app/services/block_domain_service.rb @@ -12,8 +12,11 @@ class BlockDomainService < BaseService def process_domain_block! clear_media! if domain_block.reject_media? + force_accounts_sensitive! if domain_block.force_sensitive? - if domain_block.silence? + if domain_block.force_unlisted? + force_accounts_unlisted! + elsif domain_block.silence? silence_accounts! elsif domain_block.suspend? suspend_accounts! @@ -28,6 +31,24 @@ class BlockDomainService < BaseService @affected_status_ids.each { |id| Rails.cache.delete_matched("statuses/#{id}-*") } end + def force_accounts_sensitive! + ApplicationRecord.transaction do + blocked_domain_accounts.in_batches.update_all(force_sensitive: true) + blocked_domain_accounts.reorder(nil).find_each do |account| + account.statuses.where(sensitive: false).in_batches.update_all(sensitive: true) + end + end + end + + def force_accounts_unlisted! + ApplicationRecord.transaction do + blocked_domain_accounts.in_batches.update_all(force_unlisted: true) + blocked_domain_accounts.reorder(nil).find_each do |account| + account.statuses.with_public_visibility.in_batches.update_all(visibility: :unlisted) + end + end + end + def silence_accounts! blocked_domain_accounts.without_silenced.in_batches.update_all(silenced_at: @domain_block.created_at) end @@ -44,7 +65,6 @@ class BlockDomainService < BaseService def suspend_accounts! blocked_domain_accounts.without_suspended.reorder(nil).find_each do |account| - UnsubscribeService.new.call(account) if account.subscribed? SuspendAccountService.new.call(account, suspended_at: @domain_block.created_at) end end diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index d54f9295e..5a73b541f 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -30,6 +30,7 @@ class PostStatusService < BaseService @in_reply_to = @options[:thread] @tags = @options[:tags] @local_only = @options[:local_only] + @sensitive = (@account.force_sensitive? ? true : @options[:sensitive]) return idempotency_duplicate if idempotency_given? && idempotency_duplicate? @@ -58,7 +59,7 @@ class PostStatusService < BaseService end @visibility = @options[:visibility] || @account.user&.setting_default_privacy - @visibility = :unlisted if @visibility == :public && @account.silenced? + @visibility = :unlisted if @visibility.in?([nil, 'public']) && @account.silenced? || @account.force_unlisted if @in_reply_to.present? && @in_reply_to.visibility.present? v = %w(public unlisted private direct limited) @@ -67,6 +68,8 @@ class PostStatusService < BaseService @local_only = true if @account.user_always_local? || @in_reply_to&.local_only + @sensitive = (@account.default_sensitive? || @options[:spoiler_text].present?) if @sensitive.nil? + @scheduled_at = @options[:scheduled_at]&.to_datetime @scheduled_at = nil if scheduled_in_the_past? rescue ArgumentError @@ -176,7 +179,7 @@ class PostStatusService < BaseService media_attachments: @media || [], thread: @in_reply_to, poll_attributes: poll_attributes, - sensitive: (@options[:sensitive].nil? ? @account.user&.setting_default_sensitive : @options[:sensitive]) || @options[:spoiler_text].present?, + sensitive: @sensitive, spoiler_text: @options[:spoiler_text] || '', visibility: @visibility, local_only: @local_only, diff --git a/app/services/unblock_domain_service.rb b/app/services/unblock_domain_service.rb index 9b8526fbe..d9b96edfe 100644 --- a/app/services/unblock_domain_service.rb +++ b/app/services/unblock_domain_service.rb @@ -27,6 +27,13 @@ class UnblockDomainService < BaseService end def domain_block_impact - domain_block.silence? ? :silenced_at : :suspended_at + case domain_block.severity + when :force_unlisted + :force_unlisted + when :silence + :silenced_at + when :suspend + :suspended_at + end end end diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index 7494c9fa2..0066ed8e7 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -141,42 +141,51 @@ = fa_icon DeliveryFailureTracker.unavailable?(@account.shared_inbox_url) ? 'times' : 'check' %div{ style: 'overflow: hidden' } - %div{ style: 'float: right' } - - if @account.local? - = link_to t('admin.accounts.reset_password'), admin_account_reset_path(@account.id), method: :create, class: 'button' if can?(:reset_password, @account.user) - - if @account.user&.otp_required_for_login? - = link_to t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(@account.user.id), method: :delete, class: 'button' if can?(:disable_2fa, @account.user) - - if !@account.memorial? && @account.user_approved? - = link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:memorialize, @account) + - if @account.local? && @account.user_approved? + = link_to t('admin.accounts.warn'), new_admin_account_action_path(@account.id, type: 'none'), class: 'button' if can?(:warn, @account) + + - if @account.force_sensitive? + = link_to t('admin.accounts.allow_nonsensitive'), allow_nonsensitive_admin_account_path(@account.id), method: :post, class: 'button' if can?(:allow_nonsensitive, @account) + - elsif !@account.local? || @account.user_approved? + = link_to t('admin.accounts.force_sensitive'), new_admin_account_action_path(@account.id, type: 'force_sensitive'), class: 'button button--destructive' if can?(:force_sensitive, @account) + + - if @account.force_unlisted? + = link_to t('admin.accounts.allow_public'), allow_public_admin_account_path(@account.id), method: :post, class: 'button' if can?(:allow_public, @account) + - elsif !@account.local? || @account.user_approved? + = link_to t('admin.accounts.force_unlisted'), new_admin_account_action_path(@account.id, type: 'force_unlisted'), class: 'button button--destructive' if can?(:force_unlisted, @account) + + - if @account.silenced? + = link_to t('admin.accounts.undo_silenced'), unsilence_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unsilence, @account) + - elsif !@account.local? || @account.user_approved? + = link_to t('admin.accounts.silence'), new_admin_account_action_path(@account.id, type: 'silence'), class: 'button button--destructive' if can?(:silence, @account) + + - if @account.local? + - if @account.user_pending? + = link_to t('admin.accounts.approve'), approve_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:approve, @account.user) + = link_to t('admin.accounts.reject'), reject_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:reject, @account.user) + + - unless @account.user_confirmed? + = link_to t('admin.accounts.confirm'), admin_account_confirmation_path(@account.id), method: :post, class: 'button' if can?(:confirm, @account.user) + + - if @account.suspended? + = link_to t('admin.accounts.undo_suspension'), unsuspend_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unsuspend, @account) + - elsif !@account.local? || @account.user_approved? + = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(@account.id, type: 'suspend'), class: 'button button--destructive' if can?(:suspend, @account) + + - unless @account.local? + - if DomainBlock.where(domain: @account.domain).exists? + = link_to t('admin.domain_blocks.undo'), admin_instance_path(@account.domain), class: 'button' - else - = link_to t('admin.accounts.redownload'), redownload_admin_account_path(@account.id), method: :post, class: 'button' if can?(:redownload, @account) - - %div{ style: 'float: left' } - - if @account.local? && @account.user_approved? - = link_to t('admin.accounts.warn'), new_admin_account_action_path(@account.id, type: 'none'), class: 'button' if can?(:warn, @account) - - if @account.silenced? - = link_to t('admin.accounts.undo_silenced'), unsilence_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unsilence, @account) - - elsif !@account.local? || @account.user_approved? - = link_to t('admin.accounts.silence'), new_admin_account_action_path(@account.id, type: 'silence'), class: 'button button--destructive' if can?(:silence, @account) - - - if @account.local? - - if @account.user_pending? - = link_to t('admin.accounts.approve'), approve_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:approve, @account.user) - = link_to t('admin.accounts.reject'), reject_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:reject, @account.user) - - - unless @account.user_confirmed? - = link_to t('admin.accounts.confirm'), admin_account_confirmation_path(@account.id), method: :post, class: 'button' if can?(:confirm, @account.user) - - - if @account.suspended? - = link_to t('admin.accounts.undo_suspension'), unsuspend_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unsuspend, @account) - - elsif !@account.local? || @account.user_approved? - = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(@account.id, type: 'suspend'), class: 'button button--destructive' if can?(:suspend, @account) - - - unless @account.local? - - if DomainBlock.where(domain: @account.domain).exists? - = link_to t('admin.domain_blocks.undo'), admin_instance_path(@account.domain), class: 'button' - - else - = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @account.domain), class: 'button button--destructive' + = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @account.domain), class: 'button button--destructive' + + - if @account.local? + = link_to t('admin.accounts.reset_password'), admin_account_reset_path(@account.id), method: :create, class: 'button' if can?(:reset_password, @account.user) + - if @account.user&.otp_required_for_login? + = link_to t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(@account.user.id), method: :delete, class: 'button' if can?(:disable_2fa, @account.user) + - if !@account.memorial? && @account.user_approved? + = link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:memorialize, @account) + - else + = link_to t('admin.accounts.redownload'), redownload_admin_account_path(@account.id), method: :post, class: 'button' if can?(:redownload, @account) %hr.spacer/ diff --git a/app/views/admin/domain_blocks/new.html.haml b/app/views/admin/domain_blocks/new.html.haml index 3a4963489..2517b2714 100644 --- a/app/views/admin/domain_blocks/new.html.haml +++ b/app/views/admin/domain_blocks/new.html.haml @@ -11,6 +11,9 @@ .fields-row__column.fields-row__column-6.fields-group = f.input :severity, collection: DomainBlock.severities.keys, wrapper: :with_label, include_blank: false, label_method: lambda { |type| t(".severity.#{type}") }, hint: t('.severity.desc_html') + .fields-group + = f.input :force_sensitive, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.force_sensitive'), hint: I18n.t('admin.domain_blocks.force_sensitive_hint') + .fields-group = f.input :reject_media, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_media'), hint: I18n.t('admin.domain_blocks.reject_media_hint') diff --git a/app/views/settings/profiles/show.html.haml b/app/views/settings/profiles/show.html.haml index 43d436cb1..8a7ccfd37 100644 --- a/app/views/settings/profiles/show.html.haml +++ b/app/views/settings/profiles/show.html.haml @@ -26,6 +26,9 @@ = f.input :unlisted, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.unlisted') = f.input :replies, as: :boolean, wrapper: :with_label + .fields-group + = f.input :adults_only, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.adults_only') + .fields-group = f.input :bot, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.bot') -- cgit