--- /dev/null
+# 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
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
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?
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
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
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
-
- if @report.action_taken?
- redirect_to admin_reports_path, notice: I18n.t('admin.reports.resolved_msg')
- else
- redirect_to admin_report_path(@report)
- end
+ @report.update!(assigned_account_id: current_account.id)
+ log_action :assigned_to_self, @report
+ redirect_to admin_report_path(@report)
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
+ def unassign
+ authorize @report, :update?
+ @report.update!(assigned_account_id: nil)
+ log_action :unassigned, @report
+ redirect_to admin_report_path(@report)
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)
+ def reopen
+ authorize @report, :update?
+ @report.unresolve!
+ log_action :reopen, @report
+ redirect_to admin_report_path(@report)
end
- def unresolved_reports_for_target_account
- Report.where(
- target_account: @report.target_account
- ).unresolved
+ 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 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
+++ /dev/null
-# 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
+++ /dev/null
-# 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
--- /dev/null
+# 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
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
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
'envelope'
when 'Status'
'pencil'
+ when 'AccountWarning'
+ 'warning'
end
end
private
def opposite_verbs?(log)
- %w(DomainBlock EmailDomainBlock).include?(log.target_type)
+ %w(DomainBlock EmailDomainBlock AccountWarning).include?(log.target_type)
end
end
--- /dev/null
+<svg fill="#FFFFFF" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <path d="M0 0h24v24H0z" fill="none"/>
+ <path d="M14.4 6L14 4H5v17h2v-7h5.6l.4 2h7V6z"/>
+</svg>
background: $success-green;
}
+ &.alert-icon td {
+ background: $error-red;
+ }
+
img {
max-width: 32px;
width: 32px;
border-left-color: lighten($error-red, 12%);
}
+ &.warning {
+ border-left-color: $gold-star;
+ }
+
&__bubble {
padding: 16px;
padding-left: 14px;
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
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?
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
# 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
+++ /dev/null
-# frozen_string_literal: true
-
-class Form::AdminSuspensionConfirmation
- include ActiveModel::Model
-
- attr_accessor :acct, :report_id
-end
staff?
end
+ def warn?
+ staff? && !record.user&.staff?
+ end
+
def suspend?
staff? && !record.user&.staff?
end
--- /dev/null
+# frozen_string_literal: true
+
+class AccountWarningPresetPolicy < ApplicationPolicy
+ def index?
+ staff?
+ end
+
+ def create?
+ staff?
+ end
+
+ def update?
+ staff?
+ end
+
+ def destroy?
+ staff?
+ end
+end
--- /dev/null
+- 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
--- /dev/null
+.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
= 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
%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/
%hr.spacer/
+= render @warnings
+
+%hr.spacer/
+
= render @moderation_notes
= simple_form_for @account_moderation_note, url: admin_account_moderation_notes_path do |f|
- 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
= 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
- @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|
+++ /dev/null
-- 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'
--- /dev/null
+- 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
--- /dev/null
+- 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') }
--- /dev/null
+%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'
--- /dev/null
+<%= t "user_mailer.warning.title.#{@warning.action}" %>
+
+===
+
+<% unless @warning.none_action? %>
+<%= t "user_mailer.warning.explanation.#{@warning.action}" %>
+
+<% end %>
+<%= @warning.text %>
===
-<%= 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 %>
---
last_delivery: آخر إيداع
title: WebSub
topic: الموضوع
- suspensions:
- bad_acct_msg: قيمة التأكيد غير متطابقة. متأكد مِن أنك بصدد تعليق الحساب الصحيح؟
- hint_html: 'لتأكيد إجراء تعليق الحساب، يُرجى إدخال %{value} في الحقل التالي:'
- proceed: مواصلة
- title: تعليق الحساب %{acct}
tags:
accounts: الحسابات
hidden: المخفية
failed_to_execute: Fallu al executar
subscriptions:
title: WebSub
- suspensions:
- warning_html: 'El suspender esta cuenta va desaniciar <strong>de mou irreversible</strong> los sos datos qu''inclúin:'
title: Alministración
admin_mailer:
new_report:
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à <strong>irreversiblement</strong> les dades del compte, incloent:'
tags:
accounts: Comptes
hidden: Amagat
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 <strong>irreversibile</strong> i so dati, cum''è:'
tags:
accounts: Conti
hidden: Piattatu
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 <strong>nenávratně</strong> smaže z tohoto účtu data, včetně:'
tags:
accounts: Účty
hidden: Skryté
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 <strong>am byth</strong> o''r cyfrif hwn, gan gynnwys:'
title: Gweinyddiaeth
admin_mailer:
new_report:
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 <strong>uigenkaldeligt</strong> slette al data fra denne konto, hvilket indebærer:'
title: Administration
admin_mailer:
new_report:
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 <strong>unwiederrufliche</strong> Schäden hervorrufen und alle Daten löschen, die folgendes beinhalten:'
tags:
accounts: Konten
hidden: Versteckt
last_delivery: Τελευταία παράδοση
title: WebSub
topic: Θέμα
- suspensions:
- bad_acct_msg: Η τιμή επιβεβαίωσης δεν ταιριάζει. Σίγουρα αναστέλλεις το σωστό λογαριασμό;
- hint_html: 'Για να επιβεβαιώσεις την αναστολή του λογαριασμού, γράψε %{value} στο ακόλουθο πεδίο:'
- proceed: Συνέχεια
- title: Αναστολή %{acct}
- warning_html: 'Αναστέλλοντας αυτό το λογαριασμό θα διαγραφούν <strong>αμετάκλητα</strong> δεδομένα του, μεταξύ των οποίων:'
tags:
accounts: Λογαριασμοί
hidden: Κρυμμένες
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!
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}"
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 <strong>irreversibly</strong> delete data from this account, which includes:'
tags:
accounts: Accounts
hidden: Hidden
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}"
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.
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 <strong>senrevene</strong> datumojn de ĉi tiu konto, inklusive de:'
title: Administrado
admin_mailer:
new_report:
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á <strong>irreversiblemente</strong> los datos de stra cuenta que incluyen:'
title: Administración
admin_mailer:
new_report:
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 <strong>behin betiko</strong> ezabatuko ditu kontu honetako datuak, hauek barne:'
tags:
accounts: Kontuak
hidden: Ezkutatuta
last_delivery: آخرین ارسال
title: WebSub
topic: موضوع
- suspensions:
- bad_acct_msg: محتوایی که برای تأیید وارد کردید منطبق نبود. آیا دارید حساب درستی را معلق میکنید؟
- hint_html: 'برای تأیید معلقکردن حساب، لطفاً در کادر زیر %{value} را وارد کنید:'
- proceed: ادامه
- title: معلقکردن %{acct}
- warning_html: 'معلقکردن این حساب <strong>برای همیشه</strong> دادههایش را پاک میکند. دادههایی شامل:'
title: مدیریت سرور
admin_mailer:
new_report:
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 <strong>irréversiblement</strong> les données de ce compte, ce qui inclut :'
tags:
accounts: Comptes
hidden: Masqué
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á <strong>de xeito irreversible</strong> os datos de esta conta, que inclúe:'
tags:
accounts: Contas
hidden: Ocultas
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 <strong>irreversibile</strong> dei suoi dati, che comprendono:'
title: Amministrazione
application_mailer:
notification_preferences: Cambia preferenze email
last_delivery: 最終配送
title: WebSub
topic: トピック
- suspensions:
- bad_acct_msg: 値が一致しませんでした。停止しようとしているアカウントに間違いはありませんか?
- hint_html: 'アカウントの停止を確認するには、以下のフィールドに %{value} と入力してください:'
- proceed: 完全に活動停止させる
- title: "%{acct} を停止"
- warning_html: 'このアカウントを停止すると、このアカウントから次のようなデータが<strong>不可逆的に</strong>削除されます:'
tags:
accounts: アカウント
hidden: 非表示
last_delivery: 최종 발송
title: WebSub
topic: 토픽
- suspensions:
- bad_acct_msg: 확인값이 일치하지 않습니다. 정지하려는 계정이 맞습니까?
- hint_html: '이 계정을 정지하려면 %{value}를 아래 입력칸에 입력하세요:'
- proceed: 완전히 정지시키기
- title: "%{acct} 정지하기"
- warning_html: '이 계정을 정지하면 계정의 데이터를 모두 삭제하며 <strong>되돌릴 수 없습니다</strong>. 이것은 다음을 포함합니다:'
tags:
accounts: 계정들
hidden: 숨겨짐
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 <strong>permanent</strong> verwijderd, waaronder:'
tags:
accounts: Accounts
hidden: Verborgen
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à <strong>irreversiblament</strong> las donadas del compte, aquò compren :'
tags:
accounts: Comptes
hidden: Amagat
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 <strong>nieodwracalnym</strong> usunięciem danych z tego konta, wliczając:'
tags:
accounts: Konta
hidden: Ukryte
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 <strong>irreversivelmente</strong> dados dessa conta, o que inclui:'
tags:
accounts: Contas
hidden: Escondido
last_delivery: Последняя доставка
title: WebSub
topic: Тема
- suspensions:
- bad_acct_msg: Не удалось найти такое число подтверждения. Вы уверены, что замораживаете нужный аккаунт?
- hint_html: 'Чтобы подтвердить заморозку аккаунта, пожалуйста, введите %{value} в поле ниже:'
- proceed: Продолжить
- title: Заморозить %{acct}
- warning_html: 'Заморозка этого аккаунта приведёт к <strong>необратимому</strong> удалению данных с этого аккаунта, включая:'
title: Администрирование
admin_mailer:
new_report:
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 <a href="%{path}">add warning presets</a> to save time
+ type_html: Choose what to do with <strong>%{acct}</strong>
+ 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
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
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 <strong>nenávratne</strong> zmazané, zahŕňajúc:'
tags:
accounts: Účty
hidden: Skryté
last_delivery: Последња достава
title: WebSub
topic: Topic
- suspensions:
- bad_acct_msg: Вредност потврде се не поклапа. Да ли суспендујете прави рачун?
- hint_html: 'Да бисте потврдили суспензију налога, унесите %{value} у поље испод:'
- proceed: Настави
- title: Суспендуј %{acct}
- warning_html: 'Суспендовање овог налога ће <strong>неповратно</strong>избрисати све податке са овог налога, који укључују:'
title: Администрација
admin_mailer:
new_report:
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
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
post :subscribe
post :unsubscribe
post :enable
- post :disable
+ post :unsilence
+ post :unsuspend
post :redownload
post :remove_avatar
post :remove_header
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
--- /dev/null
+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
--- /dev/null
+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
#
# 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"
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"
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
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 } }
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' }
-
- expect(response).to have_http_status(404)
- end
- end
-
- describe 'with an outcome of `resolve`' do
- it 'resolves 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
- end
-
- describe 'with an outsome of `silence`' do
- it 'silences the reported account' 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)
+ describe 'POST #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
+ 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 outsome of `assign_to_self`' do
- it 'reopens 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: 'assign_to_self' }
- expect(response).to redirect_to(admin_report_path(report))
- report.reload
- expect(report.assigned_account).to eq user.account
- 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 `unassign`' do
- it 'reopens the report' do
- report = Fabricate(:report)
+ describe 'POST #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
+++ /dev/null
-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
+++ /dev/null
-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
--- /dev/null
+Fabricator(:account_warning) do
+ account nil
+ target_account nil
+ text "MyText"
+end
--- /dev/null
+Fabricator(:account_warning_preset) do
+ text "MyText"
+end
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
--- /dev/null
+require 'rails_helper'
+
+RSpec.describe AccountWarningPreset, type: :model do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
--- /dev/null
+require 'rails_helper'
+
+RSpec.describe AccountWarning, type: :model do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
--- /dev/null
+require 'rails_helper'
+
+RSpec.describe Admin::AccountAction, type: :model do
+end