diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index eb3d618551..831e518af5 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -442,6 +442,7 @@ Rails/SkipsModelValidations: - 'db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb' - 'db/migrate/20191007013357_update_pt_locales.rb' - 'db/migrate/20220316233212_update_kurdish_locales.rb' + - 'db/migrate/20240109035435_remove_hidden_anonymous_from_domain_blocks.rb' - 'db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb' - 'db/post_migrate/20200917193528_migrate_notifications_type.rb' - 'db/post_migrate/20201017234926_fill_account_suspension_origin.rb' diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz new file mode 100644 index 0000000000..4dc538b2ca Binary files /dev/null and b/.yarn/install-state.gz differ diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb index c91b9b7163..11ea8fb566 100644 --- a/app/controllers/admin/domain_blocks_controller.rb +++ b/app/controllers/admin/domain_blocks_controller.rb @@ -88,18 +88,18 @@ module Admin end def update_params - params.require(:domain_block).permit(:severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_send_not_public_searchability, :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, :reject_send_sensitive, :reject_hashtag, - :reject_straight_follow, :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden, :hidden_anonymous) + params.require(:domain_block).permit(:severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_send_sensitive, :reject_hashtag, + :reject_straight_follow, :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden) end def resource_params - params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_send_not_public_searchability, :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, :reject_send_sensitive, :reject_hashtag, - :reject_straight_follow, :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden, :hidden_anonymous) + params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_send_sensitive, :reject_hashtag, + :reject_straight_follow, :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden) end def form_domain_block_batch_params - params.require(:form_domain_block_batch).permit(domain_blocks_attributes: [:enabled, :domain, :severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_send_not_public_searchability, :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, - :reject_send_sensitive, :reject_hashtag, :reject_straight_follow, :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden, :hidden_anonymous]) + params.require(:form_domain_block_batch).permit(domain_blocks_attributes: [:enabled, :domain, :severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, + :reject_send_sensitive, :reject_hashtag, :reject_straight_follow, :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden]) end def action_from_button diff --git a/app/controllers/api/v1/admin/domain_blocks_controller.rb b/app/controllers/api/v1/admin/domain_blocks_controller.rb index bd0660dbaa..6dbf58d2da 100644 --- a/app/controllers/api/v1/admin/domain_blocks_controller.rb +++ b/app/controllers/api/v1/admin/domain_blocks_controller.rb @@ -69,8 +69,8 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController end def domain_block_params - params.permit(:severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_reports, :reject_send_not_public_searchability, :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, :reject_send_sensitive, :reject_hashtag, :reject_straight_follow, - :reject_new_follow, :detect_invalid_subscription, :private_comment, :public_comment, :obfuscate, :hidden, :hidden_anonymous) + params.permit(:severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_reports, :reject_send_sensitive, :reject_hashtag, :reject_straight_follow, + :reject_new_follow, :detect_invalid_subscription, :private_comment, :public_comment, :obfuscate, :hidden) end def insert_pagination_headers @@ -102,7 +102,7 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController end def resource_params - params.permit(:domain, :severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_send_not_public_searchability, :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, :reject_send_sensitive, :reject_hashtag, :reject_straight_follow, - :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden, :hidden_anonymous) + params.permit(:domain, :severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_send_sensitive, :reject_hashtag, :reject_straight_follow, + :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden) end end diff --git a/app/controllers/api/v1/instances/domain_blocks_controller.rb b/app/controllers/api/v1/instances/domain_blocks_controller.rb index e91f48e1db..c91234e088 100644 --- a/app/controllers/api/v1/instances/domain_blocks_controller.rb +++ b/app/controllers/api/v1/instances/domain_blocks_controller.rb @@ -26,6 +26,5 @@ class Api::V1::Instances::DomainBlocksController < Api::BaseController def set_domain_blocks @domain_blocks = DomainBlock.with_user_facing_limitations.by_severity - @domain_blocks = @domain_blocks.filter { |block| !block.hidden_anonymous } unless user_signed_in? end end diff --git a/app/lib/account_statuses_filter.rb b/app/lib/account_statuses_filter.rb index 9a4a2b5d6e..b5c63c1693 100644 --- a/app/lib/account_statuses_filter.rb +++ b/app/lib/account_statuses_filter.rb @@ -29,9 +29,8 @@ class AccountStatusesFilter available_searchabilities = [:public, :unlisted, :private, :direct, :limited, nil] available_visibilities = [:public, :public_unlisted, :login, :unlisted, :private, :direct, :limited] - available_searchabilities = [:public] if domain_block&.reject_send_not_public_searchability - available_visibilities -= [:public_unlisted] if domain_block&.reject_send_public_unlisted || (domain_block&.detect_invalid_subscription && @account.user&.setting_reject_public_unlisted_subscription) - available_visibilities -= [:unlisted] if domain_block&.detect_invalid_subscription && @account.user&.setting_reject_unlisted_subscription + available_visibilities -= [:public_unlisted] if (domain_block&.detect_invalid_subscription || misskey_software?) && @account.user&.setting_reject_public_unlisted_subscription + available_visibilities -= [:unlisted] if (domain_block&.detect_invalid_subscription || misskey_software?) && @account.user&.setting_reject_unlisted_subscription available_visibilities -= [:login] if current_account.nil? scope.merge!(scope.where(spoiler_text: ['', nil])) if domain_block&.reject_send_sensitive @@ -44,7 +43,7 @@ class AccountStatusesFilter private def initial_scope - if (suspended? || (domain_block&.reject_send_dissubscribable && @account.dissubscribable)) || domain_block&.reject_send_media || blocked? + if suspended? || blocked? Status.none elsif anonymous? account.statuses.where(visibility: %i(public unlisted public_unlisted)) @@ -156,6 +155,21 @@ class AccountStatusesFilter end def domain_block - @domain_block = DomainBlock.find_by(domain: @account&.domain) + return nil if @account.nil? || @account.local? + + @domain_block = DomainBlock.find_by(domain: @account.domain) + end + + def misskey_software? + return false if @account.nil? || @account.local? + return false if instance_info.nil? + + %w(misskey cherrypick).include?(instance_info.software) + end + + def instance_info + return @instance_info if defined?(@instance_info) + + @instance_info = InstanceInfo.find_by(domain: @account.domain) end end diff --git a/app/lib/status_reach_finder.rb b/app/lib/status_reach_finder.rb index c7069c7dac..203d7d14f7 100644 --- a/app/lib/status_reach_finder.rb +++ b/app/lib/status_reach_finder.rb @@ -143,10 +143,6 @@ class StatusReachFinder [] 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 diff --git a/app/lib/vacuum/feeds_vacuum.rb b/app/lib/vacuum/feeds_vacuum.rb index fb0b8a8472..a9e96accdd 100644 --- a/app/lib/vacuum/feeds_vacuum.rb +++ b/app/lib/vacuum/feeds_vacuum.rb @@ -4,6 +4,7 @@ class Vacuum::FeedsVacuum def perform vacuum_inactive_home_feeds! vacuum_inactive_list_feeds! + vacuum_inactive_antenna_feeds! end private @@ -20,6 +21,12 @@ class Vacuum::FeedsVacuum end end + def vacuum_inactive_antenna_feeds! + inactive_users_antennas.select(:id).in_batches do |antennas| + feed_manager.clean_feeds!(:antenna, antennas.ids) + end + end + def inactive_users User.confirmed.inactive end @@ -28,6 +35,10 @@ class Vacuum::FeedsVacuum List.where(account_id: inactive_users.select(:account_id)) end + def inactive_users_antennas + Antenna.where(account_id: inactive_users.select(:account_id)) + end + def feed_manager FeedManager.instance end diff --git a/app/models/antenna.rb b/app/models/antenna.rb index a35fa6dd17..c64e66bde2 100644 --- a/app/models/antenna.rb +++ b/app/models/antenna.rb @@ -55,11 +55,15 @@ class Antenna < ApplicationRecord scope :available_stls, -> { where(available: true, stl: true) } scope :available_ltls, -> { where(available: true, stl: false, ltl: true) } + validates :title, presence: true + validate :list_owner validate :validate_limit validate :validate_stl_limit validate :validate_ltl_limit + before_destroy :clean_feed_manager + def list_owner raise Mastodon::ValidationError, I18n.t('antennas.errors.invalid_list_owner') if !list_id.zero? && list.present? && list.account != account end @@ -121,4 +125,8 @@ class Antenna < ApplicationRecord ltls.any? { |tl| !tl.insert_feeds } end end + + def clean_feed_manager + FeedManager.instance.clean_feeds!(:antenna, [id]) + end end diff --git a/app/models/domain_block.rb b/app/models/domain_block.rb index b05fa19476..d7ac1287e3 100644 --- a/app/models/domain_block.rb +++ b/app/models/domain_block.rb @@ -25,7 +25,6 @@ # reject_straight_follow :boolean default(FALSE), not null # reject_new_follow :boolean default(FALSE), not null # hidden :boolean default(FALSE), not null -# hidden_anonymous :boolean default(FALSE), not null # detect_invalid_subscription :boolean default(FALSE), not null # reject_reply_exclude_followers :boolean default(FALSE), not null # @@ -60,10 +59,6 @@ class DomainBlock < ApplicationRecord reject_favourite? ? :reject_favourite : nil, reject_reply? ? :reject_reply : nil, reject_reply_exclude_followers? ? :reject_reply_exclude_followers : nil, - reject_send_not_public_searchability? ? :reject_send_not_public_searchability : nil, - reject_send_public_unlisted? ? :reject_send_public_unlisted : nil, - reject_send_dissubscribable? ? :reject_send_dissubscribable : nil, - reject_send_media? ? :reject_send_media : nil, reject_send_sensitive? ? :reject_send_sensitive : nil, reject_hashtag? ? :reject_hashtag : nil, reject_straight_follow? ? :reject_straight_follow : nil, diff --git a/app/policies/status_policy.rb b/app/policies/status_policy.rb index 335abe9e92..b9a1eec72d 100644 --- a/app/policies/status_policy.rb +++ b/app/policies/status_policy.rb @@ -121,12 +121,8 @@ class StatusPolicy < ApplicationPolicy (@domain_block.detect_invalid_subscription && status.public_unlisted_visibility? && status.account.user&.setting_reject_public_unlisted_subscription) || (@domain_block.detect_invalid_subscription && status.public_visibility? && status.account.user&.setting_reject_unlisted_subscription) else - (@domain_block.reject_send_not_public_searchability && status.compute_searchability != 'public') || - (@domain_block.reject_send_public_unlisted && status.public_unlisted_visibility?) || - (@domain_block.reject_send_dissubscribable && status.account.dissubscribable) || - (@domain_block.detect_invalid_subscription && status.public_unlisted_visibility? && status.account.user&.setting_reject_public_unlisted_subscription) || + (@domain_block.detect_invalid_subscription && status.public_unlisted_visibility? && status.account.user&.setting_reject_public_unlisted_subscription) || (@domain_block.detect_invalid_subscription && status.public_visibility? && status.account.user&.setting_reject_unlisted_subscription) || - (@domain_block.reject_send_media && status.with_media?) || (@domain_block.reject_send_sensitive && ((status.with_media? && status.sensitive) || status.spoiler_text?)) end else diff --git a/app/serializers/nodeinfo/serializer.rb b/app/serializers/nodeinfo/serializer.rb index 3555f0bd8d..b316753c72 100644 --- a/app/serializers/nodeinfo/serializer.rb +++ b/app/serializers/nodeinfo/serializer.rb @@ -11,7 +11,7 @@ class NodeInfo::Serializer < ActiveModel::Serializer end def software - { name: 'mastodon', version: Mastodon::Version.to_s } + { name: 'kmyblue', version: Mastodon::Version.to_s } end def services @@ -41,6 +41,10 @@ class NodeInfo::Serializer < ActiveModel::Serializer def metadata { features: fedibird_capabilities, + upstream: { + name: 'Mastodon', + version: Mastodon::Version.to_s_of_mastodon, + }, } end diff --git a/app/serializers/rest/admin/domain_block_serializer.rb b/app/serializers/rest/admin/domain_block_serializer.rb index e7cdc40ad1..e86fd2fe2d 100644 --- a/app/serializers/rest/admin/domain_block_serializer.rb +++ b/app/serializers/rest/admin/domain_block_serializer.rb @@ -3,8 +3,8 @@ class REST::Admin::DomainBlockSerializer < ActiveModel::Serializer attributes :id, :domain, :created_at, :severity, :reject_media, :reject_favourite, :reject_reply, :reject_reports, - :reject_send_not_public_searchability, :reject_reply_exclude_followers, - :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, :reject_send_sensitive, + :reject_reply_exclude_followers, + :reject_send_sensitive, :reject_hashtag, :reject_straight_follow, :reject_new_follow, :detect_invalid_subscription, :private_comment, :public_comment, :obfuscate diff --git a/app/views/admin/domain_blocks/edit.html.haml b/app/views/admin/domain_blocks/edit.html.haml index 8a06441508..a2148e6806 100644 --- a/app/views/admin/domain_blocks/edit.html.haml +++ b/app/views/admin/domain_blocks/edit.html.haml @@ -23,18 +23,6 @@ .fields-group = f.input :reject_reply_exclude_followers, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_reply_exclude_followers'), hint: I18n.t('admin.domain_blocks.reject_reply_exclude_followers_hint') - .fields-group - = f.input :reject_send_not_public_searchability, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_send_not_public_searchability'), hint: I18n.t('admin.domain_blocks.reject_send_not_public_searchability_hint') - - .fields-group - = f.input :reject_send_dissubscribable, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_send_dissubscribable'), hint: I18n.t('admin.domain_blocks.reject_send_dissubscribable_hint') - - .fields-group - = f.input :reject_send_public_unlisted, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_send_public_unlisted'), hint: I18n.t('admin.domain_blocks.reject_send_public_unlisted_hint') - - .fields-group - = f.input :reject_send_media, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_send_media'), hint: I18n.t('admin.domain_blocks.reject_send_media_hint') - .fields-group = f.input :reject_send_sensitive, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_send_sensitive'), hint: I18n.t('admin.domain_blocks.reject_send_sensitive_hint') @@ -65,8 +53,5 @@ .fields-group = f.input :hidden, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.hidden'), hint: I18n.t('admin.domain_blocks.hidden_hint') - .fields-group - = f.input :hidden_anonymous, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.hidden_anonymous'), hint: I18n.t('admin.domain_blocks.hidden_anonymous_hint') - .actions = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/admin/domain_blocks/new.html.haml b/app/views/admin/domain_blocks/new.html.haml index 606a784e12..eda02e3207 100644 --- a/app/views/admin/domain_blocks/new.html.haml +++ b/app/views/admin/domain_blocks/new.html.haml @@ -23,18 +23,6 @@ .fields-group = f.input :reject_reply_exclude_followers, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_reply_exclude_followers'), hint: I18n.t('admin.domain_blocks.reject_reply_exclude_followers_hint') - .fields-group - = f.input :reject_send_not_public_searchability, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_send_not_public_searchability'), hint: I18n.t('admin.domain_blocks.reject_send_not_public_searchability_hint') - - .fields-group - = f.input :reject_send_dissubscribable, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_send_dissubscribable'), hint: I18n.t('admin.domain_blocks.reject_send_dissubscribable_hint') - - .fields-group - = f.input :reject_send_public_unlisted, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_send_public_unlisted'), hint: I18n.t('admin.domain_blocks.reject_send_public_unlisted_hint') - - .fields-group - = f.input :reject_send_media, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_send_media'), hint: I18n.t('admin.domain_blocks.reject_send_media_hint') - .fields-group = f.input :reject_send_sensitive, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_send_sensitive'), hint: I18n.t('admin.domain_blocks.reject_send_sensitive_hint') @@ -65,8 +53,5 @@ .fields-group = f.input :hidden, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.hidden'), hint: I18n.t('admin.domain_blocks.hidden_hint') - .fields-group - = f.input :hidden_anonymous, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.hidden_anonymous'), hint: I18n.t('admin.domain_blocks.hidden_anonymous_hint') - .actions = f.button :button, t('.create'), type: :submit diff --git a/app/views/admin/export_domain_blocks/_domain_block.html.haml b/app/views/admin/export_domain_blocks/_domain_block.html.haml index 6b2f0227f5..4789c4801b 100644 --- a/app/views/admin/export_domain_blocks/_domain_block.html.haml +++ b/app/views/admin/export_domain_blocks/_domain_block.html.haml @@ -13,10 +13,6 @@ = f.hidden_field :reject_favourite = f.hidden_field :reject_reply = f.hidden_field :reject_reply_exclude_followers - = f.hidden_field :reject_send_not_public_searchability - = f.hidden_field :reject_send_public_unlisted - = f.hidden_field :reject_send_dissubscribable - = f.hidden_field :reject_send_media = f.hidden_field :reject_send_sensitive = f.hidden_field :reject_hashtag = f.hidden_field :reject_straight_follow diff --git a/app/workers/scheduler/sidekiq_health_scheduler.rb b/app/workers/scheduler/sidekiq_health_scheduler.rb deleted file mode 100644 index 646976d831..0000000000 --- a/app/workers/scheduler/sidekiq_health_scheduler.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -class Scheduler::SidekiqHealthScheduler - include Sidekiq::Worker - - sidekiq_options retry: 0, lock: :until_executed, lock_ttl: 15.seconds.to_i - - def perform - url = ENV.fetch('SIDEKIQ_HEALTH_FETCH_URL', nil) - Request.new(:head, url).perform if url.present? - end -end diff --git a/config/locales/en.yml b/config/locales/en.yml index ecb59c9463..8ae21027b7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -438,14 +438,6 @@ en: reject_reply_exclude_followers_hint: Reject replies exclude followers in the future reject_reports: Reject reports reject_reports_hint: Ignore all reports coming from this domain. Irrelevant for suspensions - reject_send_dissubscribable: 購読拒否アカウントの投稿を配送しない - reject_send_dissubscribable_hint: 相手サーバーからのフェッチは防げません。停止とは無関係です - reject_send_media: 画像付き投稿を配送しない - reject_send_media_hint: 相手サーバーからのフェッチは防げません。停止とは無関係です - reject_send_not_public_searchability: 検索許可が「誰でも」でない投稿を配送しない - reject_send_not_public_searchability_hint: 相手サーバーからのフェッチは防げません。停止とは無関係です - reject_send_public_unlisted: ローカル公開投稿を配送しない - reject_send_public_unlisted_hint: 相手サーバーからのフェッチは防げません。停止とは無関係です reject_send_sensitive: センシティブな投稿を配送しない reject_send_sensitive_hint: 相手サーバーからのフェッチは防げません。停止とは無関係です reject_send_unlisted_dissubscribable: 購読拒否アカウントの未収載投稿を配送しない diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 85cb345e21..96fd4ea592 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -400,8 +400,6 @@ ja: export: エクスポート hidden: 非公開にする hidden_hint: 公開することで当サーバーの安全が脅かされる場合、このドメインブロックを非公開にすることができます。 - hidden_anonymous: 未ログインユーザーに非公開にする - hidden_anonymous_hint: 公開することで当サーバーの安全が脅かされる場合、非ログインユーザーに限りこのドメインブロックを非公開にすることができます。 import: インポート new: create: ブロックを作成 @@ -434,14 +432,6 @@ ja: reject_reply_exclude_followers_hint: 今後のリプライを拒否します。停止とは無関係です reject_reports: 通報を拒否 reject_reports_hint: このドメインからの通報をすべて無視します。停止とは無関係です - reject_send_dissubscribable: 購読拒否アカウントの投稿を配送しない - reject_send_dissubscribable_hint: 相手サーバーからのフェッチは防げません。停止とは無関係です - reject_send_media: 画像付き投稿を配送しない - reject_send_media_hint: 相手サーバーからのフェッチは防げません。停止とは無関係です - reject_send_not_public_searchability: 検索許可が「誰でも」でない投稿を配送しない - reject_send_not_public_searchability_hint: 相手サーバーからのフェッチは防げません。停止とは無関係です - reject_send_public_unlisted: ローカル公開投稿を配送しない - reject_send_public_unlisted_hint: 相手サーバーからのフェッチは防げません。停止とは無関係です reject_send_sensitive: センシティブな投稿を配送しない reject_send_sensitive_hint: 相手サーバーからのフェッチは防げません。停止とは無関係です reject_send_unlisted_dissubscribable: 購読拒否アカウントの未収載投稿を配送しない @@ -520,10 +510,6 @@ ja: reject_reply: リプライを拒否 reject_reply_exclude_followers: フォロー相手以外からのリプライを拒否 reject_reports: 通報を拒否 - reject_send_dissubscribable: 購読拒否投稿配送なし - reject_send_media: メディア付き投稿配送なし - reject_send_not_public_searchability: 検索許可全て投稿配送なし - reject_send_public_unlisted: ローカル公開投稿配送なし reject_send_sensitive: センシティブ投稿配送なし reject_send_unlisted_dissubscribable: 購読拒否未収載投稿配送なし reject_straight_follow: フォローを制限 diff --git a/config/sidekiq.yml b/config/sidekiq.yml index b643a1ecfb..f1ba5651dd 100644 --- a/config/sidekiq.yml +++ b/config/sidekiq.yml @@ -58,10 +58,6 @@ interval: 1 minute class: Scheduler::SuspendedUserCleanupScheduler queue: scheduler - sidekiq_health_scheduler: - interval: 30 seconds - class: Scheduler::SidekiqHealthScheduler - queue: scheduler software_update_check_scheduler: interval: 30 minutes class: Scheduler::SoftwareUpdateCheckScheduler diff --git a/db/migrate/20240109035435_remove_hidden_anonymous_from_domain_blocks.rb b/db/migrate/20240109035435_remove_hidden_anonymous_from_domain_blocks.rb new file mode 100644 index 0000000000..d1272cd79f --- /dev/null +++ b/db/migrate/20240109035435_remove_hidden_anonymous_from_domain_blocks.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class RemoveHiddenAnonymousFromDomainBlocks < ActiveRecord::Migration[7.0] + class DomainBlock < ApplicationRecord; end + + def up + safety_assured do + DomainBlock.where(hidden_anonymous: true, hidden: false).update_all(hidden: true) + remove_column :domain_blocks, :hidden_anonymous + end + end + + def down + safety_assured do + add_column :domain_blocks, :hidden_anonymous, :boolean, null: false, default: false + end + end +end diff --git a/db/schema.rb b/db/schema.rb index f8fd9283e0..8542eb9450 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_12_12_225737) do +ActiveRecord::Schema[7.0].define(version: 2024_01_09_035435) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -570,7 +570,6 @@ ActiveRecord::Schema[7.0].define(version: 2023_12_12_225737) do t.boolean "reject_straight_follow", default: false, null: false t.boolean "reject_new_follow", default: false, null: false t.boolean "hidden", default: false, null: false - t.boolean "hidden_anonymous", default: false, null: false t.boolean "detect_invalid_subscription", default: false, null: false t.boolean "reject_reply_exclude_followers", default: false, null: false t.index ["domain"], name: "index_domain_blocks_on_domain", unique: true diff --git a/lib/mastodon/cli/feeds.rb b/lib/mastodon/cli/feeds.rb index 3467dd427c..4f2de4ebb4 100644 --- a/lib/mastodon/cli/feeds.rb +++ b/lib/mastodon/cli/feeds.rb @@ -48,10 +48,35 @@ module Mastodon::CLI say('OK', :green) end + desc 'remove_legacy', 'Remove old list and antenna feeds from Redis' + def remove_legacy + current_id = 1 + List.reorder(:id).select(:id).find_in_batches do |lists| + current_id = remove_legacy_feeds(:list, lists, current_id) + end + + current_id = 1 + Antenna.reorder(:id).select(:id).find_in_batches do |antennas| + current_id = remove_legacy_feeds(:antenna, antennas, current_id) + end + + say('OK', :green) + end + private def active_user_accounts Account.joins(:user).merge(User.active) end + + def remove_legacy_feeds(type, items, current_id) + exist_ids = items.pluck(:id) + last_id = exist_ids.max + + ids = Range.new(current_id, last_id).to_a - exist_ids + FeedManager.instance.clean_feeds!(type, ids) + + last_id + 1 + end end end diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 0e819ce52c..debbdfee53 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -9,7 +9,7 @@ module Mastodon end def kmyblue_minor - 12 + 13 end def kmyblue_flag @@ -46,8 +46,19 @@ module Mastodon components.join end + def to_s_of_mastodon + components = [to_a.join('.')] + components << "-#{prerelease}" if prerelease.present? + components << "+#{build_metadata_of_mastodon}" if build_metadata_of_mastodon.present? + components.join + end + def build_metadata - ['kmyblue', to_s_of_kmyblue, ENV.fetch('MASTODON_VERSION_METADATA', nil)].compact.join('.') + ['kmyblue', to_s_of_kmyblue, build_metadata_of_mastodon].compact.join('.') + end + + def build_metadata_of_mastodon + ENV.fetch('MASTODON_VERSION_METADATA', nil) end def to_a diff --git a/spec/lib/status_reach_finder_spec.rb b/spec/lib/status_reach_finder_spec.rb index 57946d3a70..ee1a9668b9 100644 --- a/spec/lib/status_reach_finder_spec.rb +++ b/spec/lib/status_reach_finder_spec.rb @@ -176,45 +176,15 @@ describe StatusReachFinder do let(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com', protocol: :activitypub, uri: 'https://example.com/', inbox_url: 'https://example.com/inbox') } let(:tom) { Fabricate(:account, username: 'tom', domain: 'tom.com', protocol: :activitypub, uri: 'https://tom.com/', inbox_url: 'https://tom.com/inbox') } - context 'when reject_send_not_public_searchability' do - let(:properties) { { reject_send_not_public_searchability: true } } - let(:searchability) { :private } + context 'when reject_send_sensitive' do + let(:properties) { { reject_send_sensitive: true } } + let(:spoiler_text) { 'CW' } it 'does not include the inbox of blocked domain' do expect(subject.inboxes).to_not include 'https://example.com/inbox' expect(subject.inboxes).to include 'https://tom.com/inbox' end end - - context 'when reject_send_public_unlisted' do - let(:properties) { { reject_send_public_unlisted: true } } - let(:visibility) { :public_unlisted } - - it 'does not include the inbox of blocked domain' do - expect(subject.inboxes).to_not include 'https://example.com/inbox' - expect(subject.inboxes).to include 'https://tom.com/inbox' - end - - context 'when reject_send_dissubscribable' do - let(:properties) { { reject_send_dissubscribable: true } } - let(:dissubscribable) { true } - - it 'does not include the inbox of blocked domain' do - expect(subject.inboxes).to_not include 'https://example.com/inbox' - expect(subject.inboxes).to include 'https://tom.com/inbox' - end - end - - context 'when reject_send_sensitive' do - let(:properties) { { reject_send_sensitive: true } } - let(:spoiler_text) { 'CW' } - - it 'does not include the inbox of blocked domain' do - expect(subject.inboxes).to_not include 'https://example.com/inbox' - expect(subject.inboxes).to include 'https://tom.com/inbox' - end - end - end end end end diff --git a/spec/lib/vacuum/feeds_vacuum_spec.rb b/spec/lib/vacuum/feeds_vacuum_spec.rb index ede1e3c360..fa5381c8ae 100644 --- a/spec/lib/vacuum/feeds_vacuum_spec.rb +++ b/spec/lib/vacuum/feeds_vacuum_spec.rb @@ -8,12 +8,16 @@ RSpec.describe Vacuum::FeedsVacuum do describe '#perform' do let!(:active_user) { Fabricate(:user, current_sign_in_at: 2.days.ago) } let!(:inactive_user) { Fabricate(:user, current_sign_in_at: 22.days.ago) } + let!(:list) { Fabricate(:list, account: inactive_user.account) } + let!(:antenna) { Fabricate(:antenna, account: inactive_user.account) } before do redis.zadd(feed_key_for(inactive_user), 1, 1) redis.zadd(feed_key_for(active_user), 1, 1) redis.zadd(feed_key_for(inactive_user, 'reblogs'), 2, 2) redis.sadd(feed_key_for(inactive_user, 'reblogs:2'), 3) + redis.zadd(list_key_for(list), 1, 1) + redis.zadd(antenna_key_for(antenna), 1, 1) subject.perform end @@ -23,10 +27,20 @@ RSpec.describe Vacuum::FeedsVacuum do expect(redis.zcard(feed_key_for(active_user))).to eq 1 expect(redis.exists?(feed_key_for(inactive_user, 'reblogs'))).to be false expect(redis.exists?(feed_key_for(inactive_user, 'reblogs:2'))).to be false + expect(redis.zcard(list_key_for(list))).to eq 0 + expect(redis.zcard(antenna_key_for(antenna))).to eq 0 end end def feed_key_for(user, subtype = nil) FeedManager.instance.key(:home, user.account_id, subtype) end + + def list_key_for(list) + FeedManager.instance.key(:list, list.id) + end + + def antenna_key_for(antenna) + FeedManager.instance.key(:antenna, antenna.id) + end end diff --git a/spec/requests/api/v1/admin/domain_blocks_spec.rb b/spec/requests/api/v1/admin/domain_blocks_spec.rb index 1432e52623..86675b2cc7 100644 --- a/spec/requests/api/v1/admin/domain_blocks_spec.rb +++ b/spec/requests/api/v1/admin/domain_blocks_spec.rb @@ -78,10 +78,6 @@ RSpec.describe 'Domain Blocks' do reject_new_follow: domain_block.reject_new_follow, reject_reply: domain_block.reject_reply, reject_reply_exclude_followers: domain_block.reject_reply_exclude_followers, - reject_send_dissubscribable: domain_block.reject_send_dissubscribable, - reject_send_media: domain_block.reject_send_media, - reject_send_not_public_searchability: domain_block.reject_send_not_public_searchability, - reject_send_public_unlisted: domain_block.reject_send_public_unlisted, reject_send_sensitive: domain_block.reject_send_sensitive, reject_straight_follow: domain_block.reject_straight_follow, } @@ -130,10 +126,6 @@ RSpec.describe 'Domain Blocks' do reject_new_follow: domain_block.reject_new_follow, reject_reply: domain_block.reject_reply, reject_reply_exclude_followers: domain_block.reject_reply_exclude_followers, - reject_send_dissubscribable: domain_block.reject_send_dissubscribable, - reject_send_media: domain_block.reject_send_media, - reject_send_not_public_searchability: domain_block.reject_send_not_public_searchability, - reject_send_public_unlisted: domain_block.reject_send_public_unlisted, reject_send_sensitive: domain_block.reject_send_sensitive, reject_straight_follow: domain_block.reject_straight_follow, } diff --git a/spec/requests/api/v1/antennas_spec.rb b/spec/requests/api/v1/antennas_spec.rb new file mode 100644 index 0000000000..1597bbd81f --- /dev/null +++ b/spec/requests/api/v1/antennas_spec.rb @@ -0,0 +1,234 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Antennas' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read:lists write:lists' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/antennas' do + subject do + get '/api/v1/antennas', headers: headers + end + + let!(:antennas) do + [ + Fabricate(:antenna, account: user.account, title: 'first antenna'), + Fabricate(:antenna, account: user.account, title: 'second antenna', with_media_only: true), + Fabricate(:antenna, account: user.account, title: 'third antenna', stl: true), + Fabricate(:antenna, account: user.account, title: 'fourth antenna', ignore_reblog: true), + ] + end + + let(:expected_response) do + antennas.map do |antenna| + { + id: antenna.id.to_s, + title: antenna.title, + with_media_only: antenna.with_media_only, + ignore_reblog: antenna.ignore_reblog, + stl: antenna.stl, + ltl: antenna.ltl, + insert_feeds: antenna.insert_feeds, + list: nil, + accounts_count: 0, + domains_count: 0, + tags_count: 0, + keywords_count: 0, + } + end + end + + before do + Fabricate(:antenna) + end + + it_behaves_like 'forbidden for wrong scope', 'write write:lists' + + it 'returns the expected antennas', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(body_as_json).to match_array(expected_response) + end + end + + describe 'GET /api/v1/antennas/:id' do + subject do + get "/api/v1/antennas/#{antenna.id}", headers: headers + end + + let(:antenna) { Fabricate(:antenna, account: user.account) } + + it_behaves_like 'forbidden for wrong scope', 'write write:lists' + + it 'returns the requested antenna correctly', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(body_as_json).to eq({ + id: antenna.id.to_s, + title: antenna.title, + with_media_only: antenna.with_media_only, + ignore_reblog: antenna.ignore_reblog, + stl: antenna.stl, + ltl: antenna.ltl, + insert_feeds: antenna.insert_feeds, + list: nil, + accounts_count: 0, + domains_count: 0, + tags_count: 0, + keywords_count: 0, + }) + end + + context 'when the antenna belongs to a different user' do + let(:antenna) { Fabricate(:antenna) } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + + context 'when the antenna does not exist' do + it 'returns http not found' do + get '/api/v1/antennas/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + end + + describe 'POST /api/v1/antennas' do + subject do + post '/api/v1/antennas', headers: headers, params: params + end + + let(:params) { { title: 'my antenna', ltl: 'true' } } + + it_behaves_like 'forbidden for wrong scope', 'read read:lists' + + it 'returns the new antenna', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(body_as_json).to match(a_hash_including(title: 'my antenna', ltl: true)) + expect(Antenna.where(account: user.account).count).to eq(1) + end + + context 'when a title is not given' do + let(:params) { { title: '' } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + end + + describe 'PUT /api/v1/antennas/:id' do + subject do + put "/api/v1/antennas/#{antenna.id}", headers: headers, params: params + end + + let(:antenna) { Fabricate(:antenna, account: user.account, title: 'my antenna') } + let(:params) { { title: 'antenna', ignore_reblog: 'true', insert_feeds: 'true' } } + + it_behaves_like 'forbidden for wrong scope', 'read read:lists' + + it 'returns the updated antenna and updates values', :aggregate_failures do + expect { subject } + .to change_antenna_title + .and change_antenna_ignore_reblog + .and change_antenna_insert_feeds + + expect(response).to have_http_status(200) + antenna.reload + + expect(body_as_json).to eq({ + id: antenna.id.to_s, + title: antenna.title, + with_media_only: antenna.with_media_only, + ignore_reblog: antenna.ignore_reblog, + stl: antenna.stl, + ltl: antenna.ltl, + insert_feeds: antenna.insert_feeds, + list: nil, + accounts_count: 0, + domains_count: 0, + tags_count: 0, + keywords_count: 0, + }) + end + + def change_antenna_title + change { antenna.reload.title }.from('my antenna').to('antenna') + end + + def change_antenna_ignore_reblog + change { antenna.reload.ignore_reblog }.from(false).to(true) + end + + def change_antenna_insert_feeds + change { antenna.reload.insert_feeds }.from(false).to(true) + end + + context 'when the antenna does not exist' do + it 'returns http not found' do + put '/api/v1/antennas/-1', headers: headers, params: params + + expect(response).to have_http_status(404) + end + end + + context 'when the antenna belongs to another user' do + let(:antenna) { Fabricate(:antenna) } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end + + describe 'DELETE /api/v1/antennas/:id' do + subject do + delete "/api/v1/antennas/#{antenna.id}", headers: headers + end + + let(:antenna) { Fabricate(:antenna, account: user.account) } + + it_behaves_like 'forbidden for wrong scope', 'read read:lists' + + it 'deletes the antenna', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(Antenna.where(id: antenna.id)).to_not exist + end + + context 'when the antenna does not exist' do + it 'returns http not found' do + delete '/api/v1/antennas/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + + context 'when the antenna belongs to another user' do + let(:antenna) { Fabricate(:antenna) } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/workers/scheduler/sidekiq_health_scheduler_spec.rb b/spec/workers/scheduler/sidekiq_health_scheduler_spec.rb deleted file mode 100644 index 899b09fee3..0000000000 --- a/spec/workers/scheduler/sidekiq_health_scheduler_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Scheduler::SidekiqHealthScheduler do - let(:worker) { described_class.new } - - describe 'perform' do - it 'runs without error' do - expect { worker.perform }.to_not raise_error - end - end -end