diff --git a/app/helpers/json_ld_helper.rb b/app/helpers/json_ld_helper.rb index 65daaa5302..212894d0cd 100644 --- a/app/helpers/json_ld_helper.rb +++ b/app/helpers/json_ld_helper.rb @@ -72,6 +72,18 @@ module JsonLdHelper !haystack.casecmp(needle).zero? end + def safe_prefetched_embed(account, object, context) + return unless object.is_a?(Hash) + + # NOTE: Replacing the object's context by that of the parent activity is + # not sound, but it's consistent with the rest of the codebase + object = object.merge({ '@context' => context }) + + return if value_or_id(first_of_value(object['attributedTo'])) != account.uri || non_matching_uri_hosts?(account.uri, object['id']) + + object + end + def canonicalize(json) graph = RDF::Graph.new << JSON::LD::API.toRdf(json, documentLoader: method(:load_jsonld_context)) graph.dump(:normalize) diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 97d929d768..06bc940949 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -205,24 +205,12 @@ class ActivityPub::Activity::Create < ActivityPub::Activity @quote.status = status @quote.save - ActivityPub::VerifyQuoteService.new.call(@quote, fetchable_quoted_uri: @quote_uri, prefetched_quoted_object: safe_prefetched_quoted_object, request_id: @options[:request_id]) + embedded_quote = safe_prefetched_embed(@account, @status_parser.quoted_object, @json['context']) + ActivityPub::VerifyQuoteService.new.call(@quote, fetchable_quoted_uri: @quote_uri, prefetched_quoted_object: embedded_quote, request_id: @options[:request_id]) rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS ActivityPub::RefetchAndVerifyQuoteWorker.perform_in(rand(30..600).seconds, @quote.id, @quote_uri, { 'request_id' => @options[:request_id] }) end - def safe_prefetched_quoted_object - object = @status_parser.quoted_object - return unless object.is_a?(Hash) - - # NOTE: Replacing the object's context by that of the parent activity is - # not sound, but it's consistent with the rest of the codebase - object = object.merge({ '@context' => @json['@context'] }) - - return if value_or_id(first_of_value(object['attributedTo'])) != @account.uri || non_matching_uri_hosts?(@account.uri, object['id']) - - object - end - def process_tags return if @object['tag'].nil? diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index c6d957f693..aceb17f2d1 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -304,24 +304,12 @@ class ActivityPub::ProcessStatusUpdateService < BaseService end def fetch_and_verify_quote!(quote, quote_uri) - ActivityPub::VerifyQuoteService.new.call(quote, fetchable_quoted_uri: quote_uri, prefetched_quoted_object: safe_prefetched_quoted_object, request_id: @request_id) + embedded_quote = safe_prefetched_embed(@account, @status_parser.quoted_object, @activity_json['context']) + ActivityPub::VerifyQuoteService.new.call(quote, fetchable_quoted_uri: quote_uri, prefetched_quoted_object: embedded_quote, request_id: @request_id) rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS ActivityPub::RefetchAndVerifyQuoteWorker.perform_in(rand(30..600).seconds, quote.id, quote_uri, { 'request_id' => @request_id }) end - def safe_prefetched_quoted_object - object = @status_parser.quoted_object - return unless object.is_a?(Hash) - - # NOTE: Replacing the object's context by that of the parent activity is - # not sound, but it's consistent with the rest of the codebase - object = object.merge({ '@context' => @activity_json['@context'] }) - - return if value_or_id(first_of_value(object['attributedTo'])) != @account.uri || non_matching_uri_hosts?(@account.uri, object['id']) - - object - end - def update_counts! likes = @status_parser.favourites_count shares = @status_parser.reblogs_count