diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 25289a77d2..7baf55a133 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -46,6 +46,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def create_status return reject_payload! if unsupported_object_type? || non_matching_uri_hosts?(@account.uri, object_uri) || tombstone_exists? || !related_to_local_activity? + return reject_payload! if (reply_to_local? || reply_to_local_account?) && reject_reply_to_local? with_lock("create:#{object_uri}") do return if delete_arrived_first?(object_uri) || poll_vote? @@ -136,7 +137,13 @@ class ActivityPub::Activity::Create < ActivityPub::Activity } end - def process_audience + def reply_to_local_account? + accounts_in_audience.any?(&:local?) + end + + def accounts_in_audience + return @accounts_in_audience if @accounts_in_audience + # Unlike with tags, there is no point in resolving accounts we don't already # know here, because silent mentions would only be used for local access control anyway accounts_in_audience = (audience_to + audience_cc).uniq.filter_map do |audience| @@ -150,6 +157,10 @@ class ActivityPub::Activity::Create < ActivityPub::Activity accounts_in_audience.uniq! end + @accounts_in_audience = accounts_in_audience + end + + def process_audience accounts_in_audience.each do |account| # This runs after tags are processed, and those translate into non-silent # mentions, which take precedence diff --git a/app/lib/status_reach_finder.rb b/app/lib/status_reach_finder.rb index b326f098c7..85503db2c0 100644 --- a/app/lib/status_reach_finder.rb +++ b/app/lib/status_reach_finder.rb @@ -14,7 +14,11 @@ class StatusReachFinder end def inboxes_for_misskey - (reached_account_inboxes_for_misskey + followers_inboxes_for_misskey).uniq + if banned_domains_for_misskey.empty? + [] + else + (reached_account_inboxes_for_misskey + followers_inboxes_for_misskey).uniq + end end private @@ -121,26 +125,28 @@ class StatusReachFinder domains = banned_domains_of_status(@status) domains += banned_domains_of_status(@status.reblog) if @status.reblog? && @status.reblog.local? - @banned_domains = domains.uniq + @banned_domains = domains.uniq + banned_domains_for_misskey end def banned_domains_of_status(status) - blocks = DomainBlock.where(domain: nil) - unless status.account.user&.setting_send_without_domain_blocks + if status.account.user&.setting_send_without_domain_blocks + [] + else + blocks = DomainBlock.where(domain: nil) blocks = blocks.or(DomainBlock.where(reject_send_not_public_searchability: true)) if status.compute_searchability != 'public' blocks = blocks.or(DomainBlock.where(reject_send_public_unlisted: true)) if status.public_unlisted_visibility? blocks = blocks.or(DomainBlock.where(reject_send_dissubscribable: true)) if status.account.dissubscribable blocks = blocks.or(DomainBlock.where(reject_send_media: true)) if status.with_media? blocks = blocks.or(DomainBlock.where(reject_send_sensitive: true)) if (status.with_media? && status.sensitive) || status.spoiler_text? + blocks.pluck(:domain).uniq end - blocks = blocks.or(DomainBlock.where(detect_invalid_subscription: true)) if status.public_unlisted_visibility? && status.account.user&.setting_reject_public_unlisted_subscription - blocks = blocks.or(DomainBlock.where(detect_invalid_subscription: true)) if status.unlisted_visibility? && status.account.user&.setting_reject_unlisted_subscription - blocks.pluck(:domain).uniq end def banned_domains_for_misskey return @banned_domains_for_misskey if @banned_domains_for_misskey + return @banned_domains_for_misskey = [] if (!@status.account.user&.reject_public_unlisted_subscription? && !@status.account.user&.reject_unlisted_subscription?) || (!@status.public_unlisted_visibility? && !@status.unlisted_visibility?) + domains = banned_domains_for_misskey_of_status(@status) domains += banned_domains_for_misskey_of_status(@status.reblog) if @status.reblog? && @status.reblog.local? @banned_domains_for_misskey = domains.uniq diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index 12367c11d8..62a9edd500 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -122,12 +122,17 @@ class FanOutOnWriteService < BaseService domain = @account.domain || Rails.configuration.x.local_domain antennas = Antenna.availables - antennas = antennas.left_joins(:antenna_accounts).where(any_accounts: true).or(Antenna.availables.left_joins(:antenna_accounts).where(antenna_accounts: { exclude: false, account: @account })) - antennas = antennas.left_joins(:antenna_domains).where(any_domains: true).or(Antenna.availables.left_joins(:antenna_accounts).left_joins(:antenna_domains).where(antenna_domains: { exclude: false, name: domain })) - antennas = antennas.left_joins(:antenna_tags).where(any_tags: true).or(Antenna.availables.left_joins(:antenna_accounts).left_joins(:antenna_domains).left_joins(:antenna_tags).where(antenna_tags: { exclude: false, tag: @status.tags })) - antennas = antennas.where(account: @account.followers) if @status.visibility.to_sym == :unlisted + antennas = antennas.left_joins(:antenna_domains).where(any_domains: true).or(Antenna.left_joins(:antenna_domains).where(antenna_domains: { name: domain })) antennas = antennas.where(with_media_only: false) unless @status.with_media? antennas = antennas.where.not(account: @account.blocking) + + antennas = Antenna.where(id: antennas.select(:id)) + antennas = antennas.left_joins(:antenna_accounts).where(any_accounts: true).or(Antenna.left_joins(:antenna_accounts).where(antenna_accounts: { account: @account })) + + tag_ids = @status.tags.pluck(:id) + antennas = Antenna.where(id: antennas.select(:id)) + antennas = antennas.left_joins(:antenna_tags).where(any_tags: true).or(Antenna.left_joins(:antenna_tags).where(antenna_tags: { tag_id: tag_ids })) + antennas.in_batches do |ans| ans.each do |antenna| next unless antenna.enabled? diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb index ea799db57f..7228f110d2 100644 --- a/app/services/remove_status_service.rb +++ b/app/services/remove_status_service.rb @@ -88,7 +88,7 @@ class RemoveStatusService < BaseService status_reach_finder = StatusReachFinder.new(@status, unsafe: true) - ActivityPub::DeliveryWorker.push_bulk(status_reach_finder.inboxes, limit: 1_000) do |inbox_url| + ActivityPub::DeliveryWorker.push_bulk(status_reach_finder.inboxes + status_reach_finder.inboxes_for_misskey, limit: 1_000) do |inbox_url| [signed_activity_json, @account.id, inbox_url] end end diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index 0f3aee682f..a44c418c7c 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -35,6 +35,8 @@ .fields-group = ff.input :show_application, wrapper: :with_label, recommended: true, label: I18n.t('simple_form.labels.defaults.setting_show_application'), hint: I18n.t('simple_form.hints.defaults.setting_show_application') + %h4= t 'preferences.stop_deliver' + .fields-group = f.input :setting_send_without_domain_blocks, as: :boolean, wrapper: :with_label diff --git a/app/workers/activitypub/raw_distribution_worker.rb b/app/workers/activitypub/raw_distribution_worker.rb index 28a3b1c796..611b5210d8 100644 --- a/app/workers/activitypub/raw_distribution_worker.rb +++ b/app/workers/activitypub/raw_distribution_worker.rb @@ -23,16 +23,16 @@ class ActivityPub::RawDistributionWorker protected def distribute! - unless inboxes.empty? - ActivityPub::DeliveryWorker.push_bulk(inboxes, limit: 1_000) do |inbox_url| - [payload, source_account_id, inbox_url, options] + unless inboxes_for_misskey.empty? + ActivityPub::DeliveryWorker.push_bulk(inboxes_for_misskey, limit: 1_000) do |inbox_url| + [payload_for_misskey, source_account_id, inbox_url, options] end end - return if inboxes_for_misskey.empty? + return if inboxes.empty? - ActivityPub::DeliveryWorker.push_bulk(inboxes_for_misskey, limit: 1_000) do |inbox_url| - [payload_for_misskey, source_account_id, inbox_url, options] + ActivityPub::DeliveryWorker.push_bulk(inboxes, limit: 1_000) do |inbox_url| + [payload, source_account_id, inbox_url, options] end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 276a959cab..df8f68a35a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1498,6 +1498,7 @@ en: other: Other posting_defaults: Posting defaults public_timelines: Public timelines + stop_deliver: Stop delivering privacy_policy: title: Privacy Policy reactions: diff --git a/config/locales/ja.yml b/config/locales/ja.yml index b1aadc1df4..e9e0744581 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -1488,6 +1488,7 @@ ja: other: その他 posting_defaults: デフォルトの投稿設定 public_timelines: 公開タイムライン + stop_deliver: 配送停止 privacy_policy: title: プライバシーポリシー reactions: diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index 9608a97ac3..ce33febd88 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -63,7 +63,7 @@ ja: setting_display_media_expand: Misskeyなどは4個を超えて投稿可能です。その追加分を最大8個まで表示します。kmyblueからアップロードはできません setting_noindex: 公開プロフィールおよび各投稿ページに影響します setting_public_post_to_unlisted: 未対応のサードパーティアプリからもローカル公開で投稿できますが、公開投稿はWeb以外できなくなります - setting_reject_unlisted_subscription: Misskeyやそのフォーク(Calckeyなど)は、フォローしていないアカウントの「未収載」投稿を **購読・検索** することができます。これはMastodonにおける「未収載」投稿の基本的な考え方、扱い方と矛盾します。そのようなサーバーのうち管理人が指定したものに、指定した公開範囲の投稿を「フォロワーのみ」として配送します。ただし構造上、完璧な対応は困難でたまに未収載として配信されること、ご理解ください + setting_reject_unlisted_subscription: Misskeyやそのフォーク(Calckeyなど)は、フォローしていないアカウントの「未収載」投稿を **購読・検索** することができます。これはkmyblueの挙動と異なります。そのようなサーバーのうち管理人が指定したものに、指定した公開範囲の投稿を「フォロワーのみ」として配送します。ただし構造上、完璧な対応は困難でたまに未収載として配信されること、ご理解ください setting_show_application: 投稿するのに使用したアプリが投稿の詳細ビューに表示されるようになります setting_use_blurhash: ぼかしはメディアの色を元に生成されますが、細部は見えにくくなっています setting_use_pending_items: 新着があってもタイムラインを自動的にスクロールしないようにします