diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index 18277034cf878f..d2ba6975451ffc 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -265,7 +265,7 @@ def searchability_from_audience bio = searchability_from_bio return bio unless bio.nil? - return misskey_software? ? :public : :direct + return misskey_software? ? misskey_searchability_from_indexable : :direct end if audience_searchable_by.any? { |uri| ActivityPub::TagManager.instance.public_collection?(uri) } @@ -297,6 +297,12 @@ def searchability_from_bio searchability end + def misskey_searchability_from_indexable + return :public if @json['indexable'].nil? + + @json['indexable'] ? :public : :limited + end + def instance_info @instance_info ||= InstanceInfo.find_by(domain: @domain) end diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index b532b775bcb886..981fad7d757a83 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -96,6 +96,7 @@ def preprocess_attributes! end def load_circle + raise ArgumentError if @options[:visibility] == 'limited' && @options[:circle_id].nil? return unless @options[:visibility] == 'circle' || (@options[:visibility] == 'limited' && @options[:circle_id].present?) @circle = @options[:circle_id].present? && Circle.find(@options[:circle_id]) diff --git a/spec/models/status_spec.rb b/spec/models/status_spec.rb index 89f90fc751d26a..64623075943b37 100644 --- a/spec/models/status_spec.rb +++ b/spec/models/status_spec.rb @@ -169,6 +169,14 @@ end end + context 'when limited-public' do + let(:account_searchability) { :limited } + + it 'returns limited' do + expect(subject.compute_searchability).to eq 'limited' + end + end + context 'when private-limited' do let(:account_searchability) { :private } let(:status_searchability) { :limited } diff --git a/spec/services/activitypub/process_account_service_spec.rb b/spec/services/activitypub/process_account_service_spec.rb index 1ea3b6491b7419..b23aa1cea34c59 100644 --- a/spec/services/activitypub/process_account_service_spec.rb +++ b/spec/services/activitypub/process_account_service_spec.rb @@ -11,6 +11,7 @@ let(:software) { 'mastodon' } let(:searchable_by) { 'https://www.w3.org/ns/activitystreams#Public' } let(:sender_bio) { '' } + let(:indexable) { nil } let(:payload) do { id: 'https://foo.test', @@ -18,6 +19,7 @@ inbox: 'https://foo.test/inbox', followers: 'https://example.com/followers', searchableBy: searchable_by, + indexable: indexable, summary: sender_bio, }.with_indifferent_access end @@ -73,6 +75,39 @@ it 'searchability is public' do expect(subject.searchability).to eq 'public' end + + context 'with true indexable' do + let(:indexable) { true } + + it 'searchability is public' do + expect(subject.searchability).to eq 'public' + end + end + + context 'with false indexable' do + let(:indexable) { false } + + it 'searchability is limited' do + expect(subject.searchability).to eq 'limited' + end + end + + context 'with no-indexable key' do + let(:payload) do + { + id: 'https://foo.test', + type: 'Actor', + inbox: 'https://foo.test/inbox', + followers: 'https://example.com/followers', + searchableBy: searchable_by, + summary: sender_bio, + }.with_indifferent_access + end + + it 'searchability is public' do + expect(subject.searchability).to eq 'public' + end + end end context 'with bio' do diff --git a/spec/services/post_status_service_spec.rb b/spec/services/post_status_service_spec.rb index 3b953b9fc1fb65..a2cf6fbfb07348 100644 --- a/spec/services/post_status_service_spec.rb +++ b/spec/services/post_status_service_spec.rb @@ -206,6 +206,27 @@ expect(status.mentioned_accounts.first.id).to eq circle_account.id end + it 'circle post with limited visibility' do + account = Fabricate(:account) + circle_account = Fabricate(:account) + circle = Fabricate(:circle, account: account) + text = 'This is an English text.' + + circle_account.follow!(account) + circle.accounts << circle_account + status = subject.call(account, text: text, visibility: 'limited', circle_id: circle.id) + + expect(status.visibility).to eq 'limited' + expect(status.limited_scope).to eq 'circle' + end + + it 'limited visibility and empty circle' do + account = Fabricate(:account) + text = 'This is an English text.' + + expect { subject.call(account, text: text, visibility: 'limited') }.to raise_exception ActiveRecord::RecordInvalid + end + it 'safeguards mentions' do account = Fabricate(:account) mentioned_account = Fabricate(:account, username: 'alice')