Resolve links to unknown remote objects when posting (#38711)

This commit is contained in:
Claire 2026-06-10 17:55:27 +02:00 committed by GitHub
parent 008f377a37
commit 9e0a3aaf08
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 7 deletions

View File

@ -23,12 +23,15 @@ class ProcessLinksService < BaseService
def scan_text!
urls = @status.text.scan(FetchLinkCardService::URL_PATTERN).map { |array| Addressable::URI.parse(array[1]).normalize }
domains = urls.map(&:domain).uniq
valid_domains = Instance.searchable.where(domain: domains).pluck(:domain)
urls.each do |url|
# We only support `FeaturedCollection` at this time
# TODO: We probably want to resolve unknown objects at authoring time
object = ActivityPub::TagManager.instance.uri_to_resource(url.to_s, Collection)
next if object.nil?
object ||= ResolveURLService.new.call(url.to_s) if valid_domains.include?(url.domain)
next unless object.is_a?(Collection)
tagged_object = @previous_objects.find { |x| x.object == object || x.uri == url }
tagged_object ||= @current_objects.find { |x| x.object == object || x.uri == url }

View File

@ -9,17 +9,34 @@ RSpec.describe ProcessLinksService do
context 'when status mentions known collections' do
let!(:collection) { Fabricate(:collection) }
let(:status) { Fabricate(:status, account: account, text: "Hello check out this collection! #{ActivityPub::TagManager.instance.uri_for(collection)}", visibility: :public) }
let(:status) { Fabricate(:status, account: account, text:, visibility: :public) }
it 'creates a tagged object' do
expect { subject.call(status) }
.to change { status.tagged_objects.count }.by(1)
context 'when the collection is mentioned by URI' do
let(:text) { "Hello check out this collection! #{ActivityPub::TagManager.instance.uri_for(collection)}" }
it 'creates a tagged object' do
expect { subject.call(status) }
.to change { status.tagged_objects.count }.by(1)
end
end
context 'when the collection is mentioned by URL' do
let(:text) { "Hello check out this collection! #{ActivityPub::TagManager.instance.url_for(collection)}" }
it 'creates a tagged object' do
expect { subject.call(status) }
.to change { status.tagged_objects.count }.by(1)
end
end
end
context 'when status has a generic link' do
context 'when status has a generic link to something that is not a collection' do
let(:status) { Fabricate(:status, account: account, text: 'Hello check out my personal web page: https://example.com/test', visibility: :public) }
before do
stub_request(:get, 'https://example.com/test').to_return(status: 404)
end
it 'skips the link and does not create a tagged object' do
expect { expect { subject.call(status) }.to_not raise_error }
.to not_change { status.tagged_objects.count }.from(0)