mirror of
https://github.com/mastodon/mastodon.git
synced 2024-12-22 17:35:40 +01:00
Revert severed relationships feature
This commit is contained in:
parent
f3acc08ac6
commit
dec6ef7363
49 changed files with 5 additions and 810 deletions
|
@ -1,61 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SeveredRelationshipsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :set_body_classes
|
||||
before_action :set_cache_headers
|
||||
|
||||
before_action :set_event, only: [:following, :followers]
|
||||
|
||||
def index
|
||||
@events = AccountRelationshipSeveranceEvent.where(account: current_account)
|
||||
end
|
||||
|
||||
def following
|
||||
respond_to do |format|
|
||||
format.csv { send_data following_data, filename: "following-#{@event.target_name}-#{@event.created_at.to_date.iso8601}.csv" }
|
||||
end
|
||||
end
|
||||
|
||||
def followers
|
||||
respond_to do |format|
|
||||
format.csv { send_data followers_data, filename: "followers-#{@event.target_name}-#{@event.created_at.to_date.iso8601}.csv" }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_event
|
||||
@event = AccountRelationshipSeveranceEvent.find(params[:id])
|
||||
end
|
||||
|
||||
def following_data
|
||||
CSV.generate(headers: ['Account address', 'Show boosts', 'Notify on new posts', 'Languages'], write_headers: true) do |csv|
|
||||
@event.severed_relationships.active.about_local_account(current_account).includes(:remote_account).reorder(id: :desc).each do |follow|
|
||||
csv << [acct(follow.target_account), follow.show_reblogs, follow.notify, follow.languages&.join(', ')]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def followers_data
|
||||
CSV.generate(headers: ['Account address'], write_headers: true) do |csv|
|
||||
@event.severed_relationships.passive.about_local_account(current_account).includes(:remote_account).reorder(id: :desc).each do |follow|
|
||||
csv << [acct(follow.account)]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def acct(account)
|
||||
account.local? ? account.local_username_and_domain : account.acct
|
||||
end
|
||||
|
||||
def set_body_classes
|
||||
@body_classes = 'admin'
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
|
@ -14,7 +14,6 @@ import EditIcon from '@/material-icons/400-24px/edit.svg?react';
|
|||
import FlagIcon from '@/material-icons/400-24px/flag-fill.svg?react';
|
||||
import HomeIcon from '@/material-icons/400-24px/home-fill.svg?react';
|
||||
import InsertChartIcon from '@/material-icons/400-24px/insert_chart.svg?react';
|
||||
import LinkOffIcon from '@/material-icons/400-24px/link_off.svg?react';
|
||||
import PersonIcon from '@/material-icons/400-24px/person-fill.svg?react';
|
||||
import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react';
|
||||
import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react';
|
||||
|
@ -27,7 +26,6 @@ import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
|||
|
||||
import FollowRequestContainer from '../containers/follow_request_container';
|
||||
|
||||
import RelationshipsSeveranceEvent from './relationships_severance_event';
|
||||
import Report from './report';
|
||||
|
||||
const messages = defineMessages({
|
||||
|
@ -360,30 +358,6 @@ class Notification extends ImmutablePureComponent {
|
|||
);
|
||||
}
|
||||
|
||||
renderRelationshipsSevered (notification) {
|
||||
const { intl, unread } = this.props;
|
||||
|
||||
if (!notification.get('event')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<HotKeys handlers={this.getHandlers()}>
|
||||
<div className={classNames('notification notification-severed-relationships focusable', { unread })} tabIndex={0} aria-label={notificationForScreenReader(intl, intl.formatMessage(messages.adminReport, { name: notification.getIn(['event', 'target_name']) }), notification.get('created_at'))}>
|
||||
<div className='notification__message'>
|
||||
<Icon id='unlink' icon={LinkOffIcon} />
|
||||
|
||||
<span title={notification.get('created_at')}>
|
||||
<FormattedMessage id='notification.severed_relationships' defaultMessage='Relationships with {name} severed' values={{ name: notification.getIn(['event', 'target_name']) }} />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<RelationshipsSeveranceEvent event={notification.get('event')} />
|
||||
</div>
|
||||
</HotKeys>
|
||||
);
|
||||
}
|
||||
|
||||
renderAdminSignUp (notification, account, link) {
|
||||
const { intl, unread } = this.props;
|
||||
|
||||
|
@ -455,8 +429,6 @@ class Notification extends ImmutablePureComponent {
|
|||
return this.renderUpdate(notification, link);
|
||||
case 'poll':
|
||||
return this.renderPoll(notification, account);
|
||||
case 'severed_relationships':
|
||||
return this.renderRelationshipsSevered(notification);
|
||||
case 'admin.sign_up':
|
||||
return this.renderAdminSignUp(notification, account, link);
|
||||
case 'admin.report':
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
|
||||
import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
|
||||
|
||||
// This needs to be kept in sync with app/models/relationship_severance_event.rb
|
||||
const messages = defineMessages({
|
||||
account_suspension: { id: 'relationship_severance_notification.types.account_suspension', defaultMessage: 'Account has been suspended' },
|
||||
domain_block: { id: 'relationship_severance_notification.types.domain_block', defaultMessage: 'Domain has been suspended' },
|
||||
user_domain_block: { id: 'relationship_severance_notification.types.user_domain_block', defaultMessage: 'You blocked this domain' },
|
||||
});
|
||||
|
||||
const RelationshipsSeveranceEvent = ({ event, hidden }) => {
|
||||
const intl = useIntl();
|
||||
|
||||
if (hidden || !event) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='notification__report'>
|
||||
<div className='notification__report__details'>
|
||||
<div>
|
||||
<RelativeTimestamp timestamp={event.get('created_at')} short={false} />
|
||||
{' · '}
|
||||
{ event.get('purged') ? (
|
||||
<FormattedMessage
|
||||
id='relationship_severance_notification.purged_data'
|
||||
defaultMessage='purged by administrators'
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id='relationship_severance_notification.relationships'
|
||||
defaultMessage='{count, plural, one {# relationship} other {# relationships}}'
|
||||
values={{ count: event.get('relationships_count', 0) }}
|
||||
/>
|
||||
)}
|
||||
<br />
|
||||
<strong>{intl.formatMessage(messages[event.get('type')])}</strong>
|
||||
</div>
|
||||
|
||||
<div className='notification__report__actions'>
|
||||
<a href='/severed_relationships' className='button' target='_blank' rel='noopener noreferrer'>
|
||||
<FormattedMessage id='relationship_severance_notification.view' defaultMessage='View' />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
RelationshipsSeveranceEvent.propTypes = {
|
||||
event: ImmutablePropTypes.map.isRequired,
|
||||
hidden: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default RelationshipsSeveranceEvent;
|
|
@ -471,7 +471,6 @@
|
|||
"notification.own_poll": "Your poll has ended",
|
||||
"notification.poll": "A poll you have voted in has ended",
|
||||
"notification.reblog": "{name} boosted your post",
|
||||
"notification.severed_relationships": "Relationships with {name} severed",
|
||||
"notification.status": "{name} just posted",
|
||||
"notification.update": "{name} edited a post",
|
||||
"notification_requests.accept": "Accept",
|
||||
|
@ -588,12 +587,6 @@
|
|||
"refresh": "Refresh",
|
||||
"regeneration_indicator.label": "Loading…",
|
||||
"regeneration_indicator.sublabel": "Your home feed is being prepared!",
|
||||
"relationship_severance_notification.purged_data": "purged by administrators",
|
||||
"relationship_severance_notification.relationships": "{count, plural, one {# relationship} other {# relationships}}",
|
||||
"relationship_severance_notification.types.account_suspension": "Account has been suspended",
|
||||
"relationship_severance_notification.types.domain_block": "Domain has been suspended",
|
||||
"relationship_severance_notification.types.user_domain_block": "You blocked this domain",
|
||||
"relationship_severance_notification.view": "View",
|
||||
"relative_time.days": "{number}d",
|
||||
"relative_time.full.days": "{number, plural, one {# day} other {# days}} ago",
|
||||
"relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago",
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
#
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: account_relationship_severance_events
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# account_id :bigint(8) not null
|
||||
# relationship_severance_event_id :bigint(8) not null
|
||||
# relationships_count :integer default(0), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
class AccountRelationshipSeveranceEvent < ApplicationRecord
|
||||
belongs_to :account
|
||||
belongs_to :relationship_severance_event
|
||||
|
||||
delegate :severed_relationships,
|
||||
:type,
|
||||
:target_name,
|
||||
:purged,
|
||||
:purged?,
|
||||
to: :relationship_severance_event,
|
||||
prefix: false
|
||||
|
||||
before_create :set_relationships_count!
|
||||
|
||||
private
|
||||
|
||||
def set_relationships_count!
|
||||
self.relationships_count = severed_relationships.about_local_account(account).count
|
||||
end
|
||||
end
|
|
@ -83,11 +83,6 @@ module Account::Interactions
|
|||
has_many :following, -> { order('follows.id desc') }, through: :active_relationships, source: :target_account
|
||||
has_many :followers, -> { order('follows.id desc') }, through: :passive_relationships, source: :account
|
||||
|
||||
with_options class_name: 'SeveredRelationship', dependent: :destroy do
|
||||
has_many :severed_relationships, foreign_key: 'local_account_id', inverse_of: :local_account
|
||||
has_many :remote_severed_relationships, foreign_key: 'remote_account_id', inverse_of: :remote_account
|
||||
end
|
||||
|
||||
# Account notes
|
||||
has_many :account_notes, dependent: :destroy
|
||||
|
||||
|
|
|
@ -48,18 +48,6 @@ module Account::Merging
|
|||
record.update_attribute(:account_warning_id, id)
|
||||
end
|
||||
|
||||
SeveredRelationship.about_local_account(other_account).reorder(nil).find_each do |record|
|
||||
record.update_attribute(:local_account_id, id)
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
next
|
||||
end
|
||||
|
||||
SeveredRelationship.about_remote_account(other_account).reorder(nil).find_each do |record|
|
||||
record.update_attribute(:remote_account_id, id)
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
next
|
||||
end
|
||||
|
||||
# Some follow relationships have moved, so the cache is stale
|
||||
Rails.cache.delete_matched("followers_hash:#{id}:*")
|
||||
Rails.cache.delete_matched("relationships:#{id}:*")
|
||||
|
|
|
@ -54,9 +54,6 @@ class Notification < ApplicationRecord
|
|||
update: {
|
||||
filterable: false,
|
||||
}.freeze,
|
||||
severed_relationships: {
|
||||
filterable: false,
|
||||
}.freeze,
|
||||
'admin.sign_up': {
|
||||
filterable: false,
|
||||
}.freeze,
|
||||
|
@ -89,7 +86,6 @@ class Notification < ApplicationRecord
|
|||
belongs_to :favourite, inverse_of: :notification
|
||||
belongs_to :poll, inverse_of: false
|
||||
belongs_to :report, inverse_of: false
|
||||
belongs_to :account_relationship_severance_event, inverse_of: false
|
||||
end
|
||||
|
||||
validates :type, inclusion: { in: TYPES }
|
||||
|
@ -186,11 +182,6 @@ class Notification < ApplicationRecord
|
|||
self.from_account_id = activity&.status&.account_id
|
||||
when 'Account'
|
||||
self.from_account_id = activity&.id
|
||||
when 'AccountRelationshipSeveranceEvent'
|
||||
# These do not really have an originating account, but this is mandatory
|
||||
# in the data model, and the recipient's account will by definition
|
||||
# always exist
|
||||
self.from_account_id = account_id
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: relationship_severance_events
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# type :integer not null
|
||||
# target_name :string not null
|
||||
# purged :boolean default(FALSE), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
class RelationshipSeveranceEvent < ApplicationRecord
|
||||
self.inheritance_column = nil
|
||||
|
||||
has_many :severed_relationships, inverse_of: :relationship_severance_event, dependent: :delete_all
|
||||
|
||||
enum :type, {
|
||||
domain_block: 0,
|
||||
user_domain_block: 1,
|
||||
account_suspension: 2,
|
||||
}
|
||||
|
||||
scope :about_local_account, ->(account) { where(id: SeveredRelationship.about_local_account(account).select(:relationship_severance_event_id)) }
|
||||
|
||||
def import_from_active_follows!(follows)
|
||||
import_from_follows!(follows, true)
|
||||
end
|
||||
|
||||
def import_from_passive_follows!(follows)
|
||||
import_from_follows!(follows, false)
|
||||
end
|
||||
|
||||
def affected_local_accounts
|
||||
Account.where(id: severed_relationships.select(:local_account_id))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def import_from_follows!(follows, active)
|
||||
SeveredRelationship.insert_all(
|
||||
follows.pluck(:account_id, :target_account_id, :show_reblogs, :notify, :languages).map do |account_id, target_account_id, show_reblogs, notify, languages|
|
||||
{
|
||||
local_account_id: active ? account_id : target_account_id,
|
||||
remote_account_id: active ? target_account_id : account_id,
|
||||
show_reblogs: show_reblogs,
|
||||
notify: notify,
|
||||
languages: languages,
|
||||
relationship_severance_event_id: id,
|
||||
direction: active ? :active : :passive,
|
||||
}
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
|
@ -1,41 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: severed_relationships
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# relationship_severance_event_id :bigint(8) not null
|
||||
# local_account_id :bigint(8) not null
|
||||
# remote_account_id :bigint(8) not null
|
||||
# direction :integer not null
|
||||
# show_reblogs :boolean
|
||||
# notify :boolean
|
||||
# languages :string is an Array
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
class SeveredRelationship < ApplicationRecord
|
||||
belongs_to :relationship_severance_event
|
||||
belongs_to :local_account, class_name: 'Account'
|
||||
belongs_to :remote_account, class_name: 'Account'
|
||||
|
||||
enum :direction, {
|
||||
passive: 0, # analogous to `local_account.passive_relationships`
|
||||
active: 1, # analogous to `local_account.active_relationships`
|
||||
}
|
||||
|
||||
scope :about_local_account, ->(account) { where(local_account: account) }
|
||||
scope :about_remote_account, ->(account) { where(remote_account: account) }
|
||||
|
||||
scope :active, -> { where(direction: :active) }
|
||||
scope :passive, -> { where(direction: :passive) }
|
||||
|
||||
def account
|
||||
active? ? local_account : remote_account
|
||||
end
|
||||
|
||||
def target_account
|
||||
active? ? remote_account : local_account
|
||||
end
|
||||
end
|
|
@ -1,9 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class REST::AccountRelationshipSeveranceEventSerializer < ActiveModel::Serializer
|
||||
attributes :id, :type, :purged, :target_name, :created_at
|
||||
|
||||
def id
|
||||
object.id.to_s
|
||||
end
|
||||
end
|
|
@ -6,7 +6,6 @@ class REST::NotificationSerializer < ActiveModel::Serializer
|
|||
belongs_to :from_account, key: :account, serializer: REST::AccountSerializer
|
||||
belongs_to :target_status, key: :status, if: :status_type?, serializer: REST::StatusSerializer
|
||||
belongs_to :report, if: :report_type?, serializer: REST::ReportSerializer
|
||||
belongs_to :account_relationship_severance_event, key: :event, if: :relationship_severance_event?, serializer: REST::AccountRelationshipSeveranceEventSerializer
|
||||
|
||||
def id
|
||||
object.id.to_s
|
||||
|
@ -19,8 +18,4 @@ class REST::NotificationSerializer < ActiveModel::Serializer
|
|||
def report_type?
|
||||
object.type == :'admin.report'
|
||||
end
|
||||
|
||||
def relationship_severance_event?
|
||||
object.type == :severed_relationships
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,20 +9,17 @@ class AfterBlockDomainFromAccountService < BaseService
|
|||
def call(account, domain)
|
||||
@account = account
|
||||
@domain = domain
|
||||
@domain_block_event = nil
|
||||
|
||||
clear_notifications!
|
||||
remove_follows!
|
||||
reject_existing_followers!
|
||||
reject_pending_follow_requests!
|
||||
notify_of_severed_relationships!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def remove_follows!
|
||||
@account.active_relationships.where(target_account: Account.where(domain: @domain)).includes(:target_account).reorder(nil).in_batches do |follows|
|
||||
domain_block_event.import_from_active_follows!(follows)
|
||||
follows.each { |follow| UnfollowService.new.call(@account, follow.target_account) }
|
||||
end
|
||||
end
|
||||
|
@ -33,7 +30,6 @@ class AfterBlockDomainFromAccountService < BaseService
|
|||
|
||||
def reject_existing_followers!
|
||||
@account.passive_relationships.where(account: Account.where(domain: @domain)).includes(:account).reorder(nil).in_batches do |follows|
|
||||
domain_block_event.import_from_passive_follows!(follows)
|
||||
follows.each { |follow| reject_follow!(follow) }
|
||||
end
|
||||
end
|
||||
|
@ -51,15 +47,4 @@ class AfterBlockDomainFromAccountService < BaseService
|
|||
|
||||
ActivityPub::DeliveryWorker.perform_async(Oj.dump(serialize_payload(follow, ActivityPub::RejectFollowSerializer)), @account.id, follow.account.inbox_url)
|
||||
end
|
||||
|
||||
def notify_of_severed_relationships!
|
||||
return if @domain_block_event.nil?
|
||||
|
||||
event = AccountRelationshipSeveranceEvent.create!(account: @account, relationship_severance_event: @domain_block_event)
|
||||
LocalNotificationWorker.perform_async(@account.id, event.id, 'AccountRelationshipSeveranceEvent', 'severed_relationships')
|
||||
end
|
||||
|
||||
def domain_block_event
|
||||
@domain_block_event ||= RelationshipSeveranceEvent.create!(type: :user_domain_block, target_name: @domain)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,6 @@ class BlockDomainService < BaseService
|
|||
|
||||
process_domain_block!
|
||||
process_retroactive_updates! if update
|
||||
notify_of_severed_relationships!
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -40,17 +39,7 @@ class BlockDomainService < BaseService
|
|||
blocked_domain_accounts.without_suspended.in_batches.update_all(suspended_at: @domain_block.created_at, suspension_origin: :local)
|
||||
|
||||
blocked_domain_accounts.where(suspended_at: @domain_block.created_at).reorder(nil).find_each do |account|
|
||||
DeleteAccountService.new.call(account, reserve_username: true, suspended_at: @domain_block.created_at, relationship_severance_event: domain_block_event)
|
||||
end
|
||||
end
|
||||
|
||||
def notify_of_severed_relationships!
|
||||
return if @domain_block_event.nil?
|
||||
|
||||
# TODO: check how efficient that query is, also check `push_bulk`/`perform_bulk`
|
||||
@domain_block_event.affected_local_accounts.reorder(nil).find_each do |account|
|
||||
event = AccountRelationshipSeveranceEvent.create!(account: account, relationship_severance_event: @domain_block_event)
|
||||
LocalNotificationWorker.perform_async(account.id, event.id, 'AccountRelationshipSeveranceEvent', 'severed_relationships')
|
||||
DeleteAccountService.new.call(account, reserve_username: true, suspended_at: @domain_block.created_at)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -58,10 +47,6 @@ class BlockDomainService < BaseService
|
|||
domain_block.domain
|
||||
end
|
||||
|
||||
def domain_block_event
|
||||
@domain_block_event ||= RelationshipSeveranceEvent.create!(type: :domain_block, target_name: blocked_domain)
|
||||
end
|
||||
|
||||
def blocked_domain_accounts
|
||||
Account.by_domain_and_subdomains(blocked_domain)
|
||||
end
|
||||
|
|
|
@ -58,8 +58,6 @@ class DeleteAccountService < BaseService
|
|||
reports
|
||||
targeted_moderation_notes
|
||||
targeted_reports
|
||||
severed_relationships
|
||||
remote_severed_relationships
|
||||
).freeze
|
||||
|
||||
# Suspend or remove an account and remove as much of its data
|
||||
|
@ -74,7 +72,6 @@ class DeleteAccountService < BaseService
|
|||
# @option [Boolean] :skip_side_effects Side effects are ActivityPub and streaming API payloads
|
||||
# @option [Boolean] :skip_activitypub Skip sending ActivityPub payloads. Implied by :skip_side_effects
|
||||
# @option [Time] :suspended_at Only applicable when :reserve_username is true
|
||||
# @option [RelationshipSeveranceEvent] :relationship_severance_event Event used to record severed relationships not initiated by the user
|
||||
def call(account, **options)
|
||||
@account = account
|
||||
@options = { reserve_username: true, reserve_email: true }.merge(options)
|
||||
|
@ -87,7 +84,6 @@ class DeleteAccountService < BaseService
|
|||
|
||||
@options[:skip_activitypub] = true if @options[:skip_side_effects]
|
||||
|
||||
record_severed_relationships!
|
||||
distribute_activities!
|
||||
purge_content!
|
||||
fulfill_deletion_request!
|
||||
|
@ -270,20 +266,6 @@ class DeleteAccountService < BaseService
|
|||
end
|
||||
end
|
||||
|
||||
def record_severed_relationships!
|
||||
return if relationship_severance_event.nil?
|
||||
|
||||
@account.active_relationships.in_batches do |follows|
|
||||
# NOTE: these follows are passive with regards to the local accounts
|
||||
relationship_severance_event.import_from_passive_follows!(follows)
|
||||
end
|
||||
|
||||
@account.passive_relationships.in_batches do |follows|
|
||||
# NOTE: these follows are active with regards to the local accounts
|
||||
relationship_severance_event.import_from_active_follows!(follows)
|
||||
end
|
||||
end
|
||||
|
||||
def delete_actor_json
|
||||
@delete_actor_json ||= Oj.dump(serialize_payload(@account, ActivityPub::DeleteActorSerializer, signer: @account, always_sign: true))
|
||||
end
|
||||
|
@ -323,8 +305,4 @@ class DeleteAccountService < BaseService
|
|||
def skip_activitypub?
|
||||
@options[:skip_activitypub]
|
||||
end
|
||||
|
||||
def relationship_severance_event
|
||||
@options[:relationship_severance_event]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,8 +9,6 @@ class NotifyService < BaseService
|
|||
update
|
||||
poll
|
||||
status
|
||||
# TODO: this probably warrants an email notification
|
||||
severed_relationships
|
||||
).freeze
|
||||
|
||||
class DismissCondition
|
||||
|
@ -22,7 +20,7 @@ class NotifyService < BaseService
|
|||
|
||||
def dismiss?
|
||||
blocked = @recipient.unavailable?
|
||||
blocked ||= from_self? && @notification.type != :poll && @notification.type != :severed_relationships
|
||||
blocked ||= from_self? && @notification.type != :poll
|
||||
|
||||
return blocked if message? && from_staff?
|
||||
|
||||
|
|
|
@ -4,17 +4,12 @@ class PurgeDomainService < BaseService
|
|||
def call(domain)
|
||||
@domain = domain
|
||||
|
||||
purge_relationship_severance_events!
|
||||
purge_accounts!
|
||||
purge_emojis!
|
||||
|
||||
Instance.refresh
|
||||
end
|
||||
|
||||
def purge_relationship_severance_events!
|
||||
RelationshipSeveranceEvent.where(type: [:domain_block, :user_domain_block], target_name: @domain).in_batches.update_all(purged: true)
|
||||
end
|
||||
|
||||
def purge_accounts!
|
||||
Account.remote.where(domain: @domain).reorder(nil).find_each do |account|
|
||||
DeleteAccountService.new.call(account, reserve_username: false, skip_side_effects: true)
|
||||
|
|
|
@ -8,7 +8,6 @@ class SuspendAccountService < BaseService
|
|||
def call(account)
|
||||
return unless account.suspended?
|
||||
|
||||
@relationship_severance_event = nil
|
||||
@account = account
|
||||
|
||||
reject_remote_follows!
|
||||
|
@ -16,7 +15,6 @@ class SuspendAccountService < BaseService
|
|||
unmerge_from_home_timelines!
|
||||
unmerge_from_list_timelines!
|
||||
privatize_media_attachments!
|
||||
notify_of_severed_relationships!
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -38,8 +36,6 @@ class SuspendAccountService < BaseService
|
|||
[Oj.dump(serialize_payload(follow, ActivityPub::RejectFollowSerializer)), follow.target_account_id, @account.inbox_url]
|
||||
end
|
||||
|
||||
relationship_severance_event.import_from_passive_follows!(follows)
|
||||
|
||||
follows.each(&:destroy)
|
||||
end
|
||||
end
|
||||
|
@ -105,21 +101,7 @@ class SuspendAccountService < BaseService
|
|||
end
|
||||
end
|
||||
|
||||
def notify_of_severed_relationships!
|
||||
return if @relationship_severance_event.nil?
|
||||
|
||||
# TODO: check how efficient that query is, also check `push_bulk`/`perform_bulk`
|
||||
@relationship_severance_event.affected_local_accounts.reorder(nil).find_each do |account|
|
||||
event = AccountRelationshipSeveranceEvent.create!(account: account, relationship_severance_event: @relationship_severance_event)
|
||||
LocalNotificationWorker.perform_async(account.id, event.id, 'AccountRelationshipSeveranceEvent', 'severed_relationships')
|
||||
end
|
||||
end
|
||||
|
||||
def signed_activity_json
|
||||
@signed_activity_json ||= Oj.dump(serialize_payload(@account, ActivityPub::UpdateSerializer, signer: @account))
|
||||
end
|
||||
|
||||
def relationship_severance_event
|
||||
@relationship_severance_event ||= RelationshipSeveranceEvent.create!(type: :account_suspension, target_name: @account.acct)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
- content_for :page_title do
|
||||
= t('settings.severed_relationships')
|
||||
|
||||
%p.muted-hint= t('severed_relationships.preamble')
|
||||
|
||||
- unless @events.empty?
|
||||
.table-wrapper
|
||||
%table.table
|
||||
%thead
|
||||
%tr
|
||||
%th= t('exports.archive_takeout.date')
|
||||
%th= t('severed_relationships.type')
|
||||
%th= t('severed_relationships.lost_follows')
|
||||
%th= t('severed_relationships.lost_followers')
|
||||
%tbody
|
||||
- @events.each do |event|
|
||||
%tr
|
||||
%td= l event.created_at
|
||||
%td= t("severed_relationships.event_type.#{event.type}", target_name: event.target_name)
|
||||
- if event.purged?
|
||||
%td{ rowspan: 2 }= t('severed_relationships.purged')
|
||||
- else
|
||||
%td
|
||||
- count = event.severed_relationships.active.about_local_account(current_account).count
|
||||
- if count.zero?
|
||||
= t('generic.none')
|
||||
- else
|
||||
= table_link_to 'download', t('severed_relationships.download', count: count), following_severed_relationship_path(event, format: :csv)
|
||||
%td
|
||||
- count = event.severed_relationships.passive.about_local_account(current_account).count
|
||||
- if count.zero?
|
||||
= t('generic.none')
|
||||
- else
|
||||
= table_link_to 'download', t('severed_relationships.download', count: count), followers_severed_relationship_path(event, format: :csv)
|
|
@ -1664,17 +1664,6 @@ bg:
|
|||
strikes: Модериране на предупреждения
|
||||
two_factor_authentication: Двустепенно удостоверяване
|
||||
webauthn_authentication: Ключове за сигурност
|
||||
severed_relationships:
|
||||
download: Изтегляне (%{count})
|
||||
event_type:
|
||||
account_suspension: Спиране на акаунта (%{target_name})
|
||||
domain_block: Спиране на сървъра (%{target_name})
|
||||
user_domain_block: Блокирахте %{target_name}
|
||||
lost_followers: Загубени последователи
|
||||
lost_follows: Загубени последвания
|
||||
preamble: Може да загубите последванията и последователите, блокирайки домейн или когато модераторите ви решават да спрат отдалечен сървър. Случавайки се това, вие ще може да изтеглите списъците с прекъснати връзки, които да се проверят и възможно да се внесат на друг сървър.
|
||||
purged: Сведенията за този сървър са били прочистени от администраторите на сървъра ви.
|
||||
type: Събитие
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1664,17 +1664,6 @@ ca:
|
|||
strikes: Accions de mediació
|
||||
two_factor_authentication: Autenticació de dos factors
|
||||
webauthn_authentication: Claus de seguretat
|
||||
severed_relationships:
|
||||
download: Baixa (%{count})
|
||||
event_type:
|
||||
account_suspension: Suspensió del compte (%{target_name})
|
||||
domain_block: Suspensió del servidor (%{target_name})
|
||||
user_domain_block: Heu blocat %{target_name}
|
||||
lost_followers: Seguidors perduts
|
||||
lost_follows: Seguiments perduts
|
||||
preamble: Quan bloqueu un domini o els vostres moderadors decideixen suspendre un servidor remot, es poden perdre seguidors i seguiments. Si això passa, podeu baixar-vos la llista de relacions trencades per a revisar-la i, si voleu, importar-les a un altre servidor.
|
||||
purged: Els administradors del vostre servidor han purgat la informació relativa a aquest servidor.
|
||||
type: Esdeveniment
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1664,16 +1664,6 @@ da:
|
|||
strikes: Moderationsadvarsler
|
||||
two_factor_authentication: Tofaktorgodkendelse
|
||||
webauthn_authentication: Sikkerhedsnøgler
|
||||
severed_relationships:
|
||||
download: Download (%{count})
|
||||
event_type:
|
||||
account_suspension: Kontosuspendering (%{target_name})
|
||||
domain_block: Serversuspendering (%{target_name})
|
||||
user_domain_block: "%{target_name} blev blokeret"
|
||||
lost_followers: Tabte følgere
|
||||
preamble: Der kan mistes fulgte objekter og følgere, når et domæne blokeres eller moderatorerne beslutter at suspendere en ekstern server. Når det sker, kan der downloades lister over afbrudte relationer til inspektion og mulig import på anden server.
|
||||
purged: Oplysninger om denne server er blevet renset af serveradministratoreren.
|
||||
type: Begivenhed
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1665,17 +1665,6 @@ en:
|
|||
strikes: Moderation strikes
|
||||
two_factor_authentication: Two-factor Auth
|
||||
webauthn_authentication: Security keys
|
||||
severed_relationships:
|
||||
download: Download (%{count})
|
||||
event_type:
|
||||
account_suspension: Account suspension (%{target_name})
|
||||
domain_block: Server suspension (%{target_name})
|
||||
user_domain_block: You blocked %{target_name}
|
||||
lost_followers: Lost followers
|
||||
lost_follows: Lost follows
|
||||
preamble: You may lose follows and followers when you block a domain or when your moderators decide to suspend a remote server. When that happens, you will be able to download lists of severed relationships, to be inspected and possibly imported on another server.
|
||||
purged: Information about this server has been purged by your server's administrators.
|
||||
type: Event
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1668,17 +1668,6 @@ eu:
|
|||
strikes: Moderazio neurriak
|
||||
two_factor_authentication: Bi faktoreetako autentifikazioa
|
||||
webauthn_authentication: Segurtasun gakoak
|
||||
severed_relationships:
|
||||
download: Deskargatu (%{count})
|
||||
event_type:
|
||||
account_suspension: Kontua bertan behera uztea (%{target_name})
|
||||
domain_block: Domeinua bertan behera uztea (%{target_name})
|
||||
user_domain_block: "%{target_name} blokeatu duzu"
|
||||
lost_followers: Galdutako jarraitzaileak
|
||||
lost_follows: Jarraitzeari utzi diozun jendea
|
||||
preamble: Jarraitzaileak gal ditzakezu, baita jendea jarraitzeari utzi domeinu bat blokeatzen duzunean edo moderatzaileek urruneko zerbitzari bat bertan behera uztea erabakitzen badute. Hau gertatzean, galdutako erlazioen zerrendak deskargatu ahalko dituzu, aztertzeko eta agian, beste zerbitzari batean inportatzeko.
|
||||
purged: Zerbitzari honen informazioa kendu du zerbitzariko administratzaileak.
|
||||
type: Gertaera
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1664,17 +1664,6 @@ fi:
|
|||
strikes: Valvontavaroitukset
|
||||
two_factor_authentication: Kaksivaiheinen todennus
|
||||
webauthn_authentication: Suojausavaimet
|
||||
severed_relationships:
|
||||
download: Lataa (%{count})
|
||||
event_type:
|
||||
account_suspension: Tilin jäädytys (%{target_name})
|
||||
domain_block: Palvelimen jäädytys (%{target_name})
|
||||
user_domain_block: Estit käyttäjän %{target_name}
|
||||
lost_followers: Menetetyt seuraajat
|
||||
lost_follows: Menetetyt seuratut
|
||||
preamble: Voit menettää seurattusi ja seuraajasi, kun estät verkkotunnuksen tai kun valvojasi päättävät jäädyttää etäpalvelimen. Kun näin tapahtuu, voit ladata luetteloita katkenneista suhteista, jotta voit tarkastella niitä ja mahdollisesti viedä ne toiselle palvelimelle.
|
||||
purged: Palvelimesi ylläpitäjät ovat tyhjentäneet tämän palvelimen tiedot.
|
||||
type: Tapahtuma
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1664,17 +1664,6 @@ fo:
|
|||
strikes: Umsjónaratsóknir
|
||||
two_factor_authentication: Váttan í tveimum stigum
|
||||
webauthn_authentication: Trygdarlyklar
|
||||
severed_relationships:
|
||||
download: Niðurtøkur (%{count})
|
||||
event_type:
|
||||
account_suspension: Kontuógilding (%{target_name})
|
||||
domain_block: Ambætara-ógilding (%{target_name})
|
||||
user_domain_block: Tú hevur forðað %{target_name}
|
||||
lost_followers: Mistir fylgjarar
|
||||
lost_follows: Mist fylgi
|
||||
preamble: Tá ið tú forðar einum økisnavni, ella tínir umsitarar velja at avgilda ein fjarambætara, kanst tú missa fylgi og fylgjarar. Um tað hendir, kanst tú taka ein lista av avbrotnum tilknýtum niður, sum tú kanst eftirhyggja og møguliga innflyta á ein nýggjan ambætara.
|
||||
purged: Umsitararnir fyri tín ambætara hava tømt upplýsingar um henda ambætara úr skipanini.
|
||||
type: Tiltak
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1716,16 +1716,6 @@ gd:
|
|||
strikes: Rabhaidhean na maorsainneachd
|
||||
two_factor_authentication: Dearbhadh dà-cheumnach
|
||||
webauthn_authentication: Iuchraichean tèarainteachd
|
||||
severed_relationships:
|
||||
download: Luchdaich a-nuas (%{count})
|
||||
event_type:
|
||||
account_suspension: Cunntas à rèim (%{target_name})
|
||||
domain_block: Frithealaiche à rèim (%{target_name})
|
||||
user_domain_block: Bhac thu %{target_name}
|
||||
lost_followers: An luchd-leantainn a chaill thu
|
||||
lost_follows: Daoine nach lean thu tuilleadh
|
||||
purged: Chaidh am fiosrachadh mun fhrithealaiche seo a phurgaideachadh le rianairean an fhrithealaiche agad.
|
||||
type: Tachartas
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1664,17 +1664,6 @@ hu:
|
|||
strikes: Moderációs felrótt vétségek
|
||||
two_factor_authentication: Kétlépcsős hitelesítés
|
||||
webauthn_authentication: Biztonsági kulcsok
|
||||
severed_relationships:
|
||||
download: Letöltés (%{count})
|
||||
event_type:
|
||||
account_suspension: Fiók felfüggesztése (%{target_name})
|
||||
domain_block: Kiszolgáló felfüggesztése (%{target_name})
|
||||
user_domain_block: 'Blokkoltad ezt: %{target_name}'
|
||||
lost_followers: Elvesztett követők
|
||||
lost_follows: Elvesztett követések
|
||||
preamble: Ha blokkolsz egy domaint, vagy ha a moderátorok úgy döntenek, hogy blokkolnak egy távoli kiszolgálót, akkor követőket és követéseket veszíthetsz. Amikor ez megtörténik, akkor letöltheted a megszakadt kapcsolatokat, hogy átvizsgáld őket, és esetleg egy másik kiszolgálón importáld őket.
|
||||
purged: A kiszolgáló információit a kiszolgálód rendszergazdái véglegesen eltávolították.
|
||||
type: Esemény
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1640,17 +1640,6 @@ ko:
|
|||
strikes: 중재 기록
|
||||
two_factor_authentication: 2단계 인증
|
||||
webauthn_authentication: 보안 키
|
||||
severed_relationships:
|
||||
download: 다운로드 (%{count})
|
||||
event_type:
|
||||
account_suspension: 계정 정지 (%{target_name})
|
||||
domain_block: 서버 정지 (%{target_name})
|
||||
user_domain_block: 내가 %{target_name}을 차단했습니다
|
||||
lost_followers: 잃은 팔로워
|
||||
lost_follows: 잃은 팔로우
|
||||
preamble: 내가 도메인을 차단하거나 중재진이 다른 서버를 정지하기로 결정했다면 내 팔로우와 팔로워를 잃게 됩니다. 그런 일이 일어났다면 그로 인해 단절된 관계들의 목록을 다운로드 받아 확인하고 다른 서버에서 불러올 수 있습니다.
|
||||
purged: 이 서버에 대한 정보는 관리자에 의해 삭제되었습니다.
|
||||
type: 이벤트
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1663,9 +1663,6 @@ lad:
|
|||
strikes: Amonestamientos de moderasyon
|
||||
two_factor_authentication: Autentifikasyon en dos pasos
|
||||
webauthn_authentication: Yaves de sigurita
|
||||
severed_relationships:
|
||||
download: Abasha (%{count})
|
||||
type: Evenimiento
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1664,17 +1664,6 @@ nl:
|
|||
strikes: Vastgestelde overtredingen
|
||||
two_factor_authentication: Tweestapsverificatie
|
||||
webauthn_authentication: Beveiligingssleutels
|
||||
severed_relationships:
|
||||
download: Downloaden (%{count})
|
||||
event_type:
|
||||
account_suspension: Accountschorsing (%{target_name})
|
||||
domain_block: Serverschorsing (%{target_name})
|
||||
user_domain_block: Je hebt %{target_name} geblokkeerd
|
||||
lost_followers: Verloren volgers
|
||||
lost_follows: Verloren gevolgde accounts
|
||||
preamble: Je kan gevolgde accounts en volgers verliezen wanneer je een domein blokkeert of wanneer de moderators van jouw server beslissen om een externe server op te schorten. Wanneer dat gebeurt, kun je lijsten van verbroken volgrelaties downloaden, deze inspecteren en mogelijk importeren op een andere server.
|
||||
purged: Informatie over deze server is verwijderd door de beheerders van jouw server.
|
||||
type: Gebeurtenis
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1664,17 +1664,6 @@ nn:
|
|||
strikes: Modereringsadvarsler
|
||||
two_factor_authentication: Tostegsautorisering
|
||||
webauthn_authentication: Sikkerhetsnøkler
|
||||
severed_relationships:
|
||||
download: Last ned (%{count})
|
||||
event_type:
|
||||
account_suspension: Utestenging av konto (%{target_name})
|
||||
domain_block: Tenarutestenging (%{target_name})
|
||||
user_domain_block: Du blokkerte %{target_name}
|
||||
lost_followers: Mista fylgjarar
|
||||
lost_follows: Mista fylgjer
|
||||
preamble: Du kan mista fylgjarar og folk du fylgjer når du blokkerer eit domene eller når moderatorar avgjer å utestenga ein annan tenar. Når det skjer, vil du kunne lasta ned ei liste over brotne forhold, slik at du kan sjå gjennom ho og kanskje importera ho på ein annan tenar.
|
||||
purged: Informasjonen om denne tenaren er sletta av administratorane på tenaren din.
|
||||
type: Hending
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1716,17 +1716,6 @@ pl:
|
|||
strikes: Ostrzeżenia moderacyjne
|
||||
two_factor_authentication: Uwierzytelnianie dwuetapowe
|
||||
webauthn_authentication: Klucze bezpieczeństwa
|
||||
severed_relationships:
|
||||
download: Pobierz (%{count})
|
||||
event_type:
|
||||
account_suspension: Zawieszenie konta (%{target_name})
|
||||
domain_block: Zawieszenie serwera (%{target_name})
|
||||
user_domain_block: Zablokowano %{target_name}
|
||||
lost_followers: Utraceni obserwujący
|
||||
lost_follows: Utracone obserwowania
|
||||
preamble: Możesz stracić obserwowania i obserwujących kiedy zablokujesz domenę albo kiedy twoi moderatorzy postanowią zawiesić obcy serwer. W tym wypadku będziesz móc pobrać listę zerwanych związków do przejrzenia i potencjalnego importu na innym serwerze.
|
||||
purged: Informacje o tym serwerze zostały wyczyszczone przez administratora twojego serwera.
|
||||
type: Zdarzenie
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1199,9 +1199,6 @@ sk:
|
|||
profile: Profil
|
||||
relationships: Sledovania a následovatelia
|
||||
two_factor_authentication: Dvojfázové overenie
|
||||
severed_relationships:
|
||||
lost_followers: Stratení nasledovatelia
|
||||
lost_follows: Stratené sledovania
|
||||
statuses:
|
||||
attached:
|
||||
description: 'Priložené: %{attached}'
|
||||
|
|
|
@ -1716,17 +1716,6 @@ sl:
|
|||
strikes: Ukrepi morediranja
|
||||
two_factor_authentication: Dvofaktorsko overjanje
|
||||
webauthn_authentication: Varnostni ključi
|
||||
severed_relationships:
|
||||
download: Prejmi (%{count})
|
||||
event_type:
|
||||
account_suspension: Suspendiranje računa (%{target_name})
|
||||
domain_block: Suspendiranje strežnika (%{target_name})
|
||||
user_domain_block: Blokirali ste %{target_name}
|
||||
lost_followers: Izgubljeni sledilci
|
||||
lost_follows: Izgubljena sledeni
|
||||
preamble: Če blokirate domeno ali če se vaši moderatorji odločijo suspendirati oddaljen strežnik, lahko izgubite sledene in sledilce. Ko se to zgodi, boste lahko prejeli sezname prekinjenih vez za pregled in morebitno uvažanje na drugem strežniku.
|
||||
purged: Podatke o tem strežniku so očistili skrbniki vašega strežnika.
|
||||
type: Dogodek
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1659,13 +1659,6 @@ sq:
|
|||
strikes: Paralajmërime nga moderimi
|
||||
two_factor_authentication: Mirëfilltësim Dyfaktorësh
|
||||
webauthn_authentication: Kyçe sigurie
|
||||
severed_relationships:
|
||||
event_type:
|
||||
account_suspension: Pezullim llogarie (%{target_name})
|
||||
domain_block: Pezullim shërbyesi (%{target_name})
|
||||
user_domain_block: Bllokuat %{target_name}
|
||||
purged: Hollësitë rreth këtij shërbyesi janë spastuar nga përgjegjësit e shërbyesit tuaj.
|
||||
type: Akt
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1716,17 +1716,6 @@ uk:
|
|||
strikes: Попередження модераторів
|
||||
two_factor_authentication: Двофакторна автентифікація
|
||||
webauthn_authentication: Ключі безпеки
|
||||
severed_relationships:
|
||||
download: Завантажити (%{count})
|
||||
event_type:
|
||||
account_suspension: Призупинення облікового запису (%{target_name})
|
||||
domain_block: Призупинення сервера (%{target_name})
|
||||
user_domain_block: Ви заблокували %{target_name}
|
||||
lost_followers: Втрачені підписники
|
||||
lost_follows: Втрачені підписки
|
||||
preamble: Ви можете втратити підписки та підписників, коли ви блокуєте домен або коли модератори вирішують призупинити віддалений сервер. Коли це станеться, ви зможете завантажити списки розірваних зв'язків, які мають бути перевірені та, можливо, імпортовані на іншому сервері.
|
||||
purged: Інформацію про цей сервер очищені адміністраторами вашого сервера.
|
||||
type: Подія
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1638,17 +1638,6 @@ zh-CN:
|
|||
strikes: 操作记录
|
||||
two_factor_authentication: 双因素认证
|
||||
webauthn_authentication: 安全密钥
|
||||
severed_relationships:
|
||||
download: 下载 (%{count})
|
||||
event_type:
|
||||
account_suspension: 账户被封禁 (%{target_name})
|
||||
domain_block: 服务器被封禁 (%{target_name})
|
||||
user_domain_block: 你屏蔽了 %{target_name}
|
||||
lost_followers: 失去的关注者
|
||||
lost_follows: 失去的关注
|
||||
preamble: 当你屏蔽一个域名或你的管理员决定封禁一个外站服务器时,你可能会失去关注和粉丝。在这种情况下,你可以下载被切断的关系的列表,进行检查以便导入另一个服务器。
|
||||
purged: 关于此服务器的信息已被你所在服务器的管理员清除。
|
||||
type: 事件
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -1640,17 +1640,6 @@ zh-TW:
|
|||
strikes: 管理警告
|
||||
two_factor_authentication: 兩階段驗證
|
||||
webauthn_authentication: 安全金鑰
|
||||
severed_relationships:
|
||||
download: 下載 (%{count} 份)
|
||||
event_type:
|
||||
account_suspension: 停權帳號 (%{target_name})
|
||||
domain_block: 停權伺服器 (%{target_name})
|
||||
user_domain_block: 您已封鎖 %{target_name}
|
||||
lost_followers: 失去之跟隨者
|
||||
lost_follows: 失去之跟隨中
|
||||
preamble: 當您封鎖網域或您的管理員決定停權遠端伺服器時,您可能失去跟隨中或跟隨者。當此發生時,您能下載斷絕服務關係之列表並於其他伺服器中檢視或匯入資料。
|
||||
purged: 關於此伺服器已被您的伺服器管理員清除之資訊
|
||||
type: 事件
|
||||
statuses:
|
||||
attached:
|
||||
audio:
|
||||
|
|
|
@ -39,7 +39,6 @@ module Mastodon::CLI
|
|||
class Webhook < ApplicationRecord; end
|
||||
class BulkImport < ApplicationRecord; end
|
||||
class SoftwareUpdate < ApplicationRecord; end
|
||||
class SeveredRelationship < ApplicationRecord; end
|
||||
|
||||
class DomainBlock < ApplicationRecord
|
||||
enum :severity, { silence: 0, suspend: 1, noop: 2 }
|
||||
|
@ -130,20 +129,6 @@ module Mastodon::CLI
|
|||
record.update_attribute(:account_warning_id, id)
|
||||
end
|
||||
end
|
||||
|
||||
if db_table_exists?(:severed_relationships)
|
||||
SeveredRelationship.where(local_account_id: other_account.id).reorder(nil).find_each do |record|
|
||||
record.update_attribute(:local_account_id, id)
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
next
|
||||
end
|
||||
|
||||
SeveredRelationship.where(remote_account_id: other_account.id).reorder(nil).find_each do |record|
|
||||
record.update_attribute(:remote_account_id, id)
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
next
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Fabricator(:account_relationship_severance_event) do
|
||||
account
|
||||
relationship_severance_event
|
||||
end
|
|
@ -1,6 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Fabricator(:relationship_severance_event) do
|
||||
type { :domain_block }
|
||||
target_name { 'example.com' }
|
||||
end
|
|
@ -1,8 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Fabricator(:severed_relationship) do
|
||||
local_account { Fabricate.build(:account) }
|
||||
remote_account { Fabricate.build(:account) }
|
||||
relationship_severance_event { Fabricate.build(:relationship_severance_event) }
|
||||
direction { :active }
|
||||
end
|
|
@ -1,49 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe RelationshipSeveranceEvent do
|
||||
let(:local_account) { Fabricate(:account) }
|
||||
let(:remote_account) { Fabricate(:account, domain: 'example.com') }
|
||||
let(:event) { Fabricate(:relationship_severance_event) }
|
||||
|
||||
describe '#import_from_active_follows!' do
|
||||
before do
|
||||
local_account.follow!(remote_account)
|
||||
end
|
||||
|
||||
it 'imports the follow relationships with the expected direction' do
|
||||
event.import_from_active_follows!(local_account.active_relationships)
|
||||
|
||||
relationships = event.severed_relationships.to_a
|
||||
expect(relationships.size).to eq 1
|
||||
expect(relationships[0].account).to eq local_account
|
||||
expect(relationships[0].target_account).to eq remote_account
|
||||
end
|
||||
end
|
||||
|
||||
describe '#import_from_passive_follows!' do
|
||||
before do
|
||||
remote_account.follow!(local_account)
|
||||
end
|
||||
|
||||
it 'imports the follow relationships with the expected direction' do
|
||||
event.import_from_passive_follows!(local_account.passive_relationships)
|
||||
|
||||
relationships = event.severed_relationships.to_a
|
||||
expect(relationships.size).to eq 1
|
||||
expect(relationships[0].account).to eq remote_account
|
||||
expect(relationships[0].target_account).to eq local_account
|
||||
end
|
||||
end
|
||||
|
||||
describe '#affected_local_accounts' do
|
||||
before do
|
||||
event.severed_relationships.create!(local_account: local_account, remote_account: remote_account, direction: :active)
|
||||
end
|
||||
|
||||
it 'correctly lists local accounts' do
|
||||
expect(event.affected_local_accounts.to_a).to contain_exactly(local_account)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,45 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe SeveredRelationship do
|
||||
let(:local_account) { Fabricate(:account) }
|
||||
let(:remote_account) { Fabricate(:account, domain: 'example.com') }
|
||||
let(:event) { Fabricate(:relationship_severance_event) }
|
||||
|
||||
describe '#account' do
|
||||
context 'when the local account is the follower' do
|
||||
let(:severed_relationship) { Fabricate(:severed_relationship, relationship_severance_event: event, local_account: local_account, remote_account: remote_account, direction: :active) }
|
||||
|
||||
it 'returns the local account' do
|
||||
expect(severed_relationship.account).to eq local_account
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the local account is being followed' do
|
||||
let(:severed_relationship) { Fabricate(:severed_relationship, relationship_severance_event: event, local_account: local_account, remote_account: remote_account, direction: :passive) }
|
||||
|
||||
it 'returns the remote account' do
|
||||
expect(severed_relationship.account).to eq remote_account
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#target_account' do
|
||||
context 'when the local account is the follower' do
|
||||
let(:severed_relationship) { Fabricate(:severed_relationship, relationship_severance_event: event, local_account: local_account, remote_account: remote_account, direction: :active) }
|
||||
|
||||
it 'returns the remote account' do
|
||||
expect(severed_relationship.target_account).to eq remote_account
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the local account is being followed' do
|
||||
let(:severed_relationship) { Fabricate(:severed_relationship, relationship_severance_event: event, local_account: local_account, remote_account: remote_account, direction: :passive) }
|
||||
|
||||
it 'returns the local account' do
|
||||
expect(severed_relationship.target_account).to eq local_account
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,24 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Severed relationships page' do
|
||||
include RoutingHelper
|
||||
|
||||
describe 'GET severed_relationships#index' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:event) { Fabricate(:account_relationship_severance_event, account: user.account) }
|
||||
|
||||
before do
|
||||
sign_in user
|
||||
|
||||
Fabricate.times(3, :severed_relationship, local_account: user.account, relationship_severance_event: event.relationship_severance_event)
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get severed_relationships_path
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -20,7 +20,7 @@ RSpec.describe AfterBlockDomainFromAccountService do
|
|||
end
|
||||
end
|
||||
|
||||
it 'purges followers from blocked domain, sends them Reject->Follow, and records severed relationships', :aggregate_failures do
|
||||
it 'purges followers from blocked domain, sends them Reject->Follow', :aggregate_failures do
|
||||
subject.call(alice, 'evil.org')
|
||||
|
||||
expect(wolf.following?(alice)).to be false
|
||||
|
@ -28,10 +28,5 @@ RSpec.describe AfterBlockDomainFromAccountService do
|
|||
[a_string_including('"type":"Reject"'), alice.id, wolf.inbox_url],
|
||||
[a_string_including('"type":"Undo"'), alice.id, dog.inbox_url]
|
||||
)
|
||||
|
||||
severed_relationships = alice.severed_relationships.to_a
|
||||
expect(severed_relationships.count).to eq 2
|
||||
expect(severed_relationships[0].relationship_severance_event).to eq severed_relationships[1].relationship_severance_event
|
||||
expect(severed_relationships.map { |rel| [rel.account, rel.target_account] }).to contain_exactly([wolf, alice], [alice, dog])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,7 +19,7 @@ RSpec.describe BlockDomainService do
|
|||
bystander.follow!(local_account)
|
||||
end
|
||||
|
||||
it 'creates a domain block, suspends remote accounts with appropriate suspension date, records severed relationships', :aggregate_failures do
|
||||
it 'creates a domain block, suspends remote accounts with appropriate suspension date', :aggregate_failures do
|
||||
subject.call(DomainBlock.create!(domain: 'evil.org', severity: :suspend))
|
||||
|
||||
expect(DomainBlock.blocked?('evil.org')).to be true
|
||||
|
@ -36,12 +36,6 @@ RSpec.describe BlockDomainService do
|
|||
expect { bad_status_plain.reload }.to raise_exception ActiveRecord::RecordNotFound
|
||||
expect { bad_status_with_attachment.reload }.to raise_exception ActiveRecord::RecordNotFound
|
||||
expect { bad_attachment.reload }.to raise_exception ActiveRecord::RecordNotFound
|
||||
|
||||
# Records severed relationships
|
||||
severed_relationships = local_account.severed_relationships.to_a
|
||||
expect(severed_relationships.count).to eq 2
|
||||
expect(severed_relationships[0].relationship_severance_event).to eq severed_relationships[1].relationship_severance_event
|
||||
expect(severed_relationships.map { |rel| [rel.account, rel.target_account] }).to contain_exactly([bystander, local_account], [local_account, bad_account])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -85,14 +85,10 @@ RSpec.describe SuspendAccountService, :sidekiq_inline do
|
|||
account.follow!(local_followee)
|
||||
end
|
||||
|
||||
it 'sends a Reject Follow activity, and records severed relationships', :aggregate_failures do
|
||||
it 'sends a Reject Follow activity' do
|
||||
subject
|
||||
|
||||
expect(a_request(:post, account.inbox_url).with { |req| match_reject_follow_request(req, account, local_followee) }).to have_been_made.once
|
||||
|
||||
severed_relationships = local_followee.severed_relationships.to_a
|
||||
expect(severed_relationships.count).to eq 1
|
||||
expect(severed_relationships.map { |rel| [rel.account, rel.target_account] }).to contain_exactly([account, local_followee])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue