diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 10e3ecc57..f0aa06031 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -220,8 +220,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity return unless @status_parser.quote? approval_uri = @status_parser.quote_approval_uri - approval_uri = nil if unsupported_uri_scheme?(approval_uri) - @quote = Quote.new(account: @account, approval_uri: approval_uri, legacy: @status_parser.legacy_quote?) + approval_uri = nil if unsupported_uri_scheme?(approval_uri) || TagManager.instance.local_url?(approval_uri) + @quote = Quote.new(account: @account, approval_uri: approval_uri, legacy: @status_parser.legacy_quote?, state: @status_parser.deleted_quote? ? :deleted : :pending) end def process_hashtag(tag) diff --git a/app/lib/activitypub/parser/status_parser.rb b/app/lib/activitypub/parser/status_parser.rb index 9db1cb572..535d5054b 100644 --- a/app/lib/activitypub/parser/status_parser.rb +++ b/app/lib/activitypub/parser/status_parser.rb @@ -121,6 +121,10 @@ class ActivityPub::Parser::StatusParser %w(quote _misskey_quote quoteUrl quoteUri).any? { |key| @object[key].present? } end + def deleted_quote? + @object['quote'].is_a?(Hash) && @object['quote']['type'] == 'Tombstone' + end + def quote_uri %w(quote _misskey_quote quoteUrl quoteUri).filter_map do |key| value_or_id(as_array(@object[key]).first) diff --git a/app/models/quote.rb b/app/models/quote.rb index 89845ed9f..4b1072d6c 100644 --- a/app/models/quote.rb +++ b/app/models/quote.rb @@ -21,7 +21,7 @@ class Quote < ApplicationRecord REFRESH_DEADLINE = 6.hours enum :state, - { pending: 0, accepted: 1, rejected: 2, revoked: 3 }, + { pending: 0, accepted: 1, rejected: 2, revoked: 3, deleted: 4 }, validate: true belongs_to :status diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index d29e08cdd..9f4d4de55 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -305,10 +305,12 @@ class ActivityPub::ProcessStatusUpdateService < BaseService approval_uri = nil if unsupported_uri_scheme?(approval_uri) if @status.quote.present? + state = @status_parser.deleted_quote? ? :deleted : :pending + # If the quoted post has changed, discard the old object and create a new one if @status.quote.quoted_status.present? && ActivityPub::TagManager.instance.uri_for(@status.quote.quoted_status) != quote_uri @status.quote.destroy - quote = Quote.create(status: @status, approval_uri: approval_uri, legacy: @status_parser.legacy_quote?) + quote = Quote.create(status: @status, approval_uri: approval_uri, legacy: @status_parser.legacy_quote?, state: state) @quote_changed = true else quote = @status.quote diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb index 1fa04dec0..12fbdba80 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -956,7 +956,7 @@ RSpec.describe ActivityPub::Activity::Create do expect(status).to_not be_nil expect(status.quote).to_not be_nil expect(status.quote).to have_attributes( - state: 'pending', + state: 'deleted', approval_uri: nil ) end diff --git a/spec/services/activitypub/process_status_update_service_spec.rb b/spec/services/activitypub/process_status_update_service_spec.rb index 723f1343b..43e6f682c 100644 --- a/spec/services/activitypub/process_status_update_service_spec.rb +++ b/spec/services/activitypub/process_status_update_service_spec.rb @@ -1008,7 +1008,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do it 'updates the URI and unverifies the quote' do expect { subject.call(status, json, json) } .to change { status.quote.quoted_status }.from(quoted_status).to(nil) - .and change { status.quote.state }.from('accepted') + .and change { status.quote.state }.from('accepted').to('deleted') expect { quote.reload }.to raise_error(ActiveRecord::RecordNotFound) end