Skip to content

Commit b4c00a6

Browse files
committed
Merge branch 'main' of https://github.com/mastodon/mastodon into mastodon-main
2 parents fa8eb8b + 3c45dfa commit b4c00a6

11 files changed

+244
-21
lines changed

Gemfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ gem 'link_header', '~> 0.0'
6363
gem 'mime-types', '~> 3.3.1', require: 'mime/types/columnar'
6464
gem 'nokogiri', '~> 1.12'
6565
gem 'nsa', '~> 0.2'
66-
gem 'oj', '~> 3.12'
66+
gem 'oj', '~> 3.13'
6767
gem 'ox', '~> 2.14'
6868
gem 'parslet'
6969
gem 'parallel', '~> 1.20'

Gemfile.lock

+6-6
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ GEM
220220
multipart-post (>= 1.2, < 3)
221221
ruby2_keywords
222222
faraday-net_http (1.0.1)
223-
fast_blank (1.0.0)
223+
fast_blank (1.0.1)
224224
fastimage (2.2.5)
225225
ffi (1.15.0)
226226
ffi-compiler (1.0.1)
@@ -343,7 +343,7 @@ GEM
343343
activesupport (>= 4)
344344
railties (>= 4)
345345
request_store (~> 1.0)
346-
loofah (2.10.0)
346+
loofah (2.12.0)
347347
crass (~> 1.0.2)
348348
nokogiri (>= 1.5.9)
349349
mail (2.7.1)
@@ -383,7 +383,7 @@ GEM
383383
concurrent-ruby (~> 1.0, >= 1.0.2)
384384
sidekiq (>= 3.5)
385385
statsd-ruby (~> 1.4, >= 1.4.0)
386-
oj (3.12.2)
386+
oj (3.13.2)
387387
omniauth (1.9.1)
388388
hashie (>= 3.4.6)
389389
rack (>= 1.6.2, < 3)
@@ -504,7 +504,7 @@ GEM
504504
rake (>= 0.13)
505505
thor (~> 1.0)
506506
rainbow (3.0.0)
507-
rake (13.0.3)
507+
rake (13.0.6)
508508
rdf (3.1.15)
509509
hamster (~> 3.0)
510510
link_header (~> 0.0, >= 0.0.8)
@@ -534,7 +534,7 @@ GEM
534534
rspec-mocks (3.10.2)
535535
diff-lcs (>= 1.2.0, < 2.0)
536536
rspec-support (~> 3.10.0)
537-
rspec-rails (5.0.1)
537+
rspec-rails (5.0.2)
538538
actionpack (>= 5.2)
539539
activesupport (>= 5.2)
540540
railties (>= 5.2)
@@ -771,7 +771,7 @@ DEPENDENCIES
771771
net-ldap (~> 0.17)
772772
nokogiri (~> 1.12)
773773
nsa (~> 0.2)
774-
oj (~> 3.12)
774+
oj (~> 3.13)
775775
omniauth (~> 1.9)
776776
omniauth-cas (~> 2.0)
777777
omniauth-rails_csrf_protection (~> 0.1)

app/services/resolve_account_service.rb

+1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ def not_yet_deleted?
142142
end
143143

144144
def queue_deletion!
145+
@account.suspend!(origin: :remote)
145146
AccountDeletionWorker.perform_async(@account.id, reserve_username: false, skip_activitypub: true)
146147
end
147148

app/services/unsuspend_account_service.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
# frozen_string_literal: true
22

33
class UnsuspendAccountService < BaseService
4+
include Payloadable
45
def call(account)
56
@account = account
67

78
unsuspend!
89
refresh_remote_account!
910

10-
return if @account.nil?
11+
return if @account.nil? || @account.suspended?
1112

1213
merge_into_home_timelines!
1314
merge_into_list_timelines!

app/views/settings/profiles/show.html.haml

+2-3
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,8 @@
2929
.fields-group
3030
= f.input :bot, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.bot')
3131

32-
- if Setting.profile_directory
33-
.fields-group
34-
= f.input :discoverable, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.discoverable'), recommended: true
32+
.fields-group
33+
= f.input :discoverable, as: :boolean, wrapper: :with_label, hint: t(Setting.profile_directory ? 'simple_form.hints.defaults.discoverable' : 'simple_form.hints.defaults.discoverable_no_directory'), recommended: true
3534

3635
%hr.spacer/
3736

config/locales/simple_form.en.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ en:
3535
current_password: For security purposes please enter the password of the current account
3636
current_username: To confirm, please enter the username of the current account
3737
digest: Only sent after a long period of inactivity and only if you have received any personal messages in your absence
38-
discoverable: Allow your account to be discovered by strangers through recommendations and other features
38+
discoverable: Allow your account to be discovered by strangers through recommendations, profile directory and other features
39+
discoverable_no_directory: Allow your account to be discovered by strangers through recommendations and other features
3940
email: You will be sent a confirmation e-mail
4041
fields: You can have up to 4 items displayed as a table on your profile
4142
header: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px

dist/nginx.conf

+5-4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ server {
3131
ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
3232
ssl_prefer_server_ciphers on;
3333
ssl_session_cache shared:SSL:10m;
34+
ssl_session_tickets off;
3435

3536
# Uncomment these lines once you acquire a certificate:
3637
# ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
@@ -51,7 +52,7 @@ server {
5152
gzip_http_version 1.1;
5253
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
5354

54-
add_header Strict-Transport-Security "max-age=31536000";
55+
add_header Strict-Transport-Security "max-age=31536000" always;
5556
add_header Referrer-Policy "same-origin";
5657

5758
location / {
@@ -60,13 +61,13 @@ server {
6061

6162
location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) {
6263
add_header Cache-Control "public, max-age=31536000, immutable";
63-
add_header Strict-Transport-Security "max-age=31536000";
64+
add_header Strict-Transport-Security "max-age=31536000" always;
6465
try_files $uri @proxy;
6566
}
6667

6768
location /sw.js {
6869
add_header Cache-Control "public, max-age=0";
69-
add_header Strict-Transport-Security "max-age=31536000";
70+
add_header Strict-Transport-Security "max-age=31536000" always;
7071
try_files $uri @proxy;
7172
}
7273

@@ -90,7 +91,7 @@ server {
9091
proxy_cache_valid 410 24h;
9192
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
9293
add_header X-Cached $upstream_cache_status;
93-
add_header Strict-Transport-Security "max-age=31536000";
94+
add_header Strict-Transport-Security "max-age=31536000" always;
9495

9596
tcp_nodelay on;
9697
}

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@
151151
"requestidlecallback": "^0.3.0",
152152
"reselect": "^4.0.0",
153153
"rimraf": "^3.0.2",
154-
"sass": "^1.37.0",
154+
"sass": "^1.38.0",
155155
"sass-loader": "^10.2.0",
156156
"stacktrace-js": "^2.0.2",
157157
"stringz": "^2.1.0",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
require 'rails_helper'
2+
3+
RSpec.describe SuspendAccountService, type: :service do
4+
shared_examples 'common behavior' do
5+
let!(:local_follower) { Fabricate(:user, current_sign_in_at: 1.hour.ago).account }
6+
let!(:list) { Fabricate(:list, account: local_follower) }
7+
8+
subject do
9+
-> { described_class.new.call(account) }
10+
end
11+
12+
before do
13+
allow(FeedManager.instance).to receive(:unmerge_from_home).and_return(nil)
14+
allow(FeedManager.instance).to receive(:unmerge_from_list).and_return(nil)
15+
16+
local_follower.follow!(account)
17+
list.accounts << account
18+
end
19+
20+
it "unmerges from local followers' feeds" do
21+
subject.call
22+
expect(FeedManager.instance).to have_received(:unmerge_from_home).with(account, local_follower)
23+
expect(FeedManager.instance).to have_received(:unmerge_from_list).with(account, list)
24+
end
25+
26+
it 'marks account as suspended' do
27+
is_expected.to change { account.suspended? }.from(false).to(true)
28+
end
29+
end
30+
31+
describe 'suspending a local account' do
32+
def match_update_actor_request(req, account)
33+
json = JSON.parse(req.body)
34+
actor_id = ActivityPub::TagManager.instance.uri_for(account)
35+
json['type'] == 'Update' && json['actor'] == actor_id && json['object']['id'] == actor_id && json['object']['suspended']
36+
end
37+
38+
before do
39+
stub_request(:post, 'https://alice.com/inbox').to_return(status: 201)
40+
stub_request(:post, 'https://bob.com/inbox').to_return(status: 201)
41+
end
42+
43+
include_examples 'common behavior' do
44+
let!(:account) { Fabricate(:account) }
45+
let!(:remote_follower) { Fabricate(:account, uri: 'https://alice.com', inbox_url: 'https://alice.com/inbox', protocol: :activitypub) }
46+
let!(:remote_reporter) { Fabricate(:account, uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub) }
47+
let!(:report) { Fabricate(:report, account: remote_reporter, target_account: account) }
48+
49+
before do
50+
remote_follower.follow!(account)
51+
end
52+
53+
it 'sends an update actor to followers and reporters' do
54+
subject.call
55+
expect(a_request(:post, remote_follower.inbox_url).with { |req| match_update_actor_request(req, account) }).to have_been_made.once
56+
expect(a_request(:post, remote_reporter.inbox_url).with { |req| match_update_actor_request(req, account) }).to have_been_made.once
57+
end
58+
end
59+
end
60+
61+
describe 'suspending a remote account' do
62+
def match_reject_follow_request(req, account, followee)
63+
json = JSON.parse(req.body)
64+
json['type'] == 'Reject' && json['actor'] == ActivityPub::TagManager.instance.uri_for(followee) && json['object']['actor'] == account.uri
65+
end
66+
67+
before do
68+
stub_request(:post, 'https://bob.com/inbox').to_return(status: 201)
69+
end
70+
71+
include_examples 'common behavior' do
72+
let!(:account) { Fabricate(:account, domain: 'bob.com', uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub) }
73+
let!(:local_followee) { Fabricate(:account) }
74+
75+
before do
76+
account.follow!(local_followee)
77+
end
78+
79+
it 'sends a reject follow' do
80+
subject.call
81+
expect(a_request(:post, account.inbox_url).with { |req| match_reject_follow_request(req, account, local_followee) }).to have_been_made.once
82+
end
83+
end
84+
end
85+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
require 'rails_helper'
2+
3+
RSpec.describe UnsuspendAccountService, type: :service do
4+
shared_examples 'common behavior' do
5+
let!(:local_follower) { Fabricate(:user, current_sign_in_at: 1.hour.ago).account }
6+
let!(:list) { Fabricate(:list, account: local_follower) }
7+
8+
subject do
9+
-> { described_class.new.call(account) }
10+
end
11+
12+
before do
13+
allow(FeedManager.instance).to receive(:merge_into_home).and_return(nil)
14+
allow(FeedManager.instance).to receive(:merge_into_list).and_return(nil)
15+
16+
local_follower.follow!(account)
17+
list.accounts << account
18+
19+
account.suspend!(origin: :local)
20+
end
21+
end
22+
23+
describe 'unsuspending a local account' do
24+
def match_update_actor_request(req, account)
25+
json = JSON.parse(req.body)
26+
actor_id = ActivityPub::TagManager.instance.uri_for(account)
27+
json['type'] == 'Update' && json['actor'] == actor_id && json['object']['id'] == actor_id && !json['object']['suspended']
28+
end
29+
30+
before do
31+
stub_request(:post, 'https://alice.com/inbox').to_return(status: 201)
32+
stub_request(:post, 'https://bob.com/inbox').to_return(status: 201)
33+
end
34+
35+
it 'marks account as unsuspended' do
36+
is_expected.to change { account.suspended? }.from(true).to(false)
37+
end
38+
39+
include_examples 'common behavior' do
40+
let!(:account) { Fabricate(:account) }
41+
let!(:remote_follower) { Fabricate(:account, uri: 'https://alice.com', inbox_url: 'https://alice.com/inbox', protocol: :activitypub) }
42+
let!(:remote_reporter) { Fabricate(:account, uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub) }
43+
let!(:report) { Fabricate(:report, account: remote_reporter, target_account: account) }
44+
45+
before do
46+
remote_follower.follow!(account)
47+
end
48+
49+
it "merges back into local followers' feeds" do
50+
subject.call
51+
expect(FeedManager.instance).to have_received(:merge_into_home).with(account, local_follower)
52+
expect(FeedManager.instance).to have_received(:merge_into_list).with(account, list)
53+
end
54+
55+
it 'sends an update actor to followers and reporters' do
56+
subject.call
57+
expect(a_request(:post, remote_follower.inbox_url).with { |req| match_update_actor_request(req, account) }).to have_been_made.once
58+
expect(a_request(:post, remote_reporter.inbox_url).with { |req| match_update_actor_request(req, account) }).to have_been_made.once
59+
end
60+
end
61+
end
62+
63+
describe 'unsuspending a remote account' do
64+
include_examples 'common behavior' do
65+
let!(:account) { Fabricate(:account, domain: 'bob.com', uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub) }
66+
let!(:reslove_account_service) { double }
67+
68+
before do
69+
allow(ResolveAccountService).to receive(:new).and_return(reslove_account_service)
70+
end
71+
72+
context 'when the account is not remotely suspended' do
73+
before do
74+
allow(reslove_account_service).to receive(:call).with(account).and_return(account)
75+
end
76+
77+
it 're-fetches the account' do
78+
subject.call
79+
expect(reslove_account_service).to have_received(:call).with(account)
80+
end
81+
82+
it "merges back into local followers' feeds" do
83+
subject.call
84+
expect(FeedManager.instance).to have_received(:merge_into_home).with(account, local_follower)
85+
expect(FeedManager.instance).to have_received(:merge_into_list).with(account, list)
86+
end
87+
88+
it 'marks account as unsuspended' do
89+
is_expected.to change { account.suspended? }.from(true).to(false)
90+
end
91+
end
92+
93+
context 'when the account is remotely suspended' do
94+
before do
95+
allow(reslove_account_service).to receive(:call).with(account) do |account|
96+
account.suspend!(origin: :remote)
97+
account
98+
end
99+
end
100+
101+
it 're-fetches the account' do
102+
subject.call
103+
expect(reslove_account_service).to have_received(:call).with(account)
104+
end
105+
106+
it "does not merge back into local followers' feeds" do
107+
subject.call
108+
expect(FeedManager.instance).to_not have_received(:merge_into_home).with(account, local_follower)
109+
expect(FeedManager.instance).to_not have_received(:merge_into_list).with(account, list)
110+
end
111+
112+
it 'does not mark the account as unsuspended' do
113+
is_expected.not_to change { account.suspended? }
114+
end
115+
end
116+
117+
context 'when the account is remotely deleted' do
118+
before do
119+
allow(reslove_account_service).to receive(:call).with(account).and_return(nil)
120+
end
121+
122+
it 're-fetches the account' do
123+
subject.call
124+
expect(reslove_account_service).to have_received(:call).with(account)
125+
end
126+
127+
it "does not merge back into local followers' feeds" do
128+
subject.call
129+
expect(FeedManager.instance).to_not have_received(:merge_into_home).with(account, local_follower)
130+
expect(FeedManager.instance).to_not have_received(:merge_into_list).with(account, list)
131+
end
132+
end
133+
end
134+
end
135+
end

yarn.lock

+4-4
Original file line numberDiff line numberDiff line change
@@ -9859,10 +9859,10 @@ sass-loader@^10.2.0:
98599859
schema-utils "^3.0.0"
98609860
semver "^7.3.2"
98619861

9862-
sass@^1.37.0:
9863-
version "1.37.0"
9864-
resolved "https://registry.yarnpkg.com/sass/-/sass-1.37.0.tgz#f1b03a9d072ee9053a29d125c8130c78e92827c2"
9865-
integrity sha512-B+Tu6cSAG8ffs/cqsZl/bgSH2pCmavDaPTYAoW8QA1qNHh/RqndNfVKuABKYkLjUQ5aq/BnCENVpE80cqdSM1w==
9862+
sass@^1.38.0:
9863+
version "1.38.0"
9864+
resolved "https://registry.yarnpkg.com/sass/-/sass-1.38.0.tgz#2f3e60a1efdcdc910586fa79dc89d3399a145b4f"
9865+
integrity sha512-WBccZeMigAGKoI+NgD7Adh0ab1HUq+6BmyBUEaGxtErbUtWUevEbdgo5EZiJQofLUGcKtlNaO2IdN73AHEua5g==
98669866
dependencies:
98679867
chokidar ">=3.0.0 <4.0.0"
98689868

0 commit comments

Comments
 (0)