diff --git a/app/controllers/admin/account_actions_controller.rb b/app/controllers/admin/account_actions_controller.rb
new file mode 100644
index 0000000000..e847495f1b
--- /dev/null
+++ b/app/controllers/admin/account_actions_controller.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Admin
+ class AccountActionsController < BaseController
+ before_action :set_account
+
+ def new
+ @account_action = Admin::AccountAction.new(type: params[:type], report_id: params[:report_id], send_email_notification: true)
+ @warning_presets = AccountWarningPreset.all
+ end
+
+ def create
+ account_action = Admin::AccountAction.new(resource_params)
+ account_action.target_account = @account
+ account_action.current_account = current_account
+
+ account_action.save!
+
+ if account_action.with_report?
+ redirect_to admin_report_path(account_action.report)
+ else
+ redirect_to admin_account_path(@account.id)
+ end
+ end
+
+ private
+
+ def set_account
+ @account = Account.find(params[:account_id])
+ end
+
+ def resource_params
+ params.require(:admin_account_action).permit(:type, :report_id, :warning_preset_id, :text, :send_email_notification)
+ end
+ end
+end
diff --git a/app/controllers/admin/account_moderation_notes_controller.rb b/app/controllers/admin/account_moderation_notes_controller.rb
index 7d5b9bf52c..44f6e34f80 100644
--- a/app/controllers/admin/account_moderation_notes_controller.rb
+++ b/app/controllers/admin/account_moderation_notes_controller.rb
@@ -14,6 +14,7 @@ module Admin
else
@account = @account_moderation_note.target_account
@moderation_notes = @account.targeted_moderation_notes.latest
+ @warnings = @account.targeted_account_warnings.latest.custom
render template: 'admin/accounts/show'
end
diff --git a/app/controllers/admin/accounts_controller.rb b/app/controllers/admin/accounts_controller.rb
index 771302db80..10abd1e6ae 100644
--- a/app/controllers/admin/accounts_controller.rb
+++ b/app/controllers/admin/accounts_controller.rb
@@ -2,9 +2,9 @@
module Admin
class AccountsController < BaseController
- before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload, :remove_avatar, :remove_header, :enable, :disable, :memorialize]
+ before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload, :remove_avatar, :remove_header, :enable, :memorialize]
before_action :require_remote_account!, only: [:subscribe, :unsubscribe, :redownload]
- before_action :require_local_account!, only: [:enable, :disable, :memorialize]
+ before_action :require_local_account!, only: [:enable, :memorialize]
def index
authorize :account, :index?
@@ -13,8 +13,10 @@ module Admin
def show
authorize @account, :show?
+
@account_moderation_note = current_account.account_moderation_notes.new(target_account: @account)
- @moderation_notes = @account.targeted_moderation_notes.latest
+ @moderation_notes = @account.targeted_moderation_notes.latest
+ @warnings = @account.targeted_account_warnings.latest.custom
end
def subscribe
@@ -43,10 +45,17 @@ module Admin
redirect_to admin_account_path(@account.id)
end
- def disable
- authorize @account.user, :disable?
- @account.user.disable!
- log_action :disable, @account.user
+ def unsilence
+ authorize @account, :unsilence?
+ @account.unsilence!
+ log_action :unsilence, @account
+ redirect_to admin_account_path(@account.id)
+ end
+
+ def unsuspend
+ authorize @account, :unsuspend?
+ @account.unsuspend!
+ log_action :unsuspend, @account
redirect_to admin_account_path(@account.id)
end
diff --git a/app/controllers/admin/reports_controller.rb b/app/controllers/admin/reports_controller.rb
index e97ddb9b64..f138376b2f 100644
--- a/app/controllers/admin/reports_controller.rb
+++ b/app/controllers/admin/reports_controller.rb
@@ -13,75 +13,42 @@ module Admin
authorize @report, :show?
@report_note = @report.notes.new
- @report_notes = (@report.notes.latest + @report.history).sort_by(&:created_at)
+ @report_notes = (@report.notes.latest + @report.history + @report.target_account.targeted_account_warnings.latest.custom).sort_by(&:created_at)
@form = Form::StatusBatch.new
end
- def update
+ def assign_to_self
authorize @report, :update?
- process_report
+ @report.update!(assigned_account_id: current_account.id)
+ log_action :assigned_to_self, @report
+ redirect_to admin_report_path(@report)
+ end
- if @report.action_taken?
- redirect_to admin_reports_path, notice: I18n.t('admin.reports.resolved_msg')
- else
- redirect_to admin_report_path(@report)
- end
+ def unassign
+ authorize @report, :update?
+ @report.update!(assigned_account_id: nil)
+ log_action :unassigned, @report
+ redirect_to admin_report_path(@report)
+ end
+
+ def reopen
+ authorize @report, :update?
+ @report.unresolve!
+ log_action :reopen, @report
+ redirect_to admin_report_path(@report)
+ end
+
+ def resolve
+ authorize @report, :update?
+ @report.resolve!(current_account)
+ log_action :resolve, @report
+ redirect_to admin_reports_path, notice: I18n.t('admin.reports.resolved_msg')
end
private
- def process_report
- case params[:outcome].to_s
- when 'assign_to_self'
- @report.update!(assigned_account_id: current_account.id)
- log_action :assigned_to_self, @report
- when 'unassign'
- @report.update!(assigned_account_id: nil)
- log_action :unassigned, @report
- when 'reopen'
- @report.unresolve!
- log_action :reopen, @report
- when 'resolve'
- @report.resolve!(current_account)
- log_action :resolve, @report
- when 'disable'
- @report.resolve!(current_account)
- @report.target_account.user.disable!
-
- log_action :resolve, @report
- log_action :disable, @report.target_account.user
-
- resolve_all_target_account_reports
- when 'silence'
- @report.resolve!(current_account)
- @report.target_account.update!(silenced: true)
-
- log_action :resolve, @report
- log_action :silence, @report.target_account
-
- resolve_all_target_account_reports
- else
- raise ActiveRecord::RecordNotFound
- end
-
- @report.reload
- end
-
- def resolve_all_target_account_reports
- unresolved_reports_for_target_account.update_all(action_taken: true, action_taken_by_account_id: current_account.id)
- end
-
- def unresolved_reports_for_target_account
- Report.where(
- target_account: @report.target_account
- ).unresolved
- end
-
def filtered_reports
- ReportFilter.new(filter_params).results.order(id: :desc).includes(
- :account,
- :target_account
- )
+ ReportFilter.new(filter_params).results.order(id: :desc).includes(:account, :target_account)
end
def filter_params
diff --git a/app/controllers/admin/silences_controller.rb b/app/controllers/admin/silences_controller.rb
deleted file mode 100644
index 4c06a9c0cc..0000000000
--- a/app/controllers/admin/silences_controller.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-module Admin
- class SilencesController < BaseController
- before_action :set_account
-
- def create
- authorize @account, :silence?
- @account.update!(silenced: true)
- log_action :silence, @account
- redirect_to admin_accounts_path
- end
-
- def destroy
- authorize @account, :unsilence?
- @account.update!(silenced: false)
- log_action :unsilence, @account
- redirect_to admin_accounts_path
- end
-
- private
-
- def set_account
- @account = Account.find(params[:account_id])
- end
- end
-end
diff --git a/app/controllers/admin/suspensions_controller.rb b/app/controllers/admin/suspensions_controller.rb
deleted file mode 100644
index f9bbf36fb8..0000000000
--- a/app/controllers/admin/suspensions_controller.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: true
-
-module Admin
- class SuspensionsController < BaseController
- before_action :set_account
-
- def new
- @suspension = Form::AdminSuspensionConfirmation.new(report_id: params[:report_id])
- end
-
- def create
- authorize @account, :suspend?
-
- @suspension = Form::AdminSuspensionConfirmation.new(suspension_params)
-
- if suspension_params[:acct] == @account.acct
- resolve_report! if suspension_params[:report_id].present?
- perform_suspend!
- mark_reports_resolved!
- redirect_to admin_accounts_path
- else
- flash.now[:alert] = I18n.t('admin.suspensions.bad_acct_msg')
- render :new
- end
- end
-
- def destroy
- authorize @account, :unsuspend?
- @account.unsuspend!
- log_action :unsuspend, @account
- redirect_to admin_accounts_path
- end
-
- private
-
- def set_account
- @account = Account.find(params[:account_id])
- end
-
- def suspension_params
- params.require(:form_admin_suspension_confirmation).permit(:acct, :report_id)
- end
-
- def resolve_report!
- report = Report.find(suspension_params[:report_id])
- report.resolve!(current_account)
- log_action :resolve, report
- end
-
- def perform_suspend!
- @account.suspend!
- Admin::SuspensionWorker.perform_async(@account.id)
- log_action :suspend, @account
- end
-
- def mark_reports_resolved!
- Report.where(target_account: @account).unresolved.update_all(action_taken: true, action_taken_by_account_id: current_account.id)
- end
- end
-end
diff --git a/app/controllers/admin/warning_presets_controller.rb b/app/controllers/admin/warning_presets_controller.rb
new file mode 100644
index 0000000000..37be842c5b
--- /dev/null
+++ b/app/controllers/admin/warning_presets_controller.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Admin
+ class WarningPresetsController < BaseController
+ before_action :set_warning_preset, except: [:index, :create]
+
+ def index
+ authorize :account_warning_preset, :index?
+
+ @warning_presets = AccountWarningPreset.all
+ @warning_preset = AccountWarningPreset.new
+ end
+
+ def create
+ authorize :account_warning_preset, :create?
+
+ @warning_preset = AccountWarningPreset.new(warning_preset_params)
+
+ if @warning_preset.save
+ redirect_to admin_warning_presets_path
+ else
+ @warning_presets = AccountWarningPreset.all
+ render :index
+ end
+ end
+
+ def edit
+ authorize @warning_preset, :update?
+ end
+
+ def update
+ authorize @warning_preset, :update?
+
+ if @warning_preset.update(warning_preset_params)
+ redirect_to admin_warning_presets_path
+ else
+ render :edit
+ end
+ end
+
+ def destroy
+ authorize @warning_preset, :destroy?
+
+ @warning_preset.destroy!
+ redirect_to admin_warning_presets_path
+ end
+
+ private
+
+ def set_warning_preset
+ @warning_preset = AccountWarningPreset.find(params[:id])
+ end
+
+ def warning_preset_params
+ params.require(:account_warning_preset).permit(:text)
+ end
+ end
+end
diff --git a/app/helpers/admin/action_logs_helper.rb b/app/helpers/admin/action_logs_helper.rb
index 68cf8c75dd..359d60b60e 100644
--- a/app/helpers/admin/action_logs_helper.rb
+++ b/app/helpers/admin/action_logs_helper.rb
@@ -23,6 +23,8 @@ module Admin::ActionLogsHelper
link_to record.domain, "https://#{record.domain}"
when 'Status'
link_to record.account.acct, TagManager.instance.url_for(record)
+ when 'AccountWarning'
+ link_to record.target_account.acct, admin_account_path(record.target_account_id)
end
end
@@ -34,6 +36,7 @@ module Admin::ActionLogsHelper
link_to attributes['domain'], "https://#{attributes['domain']}"
when 'Status'
tmp_status = Status.new(attributes.except('reblogs_count', 'favourites_count'))
+
if tmp_status.account
link_to tmp_status.account&.acct || "##{tmp_status.account_id}", admin_account_path(tmp_status.account_id)
else
@@ -81,6 +84,8 @@ module Admin::ActionLogsHelper
'envelope'
when 'Status'
'pencil'
+ when 'AccountWarning'
+ 'warning'
end
end
@@ -104,6 +109,6 @@ module Admin::ActionLogsHelper
private
def opposite_verbs?(log)
- %w(DomainBlock EmailDomainBlock).include?(log.target_type)
+ %w(DomainBlock EmailDomainBlock AccountWarning).include?(log.target_type)
end
end
diff --git a/app/javascript/images/icon_flag.svg b/app/javascript/images/icon_flag.svg
new file mode 100644
index 0000000000..3939c9d2b3
--- /dev/null
+++ b/app/javascript/images/icon_flag.svg
@@ -0,0 +1,4 @@
+
diff --git a/app/javascript/images/mailer/icon_warning.png b/app/javascript/images/mailer/icon_warning.png
new file mode 100644
index 0000000000..7baaac61cb
Binary files /dev/null and b/app/javascript/images/mailer/icon_warning.png differ
diff --git a/app/javascript/styles/mailer.scss b/app/javascript/styles/mailer.scss
index d83bd4d960..74d1df8ed3 100644
--- a/app/javascript/styles/mailer.scss
+++ b/app/javascript/styles/mailer.scss
@@ -426,6 +426,10 @@ h5 {
background: $success-green;
}
+ &.alert-icon td {
+ background: $error-red;
+ }
+
img {
max-width: 32px;
width: 32px;
diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss
index b6c771abf3..e8f3319323 100644
--- a/app/javascript/styles/mastodon/admin.scss
+++ b/app/javascript/styles/mastodon/admin.scss
@@ -542,6 +542,10 @@ a.name-tag,
border-left-color: lighten($error-red, 12%);
}
+ &.warning {
+ border-left-color: $gold-star;
+ }
+
&__bubble {
padding: 16px;
padding-left: 14px;
diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb
index aa76b4dfe4..8f3a4ab3aa 100644
--- a/app/mailers/user_mailer.rb
+++ b/app/mailers/user_mailer.rb
@@ -78,4 +78,16 @@ class UserMailer < Devise::Mailer
mail to: @resource.email, subject: I18n.t('user_mailer.backup_ready.subject')
end
end
+
+ def warning(user, warning)
+ @resource = user
+ @warning = warning
+ @instance = Rails.configuration.x.local_domain
+
+ I18n.with_locale(@resource.locale || I18n.default_locale) do
+ mail to: @resource.email,
+ subject: I18n.t("user_mailer.warning.subject.#{@warning.action}", acct: "@#{user.account.local_username_and_domain}"),
+ reply_to: Setting.site_contact_email
+ end
+ end
end
diff --git a/app/models/account.rb b/app/models/account.rb
index 5a7a9c580a..16ef6c187a 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -155,6 +155,14 @@ class Account < ApplicationRecord
ResolveAccountService.new.call(acct)
end
+ def silence!
+ update!(silenced: true)
+ end
+
+ def unsilence!
+ update!(silenced: false)
+ end
+
def suspend!
transaction do
user&.disable! if local?
diff --git a/app/models/account_warning.rb b/app/models/account_warning.rb
new file mode 100644
index 0000000000..157e6c04d1
--- /dev/null
+++ b/app/models/account_warning.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: account_warnings
+#
+# id :bigint(8) not null, primary key
+# account_id :bigint(8)
+# target_account_id :bigint(8)
+# action :integer default("none"), not null
+# text :text default(""), not null
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+class AccountWarning < ApplicationRecord
+ enum action: %i(none disable silence suspend), _suffix: :action
+
+ belongs_to :account, inverse_of: :account_warnings
+ belongs_to :target_account, class_name: 'Account', inverse_of: :targeted_account_warnings
+
+ scope :latest, -> { order(created_at: :desc) }
+ scope :custom, -> { where.not(text: '') }
+end
diff --git a/app/models/account_warning_preset.rb b/app/models/account_warning_preset.rb
new file mode 100644
index 0000000000..ba8ceabb35
--- /dev/null
+++ b/app/models/account_warning_preset.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+# == Schema Information
+#
+# Table name: account_warning_presets
+#
+# id :bigint(8) not null, primary key
+# text :text default(""), not null
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+class AccountWarningPreset < ApplicationRecord
+ validates :text, presence: true
+end
diff --git a/app/models/admin/account_action.rb b/app/models/admin/account_action.rb
new file mode 100644
index 0000000000..84c3f880d2
--- /dev/null
+++ b/app/models/admin/account_action.rb
@@ -0,0 +1,134 @@
+# frozen_string_literal: true
+
+class Admin::AccountAction
+ include ActiveModel::Model
+ include AccountableConcern
+ include Authorization
+
+ TYPES = %w(
+ none
+ disable
+ silence
+ suspend
+ ).freeze
+
+ attr_accessor :target_account,
+ :current_account,
+ :type,
+ :text,
+ :report_id,
+ :warning_preset_id,
+ :send_email_notification
+
+ attr_reader :warning
+
+ def save!
+ ApplicationRecord.transaction do
+ process_action!
+ process_warning!
+ end
+
+ queue_email!
+ process_reports!
+ end
+
+ def report
+ @report ||= Report.find(report_id) if report_id.present?
+ end
+
+ def with_report?
+ !report.nil?
+ end
+
+ class << self
+ def types_for_account(account)
+ if account.local?
+ TYPES
+ else
+ TYPES - %w(none disable)
+ end
+ end
+ end
+
+ private
+
+ def process_action!
+ case type
+ when 'disable'
+ handle_disable!
+ when 'silence'
+ handle_silence!
+ when 'suspend'
+ handle_suspend!
+ end
+ end
+
+ def process_warning!
+ return unless warnable?
+
+ authorize(target_account, :warn?)
+
+ @warning = AccountWarning.create!(target_account: target_account,
+ account: current_account,
+ action: type,
+ text: text_for_warning)
+
+ # A log entry is only interesting if the warning contains
+ # custom text from someone. Otherwise it's just noise.
+ log_action(:create, warning) if warning.text.present?
+ end
+
+ def process_reports!
+ return if report_id.blank?
+
+ authorize(report, :update?)
+
+ if type == 'none'
+ log_action(:resolve, report)
+ report.resolve!(current_account)
+ else
+ Report.where(target_account: target_account).unresolved.update_all(action_taken: true, action_taken_by_account_id: current_account.id)
+ end
+ end
+
+ def handle_disable!
+ authorize(target_account.user, :disable?)
+ log_action(:disable, target_account.user)
+ target_account.user&.disable!
+ end
+
+ def handle_silence!
+ authorize(target_account, :silence?)
+ log_action(:silence, target_account)
+ target_account.silence!
+ end
+
+ def handle_suspend!
+ authorize(target_account, :suspend?)
+ log_action(:suspend, target_account)
+ target_account.suspend!
+ queue_suspension_worker!
+ end
+
+ def text_for_warning
+ [warning_preset&.text, text].compact.join("\n\n")
+ end
+
+ def queue_suspension_worker!
+ Admin::SuspensionWorker.perform_async(target_account.id)
+ end
+
+ def queue_email!
+ return unless warnable?
+
+ UserMailer.warning(target_account.user, warning).deliver_later!
+ end
+
+ def warnable?
+ send_email_notification && target_account.local?
+ end
+
+ def warning_preset
+ @warning_preset ||= AccountWarningPreset.find(warning_preset_id) if warning_preset_id.present?
+ end
+end
diff --git a/app/models/concerns/account_associations.rb b/app/models/concerns/account_associations.rb
index ae50860eda..a894b5eeda 100644
--- a/app/models/concerns/account_associations.rb
+++ b/app/models/concerns/account_associations.rb
@@ -39,6 +39,8 @@ module AccountAssociations
# Moderation notes
has_many :account_moderation_notes, dependent: :destroy, inverse_of: :account
has_many :targeted_moderation_notes, class_name: 'AccountModerationNote', foreign_key: :target_account_id, dependent: :destroy, inverse_of: :target_account
+ has_many :account_warnings, dependent: :destroy, inverse_of: :account
+ has_many :targeted_account_warnings, class_name: 'AccountWarning', foreign_key: :target_account_id, dependent: :destroy, inverse_of: :target_account
# Lists (that the account is on, not owned by the account)
has_many :list_accounts, inverse_of: :account, dependent: :destroy
diff --git a/app/models/form/admin_suspension_confirmation.rb b/app/models/form/admin_suspension_confirmation.rb
deleted file mode 100644
index c34b5b30e3..0000000000
--- a/app/models/form/admin_suspension_confirmation.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-class Form::AdminSuspensionConfirmation
- include ActiveModel::Model
-
- attr_accessor :acct, :report_id
-end
diff --git a/app/policies/account_policy.rb b/app/policies/account_policy.rb
index 07bae68efb..9c145979d6 100644
--- a/app/policies/account_policy.rb
+++ b/app/policies/account_policy.rb
@@ -9,6 +9,10 @@ class AccountPolicy < ApplicationPolicy
staff?
end
+ def warn?
+ staff? && !record.user&.staff?
+ end
+
def suspend?
staff? && !record.user&.staff?
end
diff --git a/app/policies/account_warning_preset_policy.rb b/app/policies/account_warning_preset_policy.rb
new file mode 100644
index 0000000000..bccbd33efd
--- /dev/null
+++ b/app/policies/account_warning_preset_policy.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AccountWarningPresetPolicy < ApplicationPolicy
+ def index?
+ staff?
+ end
+
+ def create?
+ staff?
+ end
+
+ def update?
+ staff?
+ end
+
+ def destroy?
+ staff?
+ end
+end
diff --git a/app/views/admin/account_actions/new.html.haml b/app/views/admin/account_actions/new.html.haml
new file mode 100644
index 0000000000..97286c8e5b
--- /dev/null
+++ b/app/views/admin/account_actions/new.html.haml
@@ -0,0 +1,26 @@
+- content_for :page_title do
+ = t('admin.account_actions.title', acct: @account.acct)
+
+= simple_form_for @account_action, url: admin_account_action_path(@account.id) do |f|
+ = f.input :report_id, as: :hidden
+
+ .fields-group
+ = f.input :type, collection: Admin::AccountAction.types_for_account(@account), include_blank: false, wrapper: :with_block_label, label_method: ->(type) { I18n.t("simple_form.labels.admin_account_action.types.#{type}")}, hint: t('simple_form.hints.admin_account_action.type_html', acct: @account.acct)
+
+ - if @account.local?
+ %hr.spacer/
+
+ .fields-group
+ = f.input :send_email_notification, as: :boolean, wrapper: :with_label
+
+ %hr.spacer/
+
+ - unless @warning_presets.empty?
+ .fields-group
+ = f.input :warning_preset_id, collection: @warning_presets, label_method: :text, wrapper: :with_block_label
+
+ .fields-group
+ = f.input :text, as: :text, wrapper: :with_block_label, hint: t('simple_form.hints.admin_account_action.text_html', path: admin_warning_presets_path)
+
+ .actions
+ = f.button :button, t('admin.account_actions.action'), type: :submit
diff --git a/app/views/admin/account_warnings/_account_warning.html.haml b/app/views/admin/account_warnings/_account_warning.html.haml
new file mode 100644
index 0000000000..8c9c9679ce
--- /dev/null
+++ b/app/views/admin/account_warnings/_account_warning.html.haml
@@ -0,0 +1,6 @@
+.speech-bubble.warning
+ .speech-bubble__bubble
+ = Formatter.instance.linkify(account_warning.text)
+ .speech-bubble__owner
+ = admin_account_link_to account_warning.account
+ %time.formatted{ datetime: account_warning.created_at.iso8601 }= l account_warning.created_at
diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml
index e9f7651078..226aef732e 100644
--- a/app/views/admin/accounts/show.html.haml
+++ b/app/views/admin/accounts/show.html.haml
@@ -64,7 +64,7 @@
= table_link_to 'unlock', t('admin.accounts.enable'), enable_admin_account_path(@account.id), method: :post if can?(:enable, @account.user)
- else
= t('admin.accounts.enabled')
- = table_link_to 'lock', t('admin.accounts.disable'), disable_admin_account_path(@account.id), method: :post if can?(:disable, @account.user)
+ = table_link_to 'lock', t('admin.accounts.disable'), new_admin_account_action_path(@account.id, type: 'disable') if can?(:disable, @account.user)
%tr
%th= t('admin.accounts.most_recent_ip')
%td= @account.user_current_sign_in_ip
@@ -119,18 +119,18 @@
%div{ style: 'float: left' }
- if @account.silenced?
- = link_to t('admin.accounts.undo_silenced'), admin_account_silence_path(@account.id), method: :delete, class: 'button' if can?(:unsilence, @account)
+ = link_to t('admin.accounts.undo_silenced'), unsilence_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unsilence, @account)
- else
- = link_to t('admin.accounts.silence'), admin_account_silence_path(@account.id), method: :post, class: 'button button--destructive' if can?(:silence, @account)
+ = 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?
- 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'), admin_account_suspension_path(@account.id), method: :delete, class: 'button' if can?(:unsuspend, @account)
+ = link_to t('admin.accounts.undo_suspension'), unsuspend_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unsuspend, @account)
- else
- = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_suspension_path(@account.id), class: 'button button--destructive' if can?(:suspend, @account)
+ = 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)
- if !@account.local? && @account.hub_url.present?
%hr.spacer/
@@ -184,6 +184,10 @@
%hr.spacer/
+= render @warnings
+
+%hr.spacer/
+
= render @moderation_notes
= simple_form_for @account_moderation_note, url: admin_account_moderation_notes_path do |f|
diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml
index 3588d151d2..863dada9e2 100644
--- a/app/views/admin/reports/show.html.haml
+++ b/app/views/admin/reports/show.html.haml
@@ -8,13 +8,14 @@
- if @report.unresolved?
%div{ style: 'float: right' }
- if @report.target_account.local?
- = link_to t('admin.accounts.disable'), admin_report_path(@report, outcome: 'disable'), method: :put, class: 'button button--destructive'
- = link_to t('admin.accounts.silence'), admin_report_path(@report, outcome: 'silence'), method: :put, class: 'button button--destructive'
- = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_suspension_path(@report.target_account_id, report_id: @report.id), class: 'button button--destructive'
+ = link_to t('admin.accounts.warn'), new_admin_account_action_path(@report.target_account_id, type: 'none', report_id: @report.id), class: 'button'
+ = link_to t('admin.accounts.disable'), new_admin_account_action_path(@report.target_account_id, type: 'disable', report_id: @report.id), class: 'button button--destructive'
+ = link_to t('admin.accounts.silence'), new_admin_account_action_path(@report.target_account_id, type: 'silence', report_id: @report.id), class: 'button button--destructive'
+ = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(@report.target_account_id, type: 'suspend', report_id: @report.id), class: 'button button--destructive'
%div{ style: 'float: left' }
- = link_to t('admin.reports.mark_as_resolved'), admin_report_path(@report, outcome: 'resolve'), method: :put, class: 'button'
+ = link_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(@report), method: :post, class: 'button'
- else
- = link_to t('admin.reports.mark_as_unresolved'), admin_report_path(@report, outcome: 'reopen'), method: :put, class: 'button'
+ = link_to t('admin.reports.mark_as_unresolved'), reopen_admin_report_path(@report), method: :post, class: 'button'
%hr.spacer
@@ -67,10 +68,10 @@
= admin_account_link_to @report.assigned_account
%td
- if @report.assigned_account != current_user.account
- = table_link_to 'user', t('admin.reports.assign_to_self'), admin_report_path(@report, outcome: 'assign_to_self'), method: :put
+ = table_link_to 'user', t('admin.reports.assign_to_self'), assign_to_self_admin_report_path(@report), method: :post
%td
- if !@report.assigned_account.nil?
- = table_link_to 'trash', t('admin.reports.unassign'), admin_report_path(@report, outcome: 'unassign'), method: :put
+ = table_link_to 'trash', t('admin.reports.unassign'), unassign_admin_report_path(@report), method: :post
%hr.spacer
@@ -104,7 +105,7 @@
- @report_notes.each do |item|
- if item.is_a?(Admin::ActionLog)
= render partial: 'action_log', locals: { action_log: item }
- - elsif item.is_a?(ReportNote)
+ - else
= render item
= simple_form_for @report_note, url: admin_report_notes_path do |f|
diff --git a/app/views/admin/suspensions/new.html.haml b/app/views/admin/suspensions/new.html.haml
deleted file mode 100644
index f03ecacc31..0000000000
--- a/app/views/admin/suspensions/new.html.haml
+++ /dev/null
@@ -1,25 +0,0 @@
-- content_for :page_title do
- = t('admin.suspensions.title', acct: @account.acct)
-
-= simple_form_for @suspension, url: admin_account_suspension_path(@account.id), method: :post do |f|
- %p.hint= t('admin.suspensions.warning_html')
-
- .fields-group
- %ul
- %li.negative-hint
- = number_to_human @account.statuses_count, strip_insignificant_zeros: true
- = t('accounts.posts', count: @account.statuses_count)
- %li.negative-hint
- = number_to_human @account.following_count, strip_insignificant_zeros: true
- = t('accounts.following', count: @account.following_count)
- %li.negative-hint
- = number_to_human @account.followers_count, strip_insignificant_zeros: true
- = t('accounts.followers', count: @account.followers_count)
-
- %p.hint= t('admin.suspensions.hint_html', value: content_tag(:code, @account.acct))
-
- = f.input :acct
- = f.input_field :report_id, as: :hidden
-
- .actions
- = f.button :button, t('admin.suspensions.proceed'), type: :submit, class: 'negative'
diff --git a/app/views/admin/warning_presets/edit.html.haml b/app/views/admin/warning_presets/edit.html.haml
new file mode 100644
index 0000000000..9522746cd1
--- /dev/null
+++ b/app/views/admin/warning_presets/edit.html.haml
@@ -0,0 +1,11 @@
+- content_for :page_title do
+ = t('admin.warning_presets.edit_preset')
+
+= simple_form_for @warning_preset, url: admin_warning_preset_path(@warning_preset) do |f|
+ = render 'shared/error_messages', object: @warning_preset
+
+ .fields-group
+ = f.input :text, wrapper: :with_block_label
+
+ .actions
+ = f.button :button, t('generic.save_changes'), type: :submit
diff --git a/app/views/admin/warning_presets/index.html.haml b/app/views/admin/warning_presets/index.html.haml
new file mode 100644
index 0000000000..45913ef733
--- /dev/null
+++ b/app/views/admin/warning_presets/index.html.haml
@@ -0,0 +1,30 @@
+- content_for :page_title do
+ = t('admin.warning_presets.title')
+
+- if can? :create, :account_warning_preset
+ = simple_form_for @warning_preset, url: admin_warning_presets_path do |f|
+ = render 'shared/error_messages', object: @warning_preset
+
+ .fields-group
+ = f.input :text, wrapper: :with_block_label
+
+ .actions
+ = f.button :button, t('admin.warning_presets.add_new'), type: :submit
+
+ %hr.spacer/
+
+- unless @warning_presets.empty?
+ .table-wrapper
+ %table.table
+ %thead
+ %tr
+ %th= t('simple_form.labels.account_warning_preset.text')
+ %th
+ %tbody
+ - @warning_presets.each do |preset|
+ %tr
+ %td
+ = Formatter.instance.linkify(preset.text)
+ %td
+ = table_link_to 'pencil', t('admin.warning_presets.edit'), edit_admin_warning_preset_path(preset)
+ = table_link_to 'trash', t('admin.warning_presets.delete'), admin_warning_preset_path(preset), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
diff --git a/app/views/user_mailer/warning.html.haml b/app/views/user_mailer/warning.html.haml
new file mode 100644
index 0000000000..c5e1f5a289
--- /dev/null
+++ b/app/views/user_mailer/warning.html.haml
@@ -0,0 +1,63 @@
+%table.email-table{ cellspacing: 0, cellpadding: 0 }
+ %tbody
+ %tr
+ %td.email-body
+ .email-container
+ %table.content-section{ cellspacing: 0, cellpadding: 0 }
+ %tbody
+ %tr
+ %td.content-cell.hero
+ .email-row
+ .col-6
+ %table.column{ cellspacing: 0, cellpadding: 0 }
+ %tbody
+ %tr
+ %td.column-cell.text-center.padded
+ %table.hero-icon.alert-icon{ align: 'center', cellspacing: 0, cellpadding: 0 }
+ %tbody
+ %tr
+ %td
+ = image_tag full_pack_url('icon_warning.png'), alt: ''
+
+ %h1= t "user_mailer.warning.title.#{@warning.action}"
+
+%table.email-table{ cellspacing: 0, cellpadding: 0 }
+ %tbody
+ %tr
+ %td.email-body
+ .email-container
+ %table.content-section{ cellspacing: 0, cellpadding: 0 }
+ %tbody
+ %tr
+ %td.content-cell.content-start
+ .email-row
+ .col-6
+ %table.column{ cellspacing: 0, cellpadding: 0 }
+ %tbody
+ %tr
+ %td.column-cell.text-center
+ - unless @warning.none_action?
+ %p= t "user_mailer.warning.explanation.#{@warning.action}"
+
+ - unless @warning.text.blank?
+ = Formatter.instance.linkify(@warning.text)
+
+%table.email-table{ cellspacing: 0, cellpadding: 0 }
+ %tbody
+ %tr
+ %td.email-body
+ .email-container
+ %table.content-section{ cellspacing: 0, cellpadding: 0 }
+ %tbody
+ %tr
+ %td.content-cell
+ %table.column{ cellspacing: 0, cellpadding: 0 }
+ %tbody
+ %tr
+ %td.column-cell.button-cell
+ %table.button{ align: 'center', cellspacing: 0, cellpadding: 0 }
+ %tbody
+ %tr
+ %td.button-primary
+ = link_to about_more_url do
+ %span= t 'user_mailer.warning.review_server_policies'
diff --git a/app/views/user_mailer/warning.text.erb b/app/views/user_mailer/warning.text.erb
new file mode 100644
index 0000000000..b4f2402cb3
--- /dev/null
+++ b/app/views/user_mailer/warning.text.erb
@@ -0,0 +1,9 @@
+<%= t "user_mailer.warning.title.#{@warning.action}" %>
+
+===
+
+<% unless @warning.none_action? %>
+<%= t "user_mailer.warning.explanation.#{@warning.action}" %>
+
+<% end %>
+<%= @warning.text %>
diff --git a/app/views/user_mailer/welcome.text.erb b/app/views/user_mailer/welcome.text.erb
index 5bd0cab2a5..845458c324 100644
--- a/app/views/user_mailer/welcome.text.erb
+++ b/app/views/user_mailer/welcome.text.erb
@@ -2,7 +2,7 @@
===
-<%= t 'user_mailer.welcome.full_handle' %> (<%= "@#{@resource.account.username}@#{@instance}" %>)
+<%= t 'user_mailer.welcome.full_handle' %> (<%= "@#{@resource.account.local_username_and_domain}" %>)
<%= t 'user_mailer.welcome.full_handle_hint', instance: @instance %>
---
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
index 2fa0752737..0652089d4d 100644
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -455,11 +455,6 @@ ar:
last_delivery: آخر إيداع
title: WebSub
topic: الموضوع
- suspensions:
- bad_acct_msg: قيمة التأكيد غير متطابقة. متأكد مِن أنك بصدد تعليق الحساب الصحيح؟
- hint_html: 'لتأكيد إجراء تعليق الحساب، يُرجى إدخال %{value} في الحقل التالي:'
- proceed: مواصلة
- title: تعليق الحساب %{acct}
tags:
accounts: الحسابات
hidden: المخفية
diff --git a/config/locales/ast.yml b/config/locales/ast.yml
index e6c51b10e5..c18c398eb9 100644
--- a/config/locales/ast.yml
+++ b/config/locales/ast.yml
@@ -121,8 +121,6 @@ ast:
failed_to_execute: Fallu al executar
subscriptions:
title: WebSub
- suspensions:
- warning_html: 'El suspender esta cuenta va desaniciar de mou irreversible los sos datos qu''inclúin:'
title: Alministración
admin_mailer:
new_report:
diff --git a/config/locales/ca.yml b/config/locales/ca.yml
index 1575b32ea1..b7e3cb7f6a 100644
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -439,12 +439,6 @@ ca:
last_delivery: Últim lliurament
title: WebSub
topic: Tema
- suspensions:
- bad_acct_msg: El valor de confirmació no s'ha trobat. Estàs suspenen el compte correcte?
- hint_html: 'Per confirmar la suspensió del compte, introdueix %{value} al camp següent:'
- proceed: Procedeix
- title: Suspèn %{acct}
- warning_html: 'Suspenen aquest compte esborrarà irreversiblement les dades del compte, incloent:'
tags:
accounts: Comptes
hidden: Amagat
diff --git a/config/locales/co.yml b/config/locales/co.yml
index c15f241c6c..3df78f007d 100644
--- a/config/locales/co.yml
+++ b/config/locales/co.yml
@@ -439,12 +439,6 @@ co:
last_delivery: Ultima arricata
title: WebSub
topic: Sughjettu
- suspensions:
- bad_acct_msg: U valore di cunfirmazione ùn era micca curretta. Site sicuru·a di suspende u bonu contu?
- hint_html: 'Per cunfirmà a suspensione di u contu, entrate %{value} quì sottu:'
- proceed: Cuntinuà
- title: Suspende %{acct}
- warning_html: 'A suspensione di u contu sguasserà di manera irreversibile i so dati, cum''è:'
tags:
accounts: Conti
hidden: Piattatu
diff --git a/config/locales/cs.yml b/config/locales/cs.yml
index d25ca6c2c8..0042d56410 100644
--- a/config/locales/cs.yml
+++ b/config/locales/cs.yml
@@ -444,12 +444,6 @@ cs:
last_delivery: Poslední doručení
title: WebSub
topic: Téma
- suspensions:
- bad_acct_msg: Hodnota pro potvrzení neodpovídá. Suspendujete správný účet?
- hint_html: 'Pro potvrzení suspenzace účtu prosím zadejte do pole níže %{value}:'
- proceed: Pokračovat
- title: Suspendovat účet %{acct}
- warning_html: 'Suspenzace tohoto účtu nenávratně smaže z tohoto účtu data, včetně:'
tags:
accounts: Účty
hidden: Skryté
diff --git a/config/locales/cy.yml b/config/locales/cy.yml
index 24ae6fa10d..2467d3e784 100644
--- a/config/locales/cy.yml
+++ b/config/locales/cy.yml
@@ -423,12 +423,6 @@ cy:
last_delivery: Danfoniad diwethaf
title: WebSub
topic: Pwnc
- suspensions:
- bad_acct_msg: Nid yw'r gwerthoedd cadarnhau yn cyfateb. Ydych chi'n atal y cyfrif cywir?
- hint_html: 'I gadarnhau atal y cyfrif, mewnbynwch %{value} yn y maes isod:'
- proceed: Parhau
- title: Atal %{acct}
- warning_html: 'Mi fydd atal y cyfrif hwn yn dileu data am byth o''r cyfrif hwn, gan gynnwys:'
title: Gweinyddiaeth
admin_mailer:
new_report:
diff --git a/config/locales/da.yml b/config/locales/da.yml
index c6bdc753af..202f6bfb3a 100644
--- a/config/locales/da.yml
+++ b/config/locales/da.yml
@@ -427,12 +427,6 @@ da:
last_delivery: Sidste levering
title: Websub
topic: Emne
- suspensions:
- bad_acct_msg: Bekræftelsværdien stemte ikke overens. Er du ved at udelukke den rigtige konto?
- hint_html: 'For at bekræfte udelukkelsen af kontoen, indtast venligst %{value} i nedenstående felt:'
- proceed: Fortsæt
- title: Udeluk %{acct}
- warning_html: 'Udelukkelse af denne konto vil uigenkaldeligt slette al data fra denne konto, hvilket indebærer:'
title: Administration
admin_mailer:
new_report:
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 945d5a0ff1..6478971715 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -439,12 +439,6 @@ de:
last_delivery: Letzte Zustellung
title: WebSub
topic: Thema
- suspensions:
- bad_acct_msg: Der Bestätigungswert stimmt nicht überein. Sperrst du das richtige Benutzerkonto?
- hint_html: 'Um die Sperrung des Benutzerkontos zu genehmigen tippe %{value} in das Feld unten ein:'
- proceed: Fortfahren
- title: "%{acct} sperren"
- warning_html: 'Die Sperrung des Benutzerkontos wird unwiederrufliche Schäden hervorrufen und alle Daten löschen, die folgendes beinhalten:'
tags:
accounts: Konten
hidden: Versteckt
diff --git a/config/locales/el.yml b/config/locales/el.yml
index 66393f213b..e03a116d02 100644
--- a/config/locales/el.yml
+++ b/config/locales/el.yml
@@ -439,12 +439,6 @@ el:
last_delivery: Τελευταία παράδοση
title: WebSub
topic: Θέμα
- suspensions:
- bad_acct_msg: Η τιμή επιβεβαίωσης δεν ταιριάζει. Σίγουρα αναστέλλεις το σωστό λογαριασμό;
- hint_html: 'Για να επιβεβαιώσεις την αναστολή του λογαριασμού, γράψε %{value} στο ακόλουθο πεδίο:'
- proceed: Συνέχεια
- title: Αναστολή %{acct}
- warning_html: 'Αναστέλλοντας αυτό το λογαριασμό θα διαγραφούν αμετάκλητα δεδομένα του, μεταξύ των οποίων:'
tags:
accounts: Λογαριασμοί
hidden: Κρυμμένες
diff --git a/config/locales/en.yml b/config/locales/en.yml
index bd0b0c3d52..bea182f0b7 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -70,6 +70,9 @@ en:
moderator: Mod
unfollow: Unfollow
admin:
+ account_actions:
+ action: Perform action
+ title: Perform moderation action on %{acct}
account_moderation_notes:
create: Leave note
created_msg: Moderation note successfully created!
@@ -173,6 +176,7 @@ en:
assigned_to_self_report: "%{name} assigned report %{target} to themselves"
change_email_user: "%{name} changed the e-mail address of user %{target}"
confirm_user: "%{name} confirmed e-mail address of user %{target}"
+ create_account_warning: "%{name} sent a warning to %{target}"
create_custom_emoji: "%{name} uploaded new emoji %{target}"
create_domain_block: "%{name} blocked domain %{target}"
create_email_domain_block: "%{name} blacklisted e-mail domain %{target}"
@@ -441,12 +445,6 @@ en:
last_delivery: Last delivery
title: WebSub
topic: Topic
- suspensions:
- bad_acct_msg: The confirmation value didn't match up. Are you suspending the right account?
- hint_html: 'To confirm the suspension of the account, please enter %{value} into the field below:'
- proceed: Proceed
- title: Suspend %{acct}
- warning_html: 'Suspending this account will irreversibly delete data from this account, which includes:'
tags:
accounts: Accounts
hidden: Hidden
@@ -456,6 +454,12 @@ en:
unhide: Show in directory
visible: Visible
title: Administration
+ warning_presets:
+ add_new: Add new
+ delete: Delete
+ edit: Edit
+ edit_preset: Edit warning preset
+ title: Manage warning presets
admin_mailer:
new_report:
body: "%{reporter} has reported %{target}"
@@ -922,6 +926,22 @@ en:
explanation: You requested a full backup of your Mastodon account. It's now ready for download!
subject: Your archive is ready for download
title: Archive takeout
+ warning:
+ explanation:
+ disable: While your account is frozen, your account data remains intact, but you cannot perform any actions until it is unlocked.
+ silence: While your account is limited, only people who are already following you will see your toots on this server, and you may be excluded from various public listings. However, others may still manually follow you.
+ suspend: Your account has been suspended, and all of your toots and your uploaded media files have been irreversibly removed from this server, and servers where you had followers.
+ review_server_policies: Review server policies
+ subject:
+ disable: Your account %{acct} has been frozen
+ none: Warning for %{acct}
+ silence: Your account %{acct} has been limited
+ suspend: Your account %{acct} has been suspended
+ title:
+ disable: Account frozen
+ none: Warning
+ silence: Account limited
+ suspend: Account suspended
welcome:
edit_profile_action: Setup profile
edit_profile_step: You can customize your profile by uploading an avatar, header, changing your display name and more. If you’d like to review new followers before they’re allowed to follow you, you can lock your account.
diff --git a/config/locales/eo.yml b/config/locales/eo.yml
index f944b2a19e..6a62f7021d 100644
--- a/config/locales/eo.yml
+++ b/config/locales/eo.yml
@@ -427,11 +427,6 @@ eo:
last_delivery: Lasta livero
title: WebSub
topic: Temo
- suspensions:
- hint_html: 'Por konformi la haltigo de la konto, bonvolu enigi %{value} en la kampo sube:'
- proceed: Daŭrigita
- title: Haltigi %{acct}
- warning_html: 'Haltigi ĉi tiu konton forigos senrevene datumojn de ĉi tiu konto, inklusive de:'
title: Administrado
admin_mailer:
new_report:
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 4cd1e2a380..8927c3b38e 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -433,12 +433,6 @@ es:
last_delivery: Última entrega
title: WebSub
topic: Tópico
- suspensions:
- bad_acct_msg: El valor de confirmación no cuadra. ¿Estás suspendiendo la cuenta correcta?
- hint_html: 'Para confirmar las suspensión de la cuenta, por favor introduce %{value} en el campo de abajo:'
- proceed: Proceder
- title: Suspender %{acct}
- warning_html: 'Suspender esta cuenta borrará irreversiblemente los datos de stra cuenta que incluyen:'
title: Administración
admin_mailer:
new_report:
diff --git a/config/locales/eu.yml b/config/locales/eu.yml
index c96438bc33..eb148c6a2c 100644
--- a/config/locales/eu.yml
+++ b/config/locales/eu.yml
@@ -435,12 +435,6 @@ eu:
last_delivery: Azken bidalketa
title: WebSub
topic: Mintzagaia
- suspensions:
- bad_acct_msg: Berrespen balioa ez dator bat. Dagokion kontua kanporatzen ari zara?
- hint_html: 'Kontuaren kanporatzea berresteko, sartu %{value} beheko eremuan:'
- proceed: Jarraitu
- title: Kanporatu %{acct}
- warning_html: 'Kontu hau kanporatzeak behin betiko ezabatuko ditu kontu honetako datuak, hauek barne:'
tags:
accounts: Kontuak
hidden: Ezkutatuta
diff --git a/config/locales/fa.yml b/config/locales/fa.yml
index 7802ca98d9..a87949183f 100644
--- a/config/locales/fa.yml
+++ b/config/locales/fa.yml
@@ -433,12 +433,6 @@ fa:
last_delivery: آخرین ارسال
title: WebSub
topic: موضوع
- suspensions:
- bad_acct_msg: محتوایی که برای تأیید وارد کردید منطبق نبود. آیا دارید حساب درستی را معلق میکنید؟
- hint_html: 'برای تأیید معلقکردن حساب، لطفاً در کادر زیر %{value} را وارد کنید:'
- proceed: ادامه
- title: معلقکردن %{acct}
- warning_html: 'معلقکردن این حساب برای همیشه دادههایش را پاک میکند. دادههایی شامل:'
title: مدیریت سرور
admin_mailer:
new_report:
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 3d33cd40c1..167c942ee0 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -439,12 +439,6 @@ fr:
last_delivery: Dernière livraison
title: WebSub
topic: Sujet
- suspensions:
- bad_acct_msg: La valeur de confirmation n'a pas correspondu. Êtes-vous certain de suspendre le bon compte ?
- hint_html: 'Pour confirmer la suspension du compte, veuillez entrer %{value} dans le champ ci-dessous :'
- proceed: Confirmer
- title: Suspension de %{acct}
- warning_html: 'Suspendre ce compte effacera irréversiblement les données de ce compte, ce qui inclut :'
tags:
accounts: Comptes
hidden: Masqué
diff --git a/config/locales/gl.yml b/config/locales/gl.yml
index de1557fb9b..b6830fb725 100644
--- a/config/locales/gl.yml
+++ b/config/locales/gl.yml
@@ -439,12 +439,6 @@ gl:
last_delivery: Última entrega
title: WebSub
topic: Asunto
- suspensions:
- bad_acct_msg: O valor de confirmación non é coincidente. Está a suspender a conta correcta?
- hint_html: 'Para confirmar a suspensión da conta introduza %{value} no campo inferior:'
- proceed: Proceder
- title: Suspender %{acct}
- warning_html: 'Ao suspender esta conta eliminará de xeito irreversible os datos de esta conta, que inclúe:'
tags:
accounts: Contas
hidden: Ocultas
diff --git a/config/locales/it.yml b/config/locales/it.yml
index dc62b1beaa..e9bf78cdff 100644
--- a/config/locales/it.yml
+++ b/config/locales/it.yml
@@ -429,12 +429,6 @@ it:
confirmed: Confermato
expires_in: Scade in
topic: Argomento
- suspensions:
- bad_acct_msg: Il valore di conferma non corrisponde. Stai sospendendo l'account giusto?
- hint_html: 'Per confermare la sospensione dell''account, inserisci %{value} nel campo qui sotto:'
- proceed: Continua
- title: Sospendi %{acct}
- warning_html: 'La sospensione dell''account comporta la cancellazione irreversibile dei suoi dati, che comprendono:'
title: Amministrazione
application_mailer:
notification_preferences: Cambia preferenze email
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index 038131a613..292acf52f6 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -441,12 +441,6 @@ ja:
last_delivery: 最終配送
title: WebSub
topic: トピック
- suspensions:
- bad_acct_msg: 値が一致しませんでした。停止しようとしているアカウントに間違いはありませんか?
- hint_html: 'アカウントの停止を確認するには、以下のフィールドに %{value} と入力してください:'
- proceed: 完全に活動停止させる
- title: "%{acct} を停止"
- warning_html: 'このアカウントを停止すると、このアカウントから次のようなデータが不可逆的に削除されます:'
tags:
accounts: アカウント
hidden: 非表示
diff --git a/config/locales/ko.yml b/config/locales/ko.yml
index 40dab2d79f..6bbc71e0be 100644
--- a/config/locales/ko.yml
+++ b/config/locales/ko.yml
@@ -441,12 +441,6 @@ ko:
last_delivery: 최종 발송
title: WebSub
topic: 토픽
- suspensions:
- bad_acct_msg: 확인값이 일치하지 않습니다. 정지하려는 계정이 맞습니까?
- hint_html: '이 계정을 정지하려면 %{value}를 아래 입력칸에 입력하세요:'
- proceed: 완전히 정지시키기
- title: "%{acct} 정지하기"
- warning_html: '이 계정을 정지하면 계정의 데이터를 모두 삭제하며 되돌릴 수 없습니다. 이것은 다음을 포함합니다:'
tags:
accounts: 계정들
hidden: 숨겨짐
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index d0578bc748..700217830c 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -439,12 +439,6 @@ nl:
last_delivery: Laatste bezorging
title: WebSub
topic: Account
- suspensions:
- bad_acct_msg: De bevestigingswaarde kwam niet overeen. Schort je wel het juiste account op?
- hint_html: Vul in het veld hieronder %{value} in, om het opschorten van dit account te bevestigen.
- proceed: Ga verder
- title: "%{acct} opschorten"
- warning_html: 'Door het opschorten van dit account worden gegevens van dit account permanent verwijderd, waaronder:'
tags:
accounts: Accounts
hidden: Verborgen
diff --git a/config/locales/oc.yml b/config/locales/oc.yml
index 0468fac869..e647e400cb 100644
--- a/config/locales/oc.yml
+++ b/config/locales/oc.yml
@@ -439,12 +439,6 @@ oc:
last_delivery: Darrièra distribucion
title: WebSub
topic: Subjècte
- suspensions:
- bad_acct_msg: La valor de confirmacion a pas coïncidit. Sètz a suspendre lo bon compte ?
- hint_html: 'Per confirmar la suspension del compte, picatz %{value} al camp çai-jos :'
- proceed: Tractat
- title: Suspension de %{acct}
- warning_html: 'Suspendre aqueste compte suprimirà irreversiblament las donadas del compte, aquò compren :'
tags:
accounts: Comptes
hidden: Amagat
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index 79ba6f9fb1..7fd5df038d 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -445,12 +445,6 @@ pl:
last_delivery: Ostatnio doręczono
title: WebSub
topic: Temat
- suspensions:
- bad_acct_msg: Zawartość potwierdzenia nie zgadza się. Czy próbujesz zawiesić właściwe konto?
- hint_html: 'Aby potwierdzić zawieszenie konta, wprowadź %{value} w poniższe pole:'
- proceed: Przejdź
- title: Zawieś %{acct}
- warning_html: 'Zawieszenie konta będzie skutkowało nieodwracalnym usunięciem danych z tego konta, wliczając:'
tags:
accounts: Konta
hidden: Ukryte
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index 27f3b820c9..e9625628b8 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -439,12 +439,6 @@ pt-BR:
last_delivery: Última entrega
title: WebSub
topic: Tópico
- suspensions:
- bad_acct_msg: Os valores de confirmação não correspondem. Você está suspendendo a conta certa?
- hint_html: 'Para confirmar a suspensão da conta, por favor digite %{value} no campo abaixo:'
- proceed: Prosseguir
- title: Suspender %{acct}
- warning_html: 'Suspender essa conta vai remover irreversivelmente dados dessa conta, o que inclui:'
tags:
accounts: Contas
hidden: Escondido
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index 9fa85b7c2f..dceb413763 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -427,12 +427,6 @@ ru:
last_delivery: Последняя доставка
title: WebSub
topic: Тема
- suspensions:
- bad_acct_msg: Не удалось найти такое число подтверждения. Вы уверены, что замораживаете нужный аккаунт?
- hint_html: 'Чтобы подтвердить заморозку аккаунта, пожалуйста, введите %{value} в поле ниже:'
- proceed: Продолжить
- title: Заморозить %{acct}
- warning_html: 'Заморозка этого аккаунта приведёт к необратимому удалению данных с этого аккаунта, включая:'
title: Администрирование
admin_mailer:
new_report:
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index ce6a62e870..4363c59e42 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -2,6 +2,13 @@
en:
simple_form:
hints:
+ account_warning_preset:
+ text: You can use toot syntax, such as URLs, hashtags and mentions
+ admin_account_action:
+ send_email_notification: The user will receive an explanation of what happened with their account
+ text_html: Optional. You can use toot syntax. You can add warning presets to save time
+ type_html: Choose what to do with %{acct}
+ warning_preset_id: Optional. You can still add custom text to end of the preset
defaults:
autofollow: People who sign up through the invite will automatically follow you
avatar: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px
@@ -40,6 +47,18 @@ en:
fields:
name: Label
value: Content
+ account_warning_preset:
+ text: Preset text
+ admin_account_action:
+ send_email_notification: Notify the user per e-mail
+ text: Custom warning
+ type: Action
+ types:
+ disable: Disable
+ none: Do nothing
+ silence: Silence
+ suspend: Suspend and irreversibly delete account data
+ warning_preset_id: Use a warning preset
defaults:
autofollow: Invite to follow your account
avatar: Avatar
diff --git a/config/locales/sk.yml b/config/locales/sk.yml
index 3458c699c9..f44d971a4e 100644
--- a/config/locales/sk.yml
+++ b/config/locales/sk.yml
@@ -444,12 +444,6 @@ sk:
last_delivery: Posledné doručenie
title: WebSub
topic: Téma
- suspensions:
- bad_acct_msg: Hodnota pre potvrdenie sa nezhoduje. Si si istý/á že zamrazuješ ten správny účet?
- hint_html: 'Pre potvrdenie zamrazenia účtu, prosím napíš %{value} do následujúceho políčka:'
- proceed: Pokračuj
- title: Zamraziť %{acct}
- warning_html: 'Zamrazením tohto účtu budú dáta na tomto účte nenávratne zmazané, zahŕňajúc:'
tags:
accounts: Účty
hidden: Skryté
diff --git a/config/locales/sr.yml b/config/locales/sr.yml
index da621a9103..8dee9fdac8 100644
--- a/config/locales/sr.yml
+++ b/config/locales/sr.yml
@@ -443,12 +443,6 @@ sr:
last_delivery: Последња достава
title: WebSub
topic: Topic
- suspensions:
- bad_acct_msg: Вредност потврде се не поклапа. Да ли суспендујете прави рачун?
- hint_html: 'Да бисте потврдили суспензију налога, унесите %{value} у поље испод:'
- proceed: Настави
- title: Суспендуј %{acct}
- warning_html: 'Суспендовање овог налога ће неповратноизбрисати све податке са овог налога, који укључују:'
title: Администрација
admin_mailer:
new_report:
diff --git a/config/routes.rb b/config/routes.rb
index 0aba433e29..7723a08af9 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -139,6 +139,7 @@ Rails.application.routes.draw do
resources :domain_blocks, only: [:index, :new, :create, :show, :destroy]
resources :email_domain_blocks, only: [:index, :new, :create, :destroy]
resources :action_logs, only: [:index]
+ resources :warning_presets, except: [:new]
resource :settings, only: [:edit, :update]
resources :invites, only: [:index, :create, :destroy] do
@@ -160,7 +161,14 @@ Rails.application.routes.draw do
end
end
- resources :reports, only: [:index, :show, :update] do
+ resources :reports, only: [:index, :show] do
+ member do
+ post :assign_to_self
+ post :unassign
+ post :reopen
+ post :resolve
+ end
+
resources :reported_statuses, only: [:create]
end
@@ -171,7 +179,8 @@ Rails.application.routes.draw do
post :subscribe
post :unsubscribe
post :enable
- post :disable
+ post :unsilence
+ post :unsuspend
post :redownload
post :remove_avatar
post :remove_header
@@ -180,8 +189,7 @@ Rails.application.routes.draw do
resource :change_email, only: [:show, :update]
resource :reset, only: [:create]
- resource :silence, only: [:create, :destroy]
- resource :suspension, only: [:new, :create, :destroy]
+ resource :action, only: [:new, :create], controller: 'account_actions'
resources :statuses, only: [:index, :create, :update, :destroy]
resource :confirmation, only: [:create] do
diff --git a/db/migrate/20181213184704_create_account_warnings.rb b/db/migrate/20181213184704_create_account_warnings.rb
new file mode 100644
index 0000000000..e768be2778
--- /dev/null
+++ b/db/migrate/20181213184704_create_account_warnings.rb
@@ -0,0 +1,12 @@
+class CreateAccountWarnings < ActiveRecord::Migration[5.2]
+ def change
+ create_table :account_warnings do |t|
+ t.belongs_to :account, foreign_key: { on_delete: :nullify }
+ t.belongs_to :target_account, foreign_key: { to_table: 'accounts', on_delete: :cascade }
+ t.integer :action, null: false, default: 0
+ t.text :text, null: false, default: ''
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20181213185533_create_account_warning_presets.rb b/db/migrate/20181213185533_create_account_warning_presets.rb
new file mode 100644
index 0000000000..9c81f1b5e6
--- /dev/null
+++ b/db/migrate/20181213185533_create_account_warning_presets.rb
@@ -0,0 +1,9 @@
+class CreateAccountWarningPresets < ActiveRecord::Migration[5.2]
+ def change
+ create_table :account_warning_presets do |t|
+ t.text :text, null: false, default: ''
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 51ac43e1d4..51a7b5e749 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2018_12_07_011115) do
+ActiveRecord::Schema.define(version: 2018_12_13_185533) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -76,6 +76,23 @@ ActiveRecord::Schema.define(version: 2018_12_07_011115) do
t.index ["tag_id"], name: "index_account_tag_stats_on_tag_id", unique: true
end
+ create_table "account_warning_presets", force: :cascade do |t|
+ t.text "text", default: "", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
+ create_table "account_warnings", force: :cascade do |t|
+ t.bigint "account_id"
+ t.bigint "target_account_id"
+ t.integer "action", default: 0, null: false
+ t.text "text", default: "", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["account_id"], name: "index_account_warnings_on_account_id"
+ t.index ["target_account_id"], name: "index_account_warnings_on_target_account_id"
+ end
+
create_table "accounts", force: :cascade do |t|
t.string "username", default: "", null: false
t.string "domain"
@@ -656,6 +673,8 @@ ActiveRecord::Schema.define(version: 2018_12_07_011115) do
add_foreign_key "account_pins", "accounts", on_delete: :cascade
add_foreign_key "account_stats", "accounts", on_delete: :cascade
add_foreign_key "account_tag_stats", "tags", on_delete: :cascade
+ add_foreign_key "account_warnings", "accounts", column: "target_account_id", on_delete: :cascade
+ add_foreign_key "account_warnings", "accounts", on_delete: :nullify
add_foreign_key "accounts", "accounts", column: "moved_to_account_id", on_delete: :nullify
add_foreign_key "admin_action_logs", "accounts", on_delete: :cascade
add_foreign_key "backups", "users", on_delete: :nullify
diff --git a/spec/controllers/admin/accounts_controller_spec.rb b/spec/controllers/admin/accounts_controller_spec.rb
index dbcad3c2d2..a348ab3d75 100644
--- a/spec/controllers/admin/accounts_controller_spec.rb
+++ b/spec/controllers/admin/accounts_controller_spec.rb
@@ -191,58 +191,6 @@ RSpec.describe Admin::AccountsController, type: :controller do
end
end
- describe 'POST #disable' do
- subject { post :disable, params: { id: account.id } }
-
- let(:current_user) { Fabricate(:user, admin: current_user_admin) }
- let(:account) { Fabricate(:account, user: user) }
- let(:user) { Fabricate(:user, disabled: false, admin: target_user_admin) }
-
- context 'when user is admin' do
- let(:current_user_admin) { true }
-
- context 'when target user is admin' do
- let(:target_user_admin) { true }
-
- it 'fails to disable account' do
- is_expected.to have_http_status :forbidden
- expect(user.reload).not_to be_disabled
- end
- end
-
- context 'when target user is not admin' do
- let(:target_user_admin) { false }
-
- it 'succeeds in disabling account' do
- is_expected.to redirect_to admin_account_path(account.id)
- expect(user.reload).to be_disabled
- end
- end
- end
-
- context 'when user is not admin' do
- let(:current_user_admin) { false }
-
- context 'when target user is admin' do
- let(:target_user_admin) { true }
-
- it 'fails to disable account' do
- is_expected.to have_http_status :forbidden
- expect(user.reload).not_to be_disabled
- end
- end
-
- context 'when target user is not admin' do
- let(:target_user_admin) { false }
-
- it 'fails to disable account' do
- is_expected.to have_http_status :forbidden
- expect(user.reload).not_to be_disabled
- end
- end
- end
- end
-
describe 'POST #redownload' do
subject { post :redownload, params: { id: account.id } }
diff --git a/spec/controllers/admin/reports_controller_spec.rb b/spec/controllers/admin/reports_controller_spec.rb
index bcc789c578..b428299eeb 100644
--- a/spec/controllers/admin/reports_controller_spec.rb
+++ b/spec/controllers/admin/reports_controller_spec.rb
@@ -46,73 +46,37 @@ describe Admin::ReportsController do
end
end
- describe 'PUT #update' do
- describe 'with an unknown outcome' do
- it 'rejects the change' do
- report = Fabricate(:report)
- put :update, params: { id: report, outcome: 'unknown' }
+ describe 'POST #reopen' do
+ it 'reopens the report' do
+ report = Fabricate(:report)
- expect(response).to have_http_status(404)
- end
+ put :reopen, params: { id: report }
+ expect(response).to redirect_to(admin_report_path(report))
+ report.reload
+ expect(report.action_taken_by_account).to eq nil
+ expect(report.action_taken).to eq false
end
+ end
- describe 'with an outcome of `resolve`' do
- it 'resolves the report' do
- report = Fabricate(:report)
+ describe 'POST #assign_to_self' do
+ it 'reopens the report' do
+ report = Fabricate(:report)
- put :update, params: { id: report, outcome: 'resolve' }
- expect(response).to redirect_to(admin_reports_path)
- report.reload
- expect(report.action_taken_by_account).to eq user.account
- expect(report.action_taken).to eq true
- end
+ put :assign_to_self, params: { id: report }
+ expect(response).to redirect_to(admin_report_path(report))
+ report.reload
+ expect(report.assigned_account).to eq user.account
end
+ end
- describe 'with an outsome of `silence`' do
- it 'silences the reported account' do
- report = Fabricate(:report)
+ describe 'POST #unassign' do
+ it 'reopens the report' do
+ report = Fabricate(:report)
- put :update, params: { id: report, outcome: 'silence' }
- expect(response).to redirect_to(admin_reports_path)
- report.reload
- expect(report.action_taken_by_account).to eq user.account
- expect(report.action_taken).to eq true
- expect(report.target_account).to be_silenced
- end
- end
-
- describe 'with an outsome of `reopen`' do
- it 'reopens the report' do
- report = Fabricate(:report)
-
- put :update, params: { id: report, outcome: 'reopen' }
- expect(response).to redirect_to(admin_report_path(report))
- report.reload
- expect(report.action_taken_by_account).to eq nil
- expect(report.action_taken).to eq false
- end
- end
-
- describe 'with an outsome of `assign_to_self`' do
- it 'reopens the report' do
- report = Fabricate(:report)
-
- put :update, params: { id: report, outcome: 'assign_to_self' }
- expect(response).to redirect_to(admin_report_path(report))
- report.reload
- expect(report.assigned_account).to eq user.account
- end
- end
-
- describe 'with an outsome of `unassign`' do
- it 'reopens the report' do
- report = Fabricate(:report)
-
- put :update, params: { id: report, outcome: 'unassign' }
- expect(response).to redirect_to(admin_report_path(report))
- report.reload
- expect(report.assigned_account).to eq nil
- end
+ put :unassign, params: { id: report }
+ expect(response).to redirect_to(admin_report_path(report))
+ report.reload
+ expect(report.assigned_account).to eq nil
end
end
end
diff --git a/spec/controllers/admin/silences_controller_spec.rb b/spec/controllers/admin/silences_controller_spec.rb
deleted file mode 100644
index 78560eb393..0000000000
--- a/spec/controllers/admin/silences_controller_spec.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-require 'rails_helper'
-
-describe Admin::SilencesController do
- render_views
-
- before do
- sign_in Fabricate(:user, admin: true), scope: :user
- end
-
- describe 'POST #create' do
- it 'redirects to admin accounts page' do
- account = Fabricate(:account, silenced: false)
-
- post :create, params: { account_id: account.id }
-
- account.reload
- expect(account.silenced?).to eq true
- expect(response).to redirect_to(admin_accounts_path)
- end
- end
-
- describe 'DELETE #destroy' do
- it 'redirects to admin accounts page' do
- account = Fabricate(:account, silenced: true)
-
- delete :destroy, params: { account_id: account.id }
-
- account.reload
- expect(account.silenced?).to eq false
- expect(response).to redirect_to(admin_accounts_path)
- end
- end
-end
diff --git a/spec/controllers/admin/suspensions_controller_spec.rb b/spec/controllers/admin/suspensions_controller_spec.rb
deleted file mode 100644
index 1bc33e4901..0000000000
--- a/spec/controllers/admin/suspensions_controller_spec.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-require 'rails_helper'
-
-describe Admin::SuspensionsController do
- render_views
-
- before do
- sign_in Fabricate(:user, admin: true), scope: :user
- end
-
- describe 'GET #new' do
- it 'returns 200' do
- get :new, params: { account_id: Fabricate(:account).id, report_id: Fabricate(:report).id }
- expect(response).to have_http_status(200)
- end
- end
-
- describe 'POST #create' do
- it 'redirects to admin accounts page' do
- account = Fabricate(:account, suspended: false)
- expect(Admin::SuspensionWorker).to receive(:perform_async).with(account.id)
-
- post :create, params: { account_id: account.id, form_admin_suspension_confirmation: { acct: account.acct } }
-
- expect(response).to redirect_to(admin_accounts_path)
- end
- end
-
- describe 'DELETE #destroy' do
- it 'redirects to admin accounts page' do
- account = Fabricate(:account, suspended: true)
-
- delete :destroy, params: { account_id: account.id }
-
- account.reload
- expect(account.suspended?).to eq false
- expect(response).to redirect_to(admin_accounts_path)
- end
- end
-end
diff --git a/spec/fabricators/account_warning_fabricator.rb b/spec/fabricators/account_warning_fabricator.rb
new file mode 100644
index 0000000000..db161d4464
--- /dev/null
+++ b/spec/fabricators/account_warning_fabricator.rb
@@ -0,0 +1,5 @@
+Fabricator(:account_warning) do
+ account nil
+ target_account nil
+ text "MyText"
+end
diff --git a/spec/fabricators/account_warning_preset_fabricator.rb b/spec/fabricators/account_warning_preset_fabricator.rb
new file mode 100644
index 0000000000..6c0b87e7cd
--- /dev/null
+++ b/spec/fabricators/account_warning_preset_fabricator.rb
@@ -0,0 +1,3 @@
+Fabricator(:account_warning_preset) do
+ text "MyText"
+end
diff --git a/spec/mailers/previews/user_mailer_preview.rb b/spec/mailers/previews/user_mailer_preview.rb
index d9cdb9264a..53c8364944 100644
--- a/spec/mailers/previews/user_mailer_preview.rb
+++ b/spec/mailers/previews/user_mailer_preview.rb
@@ -39,4 +39,9 @@ class UserMailerPreview < ActionMailer::Preview
def backup_ready
UserMailer.backup_ready(User.first, Backup.first)
end
+
+ # Preview this email at http://localhost:3000/rails/mailers/user_mailer/warning
+ def warning
+ UserMailer.warning(User.first, AccountWarning.new(text: '', action: :silence))
+ end
end
diff --git a/spec/models/account_warning_preset_spec.rb b/spec/models/account_warning_preset_spec.rb
new file mode 100644
index 0000000000..a859a305fe
--- /dev/null
+++ b/spec/models/account_warning_preset_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe AccountWarningPreset, type: :model do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/models/account_warning_spec.rb b/spec/models/account_warning_spec.rb
new file mode 100644
index 0000000000..5286f9177e
--- /dev/null
+++ b/spec/models/account_warning_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe AccountWarning, type: :model do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/models/admin/account_action_spec.rb b/spec/models/admin/account_action_spec.rb
new file mode 100644
index 0000000000..8c55cf4ddf
--- /dev/null
+++ b/spec/models/admin/account_action_spec.rb
@@ -0,0 +1,4 @@
+require 'rails_helper'
+
+RSpec.describe Admin::AccountAction, type: :model do
+end