Add: ホワイトリスト運用時、承認待ちリモートアカウントの概念ならびに操作画面 (#584)
* Add: ホワイトリスト運用時、承認待ちリモートアカウントの概念ならびに操作画面 * Fix test * Fix test
This commit is contained in:
parent
0048a8368e
commit
0f680a21b4
18 changed files with 174 additions and 20 deletions
|
@ -168,6 +168,12 @@ module Admin
|
||||||
'approve'
|
'approve'
|
||||||
elsif params[:reject]
|
elsif params[:reject]
|
||||||
'reject'
|
'reject'
|
||||||
|
elsif params[:approve_remote]
|
||||||
|
'approve_remote'
|
||||||
|
elsif params[:approve_remote_domain]
|
||||||
|
'approve_remote_domain'
|
||||||
|
elsif params[:reject_remote]
|
||||||
|
'reject_remote'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,7 @@ module Admin::AccountsHelper
|
||||||
[t('admin.accounts.moderation.silenced'), 'silenced'],
|
[t('admin.accounts.moderation.silenced'), 'silenced'],
|
||||||
[t('admin.accounts.moderation.disabled'), 'disabled'],
|
[t('admin.accounts.moderation.disabled'), 'disabled'],
|
||||||
[t('admin.accounts.moderation.suspended'), 'suspended'],
|
[t('admin.accounts.moderation.suspended'), 'suspended'],
|
||||||
|
[t('admin.accounts.moderation.remote_pending'), 'remote_pending'],
|
||||||
[safe_join([t('admin.accounts.moderation.pending'), "(#{pending_user_count_label})"], ' '), 'pending'],
|
[safe_join([t('admin.accounts.moderation.pending'), "(#{pending_user_count_label})"], ' '), 'pending'],
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
|
@ -55,7 +55,7 @@ const messages = defineMessages({
|
||||||
},
|
},
|
||||||
circle_short: {
|
circle_short: {
|
||||||
id: 'privacy.circle.short',
|
id: 'privacy.circle.short',
|
||||||
defaultMessage: 'Circle members only',
|
defaultMessage: 'Circle',
|
||||||
},
|
},
|
||||||
reply_short: {
|
reply_short: {
|
||||||
id: 'privacy.reply.short',
|
id: 'privacy.reply.short',
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
# settings :jsonb
|
# settings :jsonb
|
||||||
# indexable :boolean default(FALSE), not null
|
# indexable :boolean default(FALSE), not null
|
||||||
# master_settings :jsonb
|
# master_settings :jsonb
|
||||||
|
# remote_pending :boolean default(FALSE), not null
|
||||||
#
|
#
|
||||||
|
|
||||||
class Account < ApplicationRecord
|
class Account < ApplicationRecord
|
||||||
|
@ -122,6 +123,7 @@ class Account < ApplicationRecord
|
||||||
scope :partitioned, -> { order(Arel.sql('row_number() over (partition by domain)')) }
|
scope :partitioned, -> { order(Arel.sql('row_number() over (partition by domain)')) }
|
||||||
scope :silenced, -> { where.not(silenced_at: nil) }
|
scope :silenced, -> { where.not(silenced_at: nil) }
|
||||||
scope :suspended, -> { where.not(suspended_at: nil) }
|
scope :suspended, -> { where.not(suspended_at: nil) }
|
||||||
|
scope :remote_pending, -> { where(remote_pending: true).where.not(suspended_at: nil) }
|
||||||
scope :sensitized, -> { where.not(sensitized_at: nil) }
|
scope :sensitized, -> { where.not(sensitized_at: nil) }
|
||||||
scope :without_suspended, -> { where(suspended_at: nil) }
|
scope :without_suspended, -> { where(suspended_at: nil) }
|
||||||
scope :without_silenced, -> { where(silenced_at: nil) }
|
scope :without_silenced, -> { where(silenced_at: nil) }
|
||||||
|
@ -295,6 +297,16 @@ class Account < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def approve_remote!
|
||||||
|
update!(remote_pending: false)
|
||||||
|
unsuspend!
|
||||||
|
end
|
||||||
|
|
||||||
|
def reject_remote!
|
||||||
|
update!(remote_pending: false)
|
||||||
|
suspend!
|
||||||
|
end
|
||||||
|
|
||||||
def sensitized?
|
def sensitized?
|
||||||
sensitized_at.present?
|
sensitized_at.present?
|
||||||
end
|
end
|
||||||
|
|
|
@ -88,6 +88,8 @@ class AccountFilter
|
||||||
Account.without_suspended
|
Account.without_suspended
|
||||||
when 'pending'
|
when 'pending'
|
||||||
accounts_with_users.merge(User.pending)
|
accounts_with_users.merge(User.pending)
|
||||||
|
when 'remote_pending'
|
||||||
|
Account.remote_pending
|
||||||
when 'suspended'
|
when 'suspended'
|
||||||
Account.suspended
|
Account.suspended
|
||||||
when 'disabled'
|
when 'disabled'
|
||||||
|
|
|
@ -23,6 +23,12 @@ class Form::AccountBatch
|
||||||
approve!
|
approve!
|
||||||
when 'reject'
|
when 'reject'
|
||||||
reject!
|
reject!
|
||||||
|
when 'approve_remote'
|
||||||
|
approve_remote!
|
||||||
|
when 'approve_remote_domain'
|
||||||
|
approve_remote_domain!
|
||||||
|
when 'reject_remote'
|
||||||
|
reject_remote!
|
||||||
when 'suppress_follow_recommendation'
|
when 'suppress_follow_recommendation'
|
||||||
suppress_follow_recommendation!
|
suppress_follow_recommendation!
|
||||||
when 'unsuppress_follow_recommendation'
|
when 'unsuppress_follow_recommendation'
|
||||||
|
@ -84,6 +90,29 @@ class Form::AccountBatch
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def approve_remote!
|
||||||
|
accounts.find_each do |account|
|
||||||
|
approve_remote_account(account)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def approve_remote_domain!
|
||||||
|
domains = accounts.group_by(&:domain).pluck(0)
|
||||||
|
if (Setting.permit_new_account_domains || []).compact_blank.present?
|
||||||
|
list = ((Setting.permit_new_account_domains || []) + domains).compact_blank.uniq.join("\n")
|
||||||
|
Form::AdminSettings.new(permit_new_account_domains: list).save
|
||||||
|
end
|
||||||
|
Account.where(domain: domains, remote_pending: true).find_each do |account|
|
||||||
|
approve_remote_account(account)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def reject_remote!
|
||||||
|
accounts.find_each do |account|
|
||||||
|
reject_remote_account(account)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def suspend!
|
def suspend!
|
||||||
accounts.find_each do |account|
|
accounts.find_each do |account|
|
||||||
if account.user_pending?
|
if account.user_pending?
|
||||||
|
@ -115,10 +144,21 @@ class Form::AccountBatch
|
||||||
AccountDeletionWorker.perform_async(account.id, { 'reserve_username' => false })
|
AccountDeletionWorker.perform_async(account.id, { 'reserve_username' => false })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def reject_remote_account(account)
|
||||||
|
authorize(account, :reject_remote?)
|
||||||
|
log_action(:reject_remote, account)
|
||||||
|
account.reject_remote!
|
||||||
|
process_suspend(account)
|
||||||
|
end
|
||||||
|
|
||||||
def suspend_account(account)
|
def suspend_account(account)
|
||||||
authorize(account, :suspend?)
|
authorize(account, :suspend?)
|
||||||
log_action(:suspend, account)
|
log_action(:suspend, account)
|
||||||
account.suspend!(origin: :local)
|
account.suspend!(origin: :local)
|
||||||
|
process_suspend(account)
|
||||||
|
end
|
||||||
|
|
||||||
|
def process_suspend(account)
|
||||||
account.strikes.create!(
|
account.strikes.create!(
|
||||||
account: current_account,
|
account: current_account,
|
||||||
action: :suspend
|
action: :suspend
|
||||||
|
@ -143,6 +183,12 @@ class Form::AccountBatch
|
||||||
account.user.approve!
|
account.user.approve!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def approve_remote_account(account)
|
||||||
|
authorize(account, :approve_remote?)
|
||||||
|
log_action(:approve_remote, account)
|
||||||
|
account.approve_remote!
|
||||||
|
end
|
||||||
|
|
||||||
def select_all_matching?
|
def select_all_matching?
|
||||||
select_all_matching == '1'
|
select_all_matching == '1'
|
||||||
end
|
end
|
||||||
|
|
|
@ -64,4 +64,12 @@ class AccountPolicy < ApplicationPolicy
|
||||||
def review?
|
def review?
|
||||||
role.can?(:manage_taxonomies)
|
role.can?(:manage_taxonomies)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def approve_remote?
|
||||||
|
role.can?(:manage_users) && record.remote_pending
|
||||||
|
end
|
||||||
|
|
||||||
|
def reject_remote?
|
||||||
|
role.can?(:manage_users) && record.remote_pending
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,8 +37,6 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||||
@suspension_changed = false
|
@suspension_changed = false
|
||||||
|
|
||||||
if @account.nil?
|
if @account.nil?
|
||||||
return nil if blocking_new_account?(@domain)
|
|
||||||
|
|
||||||
with_redis do |redis|
|
with_redis do |redis|
|
||||||
return nil if redis.pfcount("unique_subdomains_for:#{PublicSuffix.domain(@domain, ignore_private: true)}") >= SUBDOMAINS_RATELIMIT
|
return nil if redis.pfcount("unique_subdomains_for:#{PublicSuffix.domain(@domain, ignore_private: true)}") >= SUBDOMAINS_RATELIMIT
|
||||||
|
|
||||||
|
@ -61,7 +59,7 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||||
clear_tombstones! if key_changed?
|
clear_tombstones! if key_changed?
|
||||||
after_suspension_change! if suspension_changed?
|
after_suspension_change! if suspension_changed?
|
||||||
|
|
||||||
unless @options[:only_key] || @account.suspended?
|
unless @options[:only_key] || (@account.suspended? && !@account.remote_pending)
|
||||||
check_featured_collection! if @account.featured_collection_url.present?
|
check_featured_collection! if @account.featured_collection_url.present?
|
||||||
check_featured_tags_collection! if @json['featuredTags'].present?
|
check_featured_tags_collection! if @json['featuredTags'].present?
|
||||||
check_links! if @account.fields.any?(&:requires_verification?)
|
check_links! if @account.fields.any?(&:requires_verification?)
|
||||||
|
@ -87,6 +85,12 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||||
@account.silenced_at = domain_block.created_at if auto_silence?
|
@account.silenced_at = domain_block.created_at if auto_silence?
|
||||||
@account.searchability = :direct # not null
|
@account.searchability = :direct # not null
|
||||||
|
|
||||||
|
if @account.suspended_at.nil? && blocking_new_account?
|
||||||
|
@account.suspended_at = Time.now.utc
|
||||||
|
@account.suspension_origin = :local
|
||||||
|
@account.remote_pending = true
|
||||||
|
end
|
||||||
|
|
||||||
set_immediate_protocol_attributes!
|
set_immediate_protocol_attributes!
|
||||||
|
|
||||||
@account.save!
|
@account.save!
|
||||||
|
@ -98,9 +102,12 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||||
|
|
||||||
set_suspension!
|
set_suspension!
|
||||||
set_immediate_protocol_attributes!
|
set_immediate_protocol_attributes!
|
||||||
set_fetchable_key! unless @account.suspended? && @account.suspension_origin_local?
|
|
||||||
set_immediate_attributes! unless @account.suspended?
|
freeze_data = @account.suspended? && (@account.suspension_origin_remote? || !@account.remote_pending)
|
||||||
set_fetchable_attributes! unless @options[:only_key] || @account.suspended?
|
|
||||||
|
set_fetchable_key! unless @account.suspended? && @account.suspension_origin_local? && !@account.remote_pending
|
||||||
|
set_immediate_attributes! unless freeze_data
|
||||||
|
set_fetchable_attributes! unless @options[:only_key] || freeze_data
|
||||||
|
|
||||||
@account.save_with_optional_media!
|
@account.save_with_optional_media!
|
||||||
end
|
end
|
||||||
|
@ -132,10 +139,10 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||||
@account.memorial = @json['memorial'] || false
|
@account.memorial = @json['memorial'] || false
|
||||||
end
|
end
|
||||||
|
|
||||||
def blocking_new_account?(domain)
|
def blocking_new_account?
|
||||||
return false if permit_new_account_domains.blank?
|
return false if permit_new_account_domains.blank?
|
||||||
|
|
||||||
permit_new_account_domains.exclude?(domain)
|
permit_new_account_domains.exclude?(@domain)
|
||||||
end
|
end
|
||||||
|
|
||||||
def permit_new_account_domains
|
def permit_new_account_domains
|
||||||
|
@ -410,7 +417,7 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def skip_download?
|
def skip_download?
|
||||||
@account.suspended? || domain_block&.reject_media?
|
(@account.suspended? && !@account.remote_pending) || domain_block&.reject_media?
|
||||||
end
|
end
|
||||||
|
|
||||||
def auto_suspend?
|
def auto_suspend?
|
||||||
|
|
|
@ -50,6 +50,13 @@
|
||||||
|
|
||||||
= f.button safe_join([fa_icon('times'), t('admin.accounts.reject')]), name: :reject, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
= f.button safe_join([fa_icon('times'), t('admin.accounts.reject')]), name: :reject, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
|
|
||||||
|
- elsif @accounts.any?(&:remote_pending)
|
||||||
|
= f.button safe_join([fa_icon('check'), t('admin.accounts.approve')]), name: :approve_remote, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
|
|
||||||
|
= f.button safe_join([fa_icon('check'), t('admin.accounts.approve_domain')]), name: :approve_remote_domain, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
|
|
||||||
|
= f.button safe_join([fa_icon('times'), t('admin.accounts.reject')]), name: :reject_remote, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
|
|
||||||
= f.button safe_join([fa_icon('lock'), t('admin.accounts.perform_full_suspension')]), name: :suspend, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
= f.button safe_join([fa_icon('lock'), t('admin.accounts.perform_full_suspension')]), name: :suspend, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
- if @accounts.total_count > @accounts.size
|
- if @accounts.total_count > @accounts.size
|
||||||
.batch-table__select-all
|
.batch-table__select-all
|
||||||
|
|
|
@ -32,8 +32,12 @@
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :hide_local_users_for_anonymous, wrapper: :with_label, as: :boolean, label: t('admin.ng_words.hide_local_users_for_anonymous')
|
= f.input :hide_local_users_for_anonymous, wrapper: :with_label, as: :boolean, label: t('admin.ng_words.hide_local_users_for_anonymous')
|
||||||
|
|
||||||
|
%p.hint
|
||||||
|
= t 'admin.ng_words.remote_approval_hint'
|
||||||
|
= link_to t('admin.ng_words.remote_approval_list'), admin_accounts_path(status: 'remote_pending', origin: 'remote')
|
||||||
|
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :permit_new_account_domains, wrapper: :with_label, as: :text, kmyblue: true, input_html: { rows: 6 }, label: t('admin.special_instances.permit_new_account_domains'), hint: t('admin.special_instances.permit_new_account_domains_hint')
|
= f.input :permit_new_account_domains, wrapper: :with_label, as: :text, kmyblue: true, input_html: { rows: 6 }, label: t('admin.ng_words.permit_new_account_domains')
|
||||||
|
|
||||||
.actions
|
.actions
|
||||||
= f.button :button, t('generic.save_changes'), type: :submit
|
= f.button :button, t('generic.save_changes'), type: :submit
|
||||||
|
|
|
@ -10,7 +10,7 @@ class RedownloadAvatarWorker
|
||||||
def perform(id)
|
def perform(id)
|
||||||
account = Account.find(id)
|
account = Account.find(id)
|
||||||
|
|
||||||
return if account.suspended? || DomainBlock.rule_for(account.domain)&.reject_media?
|
return if (account.suspended? && !account.remote_pending) || DomainBlock.rule_for(account.domain)&.reject_media?
|
||||||
return if account.avatar_remote_url.blank? || account.avatar_file_name.present?
|
return if account.avatar_remote_url.blank? || account.avatar_file_name.present?
|
||||||
|
|
||||||
account.reset_avatar!
|
account.reset_avatar!
|
||||||
|
|
|
@ -10,7 +10,7 @@ class RedownloadHeaderWorker
|
||||||
def perform(id)
|
def perform(id)
|
||||||
account = Account.find(id)
|
account = Account.find(id)
|
||||||
|
|
||||||
return if account.suspended? || DomainBlock.rule_for(account.domain)&.reject_media?
|
return if (account.suspended? && !account.remote_pending) || DomainBlock.rule_for(account.domain)&.reject_media?
|
||||||
return if account.header_remote_url.blank? || account.header_file_name.present?
|
return if account.header_remote_url.blank? || account.header_file_name.present?
|
||||||
|
|
||||||
account.reset_header!
|
account.reset_header!
|
||||||
|
|
|
@ -33,6 +33,7 @@ en:
|
||||||
accounts:
|
accounts:
|
||||||
add_email_domain_block: Block e-mail domain
|
add_email_domain_block: Block e-mail domain
|
||||||
approve: Approve
|
approve: Approve
|
||||||
|
approve_domain: Approve domain
|
||||||
approved_msg: Successfully approved %{username}'s sign-up application
|
approved_msg: Successfully approved %{username}'s sign-up application
|
||||||
are_you_sure: Are you sure?
|
are_you_sure: Are you sure?
|
||||||
avatar: Avatar
|
avatar: Avatar
|
||||||
|
@ -93,6 +94,7 @@ en:
|
||||||
all: All
|
all: All
|
||||||
disabled: Disabled
|
disabled: Disabled
|
||||||
pending: Pending
|
pending: Pending
|
||||||
|
remote_pending: Pending (Remote)
|
||||||
silenced: Limited
|
silenced: Limited
|
||||||
suspended: Suspended
|
suspended: Suspended
|
||||||
title: Moderation
|
title: Moderation
|
||||||
|
@ -230,6 +232,7 @@ en:
|
||||||
update_user_role: Update Role
|
update_user_role: Update Role
|
||||||
actions:
|
actions:
|
||||||
approve_appeal_html: "%{name} approved moderation decision appeal from %{target}"
|
approve_appeal_html: "%{name} approved moderation decision appeal from %{target}"
|
||||||
|
approve_remote_account_html: "%{name} approved %{target} join on this server"
|
||||||
approve_user_html: "%{name} approved sign-up from %{target}"
|
approve_user_html: "%{name} approved sign-up from %{target}"
|
||||||
assigned_to_self_report_html: "%{name} assigned report %{target} to themselves"
|
assigned_to_self_report_html: "%{name} assigned report %{target} to themselves"
|
||||||
change_email_user_html: "%{name} changed the e-mail address of user %{target}"
|
change_email_user_html: "%{name} changed the e-mail address of user %{target}"
|
||||||
|
@ -269,6 +272,7 @@ en:
|
||||||
memorialize_account_html: "%{name} turned %{target}'s account into a memoriam page"
|
memorialize_account_html: "%{name} turned %{target}'s account into a memoriam page"
|
||||||
promote_user_html: "%{name} promoted user %{target}"
|
promote_user_html: "%{name} promoted user %{target}"
|
||||||
reject_appeal_html: "%{name} rejected moderation decision appeal from %{target}"
|
reject_appeal_html: "%{name} rejected moderation decision appeal from %{target}"
|
||||||
|
reject_remote_account_html: "%{name} rejected %{target} join on this server"
|
||||||
reject_user_html: "%{name} rejected sign-up from %{target}"
|
reject_user_html: "%{name} rejected sign-up from %{target}"
|
||||||
remove_avatar_user_html: "%{name} removed %{target}'s avatar"
|
remove_avatar_user_html: "%{name} removed %{target}'s avatar"
|
||||||
remove_history_status_html: "%{name} removed post edit histories by %{target}"
|
remove_history_status_html: "%{name} removed post edit histories by %{target}"
|
||||||
|
@ -647,9 +651,12 @@ en:
|
||||||
keywords_for_stranger_mention: Reject keywords when mention/reply/reference/quote from strangers
|
keywords_for_stranger_mention: Reject keywords when mention/reply/reference/quote from strangers
|
||||||
keywords_for_stranger_mention_hint: This words are checked posts from other servers only.
|
keywords_for_stranger_mention_hint: This words are checked posts from other servers only.
|
||||||
keywords_hint: The first character of the line is "?". to use regular expressions
|
keywords_hint: The first character of the line is "?". to use regular expressions
|
||||||
|
permit_new_account_domains: Domain list to automatically approve new users
|
||||||
post_hash_tags_max: Hash tags max for posts
|
post_hash_tags_max: Hash tags max for posts
|
||||||
post_mentions_max: Mentions max for posts
|
post_mentions_max: Mentions max for posts
|
||||||
post_stranger_mentions_max: 投稿に設定可能なメンションの最大数 (If the mentions include at least one person who is not a follower of yours)
|
post_stranger_mentions_max: 投稿に設定可能なメンションの最大数 (If the mentions include at least one person who is not a follower of yours)
|
||||||
|
remote_approval_list: List of remote accounts awaiting approval
|
||||||
|
remote_approval_hint: If you set one or more domains on the list of domains for which you want to automatically approve new users, newly recognized accounts on unspecified domains will be placed in suspend status. You can review that list and approve them if necessary. If none is specified, all remote accounts are approved immediately.
|
||||||
stranger_mention_from_local_ng: フォローしていないアカウントへのメンションのNGワードを、ローカルユーザーによる投稿にも適用する
|
stranger_mention_from_local_ng: フォローしていないアカウントへのメンションのNGワードを、ローカルユーザーによる投稿にも適用する
|
||||||
stranger_mention_from_local_ng_hint: サーバーの登録が承認制でない場合、あなたのサーバーにもスパムが入り込む可能性があります
|
stranger_mention_from_local_ng_hint: サーバーの登録が承認制でない場合、あなたのサーバーにもスパムが入り込む可能性があります
|
||||||
test_error: Testing is returned any errors
|
test_error: Testing is returned any errors
|
||||||
|
@ -918,8 +925,6 @@ en:
|
||||||
special_instances:
|
special_instances:
|
||||||
emoji_reaction_disallow_domains: Domains we are not permitted emoji reaction
|
emoji_reaction_disallow_domains: Domains we are not permitted emoji reaction
|
||||||
emoji_reaction_disallow_domains_hint: If you need to be considerate to your coalition partners, set the domain with a new line separator. It is not possible to put an emoji reaction on a post from a set domain.
|
emoji_reaction_disallow_domains_hint: If you need to be considerate to your coalition partners, set the domain with a new line separator. It is not possible to put an emoji reaction on a post from a set domain.
|
||||||
permit_new_account_domains: Domain to allow recognition of new accounts
|
|
||||||
permit_new_account_domains_hint: Only new account information sent from the domain specified here will be saved if more than one is specified,
|
|
||||||
title: Special servers
|
title: Special servers
|
||||||
statuses:
|
statuses:
|
||||||
account: Author
|
account: Author
|
||||||
|
|
|
@ -31,6 +31,7 @@ ja:
|
||||||
accounts:
|
accounts:
|
||||||
add_email_domain_block: メールドメインブロックに追加
|
add_email_domain_block: メールドメインブロックに追加
|
||||||
approve: 承認
|
approve: 承認
|
||||||
|
approve_domain: ドメインを承認
|
||||||
approved_msg: '%{username}さんの登録申請を承認しました'
|
approved_msg: '%{username}さんの登録申請を承認しました'
|
||||||
are_you_sure: 本当に実行しますか?
|
are_you_sure: 本当に実行しますか?
|
||||||
avatar: アイコン
|
avatar: アイコン
|
||||||
|
@ -91,6 +92,7 @@ ja:
|
||||||
all: すべて
|
all: すべて
|
||||||
disabled: 無効化済み
|
disabled: 無効化済み
|
||||||
pending: 承認待ち
|
pending: 承認待ち
|
||||||
|
remote_pending: 承認待ち (リモート)
|
||||||
silenced: 制限
|
silenced: 制限
|
||||||
suspended: 停止済み
|
suspended: 停止済み
|
||||||
title: モデレーション
|
title: モデレーション
|
||||||
|
@ -227,6 +229,7 @@ ja:
|
||||||
update_user_role: ロールを更新
|
update_user_role: ロールを更新
|
||||||
actions:
|
actions:
|
||||||
approve_appeal_html: "%{name}さんが%{target}さんからの抗議を承認しました"
|
approve_appeal_html: "%{name}さんが%{target}さんからの抗議を承認しました"
|
||||||
|
approve_remote_account_html: "%{name}さんが%{target}さんの参加を承認しました"
|
||||||
approve_user_html: "%{name}さんが%{target}さんからの登録を承認しました"
|
approve_user_html: "%{name}さんが%{target}さんからの登録を承認しました"
|
||||||
assigned_to_self_report_html: "%{name}さんが通報 %{target}を自身の担当に割り当てました"
|
assigned_to_self_report_html: "%{name}さんが通報 %{target}を自身の担当に割り当てました"
|
||||||
change_email_user_html: "%{name}さんが%{target}さんのメールアドレスを変更しました"
|
change_email_user_html: "%{name}さんが%{target}さんのメールアドレスを変更しました"
|
||||||
|
@ -266,6 +269,7 @@ ja:
|
||||||
memorialize_account_html: "%{name}さんが%{target}さんを追悼アカウントページに登録しました"
|
memorialize_account_html: "%{name}さんが%{target}さんを追悼アカウントページに登録しました"
|
||||||
promote_user_html: "%{name}さんが%{target}さんを昇格しました"
|
promote_user_html: "%{name}さんが%{target}さんを昇格しました"
|
||||||
reject_appeal_html: "%{name}さんが%{target}からの抗議を却下しました"
|
reject_appeal_html: "%{name}さんが%{target}からの抗議を却下しました"
|
||||||
|
reject_remote_account_html: "%{name}さんが%{target}さんの参加を却下しました"
|
||||||
reject_user_html: "%{name}さんが%{target}さんからの登録を拒否しました"
|
reject_user_html: "%{name}さんが%{target}さんからの登録を拒否しました"
|
||||||
remove_avatar_user_html: "%{name}さんが%{target}さんのアイコンを削除しました"
|
remove_avatar_user_html: "%{name}さんが%{target}さんのアイコンを削除しました"
|
||||||
remove_history_status_html: "%{name}さんが%{target}さんの投稿の編集履歴を削除しました"
|
remove_history_status_html: "%{name}さんが%{target}さんの投稿の編集履歴を削除しました"
|
||||||
|
@ -640,9 +644,12 @@ ja:
|
||||||
keywords_for_stranger_mention: フォローしていないアカウントへのメンションや参照で利用できないキーワード
|
keywords_for_stranger_mention: フォローしていないアカウントへのメンションや参照で利用できないキーワード
|
||||||
keywords_for_stranger_mention_hint: フォローしていないアカウントへのメンション、参照、引用にのみ適用されます
|
keywords_for_stranger_mention_hint: フォローしていないアカウントへのメンション、参照、引用にのみ適用されます
|
||||||
keywords_hint: 行を「?」で始めると、正規表現が使えます
|
keywords_hint: 行を「?」で始めると、正規表現が使えます
|
||||||
|
permit_new_account_domains: 新規ユーザーを自動承認するドメイン
|
||||||
post_hash_tags_max: 投稿に設定可能なハッシュタグの最大数
|
post_hash_tags_max: 投稿に設定可能なハッシュタグの最大数
|
||||||
post_mentions_max: 投稿に設定可能なメンションの最大数
|
post_mentions_max: 投稿に設定可能なメンションの最大数
|
||||||
post_stranger_mentions_max: 投稿に設定可能なメンションの最大数 (メンション先にフォロワー以外を1人でも含む場合)
|
post_stranger_mentions_max: 投稿に設定可能なメンションの最大数 (メンション先にフォロワー以外を1人でも含む場合)
|
||||||
|
remote_approval_list: 承認待ちのリモートアカウント一覧
|
||||||
|
remote_approval_hint: 新規ユーザーを自動承認するドメインリストに1つ以上のドメインを設定すると、指定されていないドメインで新しく認識されたアカウントはサスペンド状態になります。その一覧を確認し、必要であれば承認を行うことができます。何も指定しなかった場合、全てのリモートアカウントが即座に承認されます。
|
||||||
stranger_mention_from_local_ng: フォローしていないアカウントへのメンションのNGワードを、ローカルユーザーによる投稿にも適用する
|
stranger_mention_from_local_ng: フォローしていないアカウントへのメンションのNGワードを、ローカルユーザーによる投稿にも適用する
|
||||||
stranger_mention_from_local_ng_hint: サーバーの登録が承認制でない場合、あなたのサーバーにもスパムが入り込む可能性があります
|
stranger_mention_from_local_ng_hint: サーバーの登録が承認制でない場合、あなたのサーバーにもスパムが入り込む可能性があります
|
||||||
test_error: NGワードのテストに失敗しました。正規表現のミスが含まれているかもしれません
|
test_error: NGワードのテストに失敗しました。正規表現のミスが含まれているかもしれません
|
||||||
|
@ -909,8 +916,6 @@ ja:
|
||||||
special_instances:
|
special_instances:
|
||||||
emoji_reaction_disallow_domains: 自分のサーバーが絵文字リアクションをすることを許可しないドメイン
|
emoji_reaction_disallow_domains: 自分のサーバーが絵文字リアクションをすることを許可しないドメイン
|
||||||
emoji_reaction_disallow_domains_hint: 連合先に配慮する必要がある場合、ドメインを改行区切りで設定します。設定されたドメインの投稿に絵文字リアクションを付けることはできません。
|
emoji_reaction_disallow_domains_hint: 連合先に配慮する必要がある場合、ドメインを改行区切りで設定します。設定されたドメインの投稿に絵文字リアクションを付けることはできません。
|
||||||
permit_new_account_domains: 新規アカウントの認知を許可するドメイン
|
|
||||||
permit_new_account_domains_hint: 1つ以上指定した場合、ここで指定されたドメインから送られてくる新規アカウント情報だけが保存されるようになります
|
|
||||||
title: 特殊なサーバー
|
title: 特殊なサーバー
|
||||||
statuses:
|
statuses:
|
||||||
account: 作成者
|
account: 作成者
|
||||||
|
|
11
db/migrate/20240217093511_add_remote_pending_to_accounts.rb
Normal file
11
db/migrate/20240217093511_add_remote_pending_to_accounts.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddRemotePendingToAccounts < ActiveRecord::Migration[7.1]
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
def change
|
||||||
|
add_column :accounts, :remote_pending, :boolean, null: false, default: false
|
||||||
|
|
||||||
|
add_index :accounts, :remote_pending, unique: false, algorithm: :concurrently
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[7.1].define(version: 2024_02_17_022038) do
|
ActiveRecord::Schema[7.1].define(version: 2024_02_17_093511) do
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
|
||||||
|
@ -194,10 +194,12 @@ ActiveRecord::Schema[7.1].define(version: 2024_02_17_022038) do
|
||||||
t.jsonb "settings"
|
t.jsonb "settings"
|
||||||
t.boolean "indexable", default: false, null: false
|
t.boolean "indexable", default: false, null: false
|
||||||
t.jsonb "master_settings"
|
t.jsonb "master_settings"
|
||||||
|
t.boolean "remote_pending", default: false, null: false
|
||||||
t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin
|
t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin
|
||||||
t.index "lower((username)::text), COALESCE(lower((domain)::text), ''::text)", name: "index_accounts_on_username_and_domain_lower", unique: true
|
t.index "lower((username)::text), COALESCE(lower((domain)::text), ''::text)", name: "index_accounts_on_username_and_domain_lower", unique: true
|
||||||
t.index ["domain", "id"], name: "index_accounts_on_domain_and_id"
|
t.index ["domain", "id"], name: "index_accounts_on_domain_and_id"
|
||||||
t.index ["moved_to_account_id"], name: "index_accounts_on_moved_to_account_id", where: "(moved_to_account_id IS NOT NULL)"
|
t.index ["moved_to_account_id"], name: "index_accounts_on_moved_to_account_id", where: "(moved_to_account_id IS NOT NULL)"
|
||||||
|
t.index ["remote_pending"], name: "index_accounts_on_remote_pending"
|
||||||
t.index ["uri"], name: "index_accounts_on_uri"
|
t.index ["uri"], name: "index_accounts_on_uri"
|
||||||
t.index ["url"], name: "index_accounts_on_url", opclass: :text_pattern_ops, where: "(url IS NOT NULL)"
|
t.index ["url"], name: "index_accounts_on_url", opclass: :text_pattern_ops, where: "(url IS NOT NULL)"
|
||||||
end
|
end
|
||||||
|
|
|
@ -86,6 +86,7 @@ namespace :dangerous do
|
||||||
20240212230358
|
20240212230358
|
||||||
20240216042730
|
20240216042730
|
||||||
20240217022038
|
20240217022038
|
||||||
|
20240217093511
|
||||||
)
|
)
|
||||||
# Removed: account_groups
|
# Removed: account_groups
|
||||||
target_tables = %w(
|
target_tables = %w(
|
||||||
|
@ -112,6 +113,7 @@ namespace :dangerous do
|
||||||
%w(accounts group_allow_private_message),
|
%w(accounts group_allow_private_message),
|
||||||
# Removed: accounts group_message_following_only
|
# Removed: accounts group_message_following_only
|
||||||
%w(accounts master_settings),
|
%w(accounts master_settings),
|
||||||
|
%w(accounts remote_pending),
|
||||||
%w(accounts searchability),
|
%w(accounts searchability),
|
||||||
%w(accounts settings),
|
%w(accounts settings),
|
||||||
# Removed: accounts stop_emoji_reaction_streaming
|
# Removed: accounts stop_emoji_reaction_streaming
|
||||||
|
|
|
@ -30,13 +30,17 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do
|
||||||
it 'created account in a simple case' do
|
it 'created account in a simple case' do
|
||||||
expect(subject).to_not be_nil
|
expect(subject).to_not be_nil
|
||||||
expect(subject.uri).to eq 'https://foo.test'
|
expect(subject.uri).to eq 'https://foo.test'
|
||||||
|
expect(subject.suspended?).to be false
|
||||||
|
expect(subject.remote_pending).to be false
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when is blocked' do
|
context 'when is blocked' do
|
||||||
let(:permit_new_account_domains) { ['foo.bar'] }
|
let(:permit_new_account_domains) { ['foo.bar'] }
|
||||||
|
|
||||||
it 'does not create account' do
|
it 'creates pending account' do
|
||||||
expect(subject).to be_nil
|
expect(subject).to_not be_nil
|
||||||
|
expect(subject.suspended?).to be true
|
||||||
|
expect(subject.remote_pending).to be true
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with has existing account' do
|
context 'with has existing account' do
|
||||||
|
@ -46,9 +50,39 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do
|
||||||
|
|
||||||
it 'updated account' do
|
it 'updated account' do
|
||||||
expect(subject).to_not be_nil
|
expect(subject).to_not be_nil
|
||||||
|
expect(subject.suspended?).to be false
|
||||||
|
expect(subject.remote_pending).to be false
|
||||||
expect(subject.note).to eq 'new bio'
|
expect(subject.note).to eq 'new bio'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with has existing suspended pending account' do
|
||||||
|
before do
|
||||||
|
Fabricate(:account, uri: 'https://foo.test', domain: 'example.com', username: 'alice', note: 'old bio', suspended_at: 1.day.ago, remote_pending: true, suspension_origin: :local)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updated account' do
|
||||||
|
expect(subject).to_not be_nil
|
||||||
|
expect(subject.suspended?).to be true
|
||||||
|
expect(subject.remote_pending).to be true
|
||||||
|
expect(subject.suspension_origin_local?).to be true
|
||||||
|
expect(subject.note).to eq 'new bio'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with has existing suspended account' do
|
||||||
|
before do
|
||||||
|
Fabricate(:account, uri: 'https://foo.test', domain: 'example.com', username: 'alice', note: 'old bio', suspended_at: 1.day.ago, suspension_origin: :local)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not update account' do
|
||||||
|
expect(subject).to_not be_nil
|
||||||
|
expect(subject.suspended?).to be true
|
||||||
|
expect(subject.remote_pending).to be false
|
||||||
|
expect(subject.suspension_origin_local?).to be true
|
||||||
|
expect(subject.note).to eq 'old bio'
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when is in whitelist' do
|
context 'when is in whitelist' do
|
||||||
|
@ -57,6 +91,8 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do
|
||||||
it 'does not create account' do
|
it 'does not create account' do
|
||||||
expect(subject).to_not be_nil
|
expect(subject).to_not be_nil
|
||||||
expect(subject.uri).to eq 'https://foo.test'
|
expect(subject.uri).to eq 'https://foo.test'
|
||||||
|
expect(subject.suspended?).to be false
|
||||||
|
expect(subject.remote_pending).to be false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue