Account deletion (#3728)
* Add form for account deletion * If avatar or header are gone from source, remove them * Add option to have SuspendAccountService remove user record, add tests * Exclude suspended accounts from search
This commit is contained in:
parent
a208e7d655
commit
4a618908e8
15 changed files with 183 additions and 7 deletions
27
app/controllers/settings/deletes_controller.rb
Normal file
27
app/controllers/settings/deletes_controller.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Settings::DeletesController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
|
||||
def show
|
||||
@confirmation = Form::DeleteConfirmation.new
|
||||
end
|
||||
|
||||
def destroy
|
||||
if current_user.valid_password?(delete_params[:password])
|
||||
Admin::SuspensionWorker.perform_async(current_user.account_id, true)
|
||||
sign_out
|
||||
redirect_to new_user_session_path, notice: I18n.t('deletes.success_msg')
|
||||
else
|
||||
redirect_to settings_delete_path, alert: I18n.t('deletes.bad_password_msg')
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def delete_params
|
||||
params.permit(:password)
|
||||
end
|
||||
end
|
|
@ -96,6 +96,13 @@
|
|||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 16px;
|
||||
color: $ui-primary-color;
|
||||
line-height: 28px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
& > p {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
|
@ -114,6 +121,14 @@
|
|||
background: transparent;
|
||||
border-bottom: 1px solid $ui-base-color;
|
||||
}
|
||||
|
||||
.muted-hint {
|
||||
color: lighten($ui-base-color, 27%);
|
||||
|
||||
a {
|
||||
color: $ui-primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.simple_form {
|
||||
|
|
|
@ -303,7 +303,10 @@ code {
|
|||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.simple_form,
|
||||
.table-form {
|
||||
.warning {
|
||||
max-width: 400px;
|
||||
box-sizing: border-box;
|
||||
|
|
|
@ -177,6 +177,7 @@ class Account < ApplicationRecord
|
|||
account_id IN (SELECT * FROM first_degree)
|
||||
AND target_account_id NOT IN (SELECT * FROM first_degree)
|
||||
AND target_account_id NOT IN (:excluded_account_ids)
|
||||
AND accounts.suspended = false
|
||||
GROUP BY target_account_id, accounts.id
|
||||
ORDER BY count(account_id) DESC
|
||||
OFFSET :offset
|
||||
|
@ -199,6 +200,7 @@ class Account < ApplicationRecord
|
|||
ts_rank_cd(#{textsearch}, #{query}, 32) AS rank
|
||||
FROM accounts
|
||||
WHERE #{query} @@ #{textsearch}
|
||||
AND accounts.suspended = false
|
||||
ORDER BY rank DESC
|
||||
LIMIT ?
|
||||
SQL
|
||||
|
@ -216,6 +218,7 @@ class Account < ApplicationRecord
|
|||
FROM accounts
|
||||
LEFT OUTER JOIN follows AS f ON (accounts.id = f.account_id AND f.target_account_id = ?) OR (accounts.id = f.target_account_id AND f.account_id = ?)
|
||||
WHERE #{query} @@ #{textsearch}
|
||||
AND accounts.suspended = false
|
||||
GROUP BY accounts.id
|
||||
ORDER BY rank DESC
|
||||
LIMIT ?
|
||||
|
|
7
app/models/form/delete_confirmation.rb
Normal file
7
app/models/form/delete_confirmation.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Form::DeleteConfirmation
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :password
|
||||
end
|
|
@ -1,9 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SuspendAccountService < BaseService
|
||||
def call(account)
|
||||
def call(account, remove_user = false)
|
||||
@account = account
|
||||
|
||||
purge_user if remove_user
|
||||
purge_content
|
||||
purge_profile
|
||||
unsubscribe_push_subscribers
|
||||
|
@ -11,6 +12,10 @@ class SuspendAccountService < BaseService
|
|||
|
||||
private
|
||||
|
||||
def purge_user
|
||||
@account.user.destroy
|
||||
end
|
||||
|
||||
def purge_content
|
||||
@account.statuses.reorder(nil).find_each do |status|
|
||||
# This federates out deletes to previous followers
|
||||
|
|
|
@ -27,8 +27,19 @@ class UpdateRemoteProfileService < BaseService
|
|||
account.locked = remote_profile.locked?
|
||||
|
||||
if !account.suspended? && !DomainBlock.find_by(domain: account.domain)&.reject_media?
|
||||
account.avatar_remote_url = remote_profile.avatar if remote_profile.avatar.present?
|
||||
account.header_remote_url = remote_profile.header if remote_profile.header.present?
|
||||
if remote_profile.avatar.present?
|
||||
account.avatar_remote_url = remote_profile.avatar
|
||||
else
|
||||
account.avatar_remote_url = ''
|
||||
account.avatar.destroy
|
||||
end
|
||||
|
||||
if remote_profile.header.present?
|
||||
account.header_remote_url = remote_profile.header
|
||||
else
|
||||
account.header_remote_url = ''
|
||||
account.header.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,3 +11,8 @@
|
|||
|
||||
.actions
|
||||
= f.button :button, t('generic.save_changes'), type: :submit
|
||||
|
||||
%hr/
|
||||
|
||||
%h6= t('auth.delete_account')
|
||||
%p.muted-hint= t('auth.delete_account_html', path: settings_delete_path)
|
||||
|
|
16
app/views/settings/deletes/show.html.haml
Normal file
16
app/views/settings/deletes/show.html.haml
Normal file
|
@ -0,0 +1,16 @@
|
|||
- content_for :page_title do
|
||||
= t('settings.delete')
|
||||
|
||||
= simple_form_for @confirmation, url: settings_delete_path, method: :delete do |f|
|
||||
.warning
|
||||
%strong
|
||||
= fa_icon('warning')
|
||||
= t('deletes.warning_title')
|
||||
= t('deletes.warning_html')
|
||||
|
||||
%p.hint= t('deletes.description_html')
|
||||
|
||||
= f.input :password, autocomplete: 'off', placeholder: t('simple_form.labels.defaults.current_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.current_password') }, hint: t('deletes.confirm_password')
|
||||
|
||||
.actions
|
||||
= f.button :button, t('deletes.proceed'), type: :submit, class: 'negative'
|
|
@ -5,7 +5,7 @@ class Admin::SuspensionWorker
|
|||
|
||||
sidekiq_options queue: 'pull'
|
||||
|
||||
def perform(account_id)
|
||||
SuspendAccountService.new.call(Account.find(account_id))
|
||||
def perform(account_id, remove_user = false)
|
||||
SuspendAccountService.new.call(Account.find(account_id), remove_user)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue