Skip to content

Commit 55252ef

Browse files
committed
Merge remote-tracking branch 'parent/stable-4.5' into kb-draft-21.9-lts
2 parents bd4d724 + 38e7bb9 commit 55252ef

194 files changed

Lines changed: 6060 additions & 2171 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,36 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [4.5.8] - 2026-03-24
6+
7+
### Security
8+
9+
- Fix insufficient checks on quote authorizations ([GHSA-q4g8-82c5-9h33](https://github.com/mastodon/mastodon/security/advisories/GHSA-q4g8-82c5-9h33))
10+
- Fix open redirect in legacy path handler ([GHSA-xqw8-4j56-5hj6](https://github.com/mastodon/mastodon/security/advisories/GHSA-xqw8-4j56-5hj6))
11+
- Updated dependencies
12+
13+
### Added
14+
15+
- Add for searching already-known private GtS posts (#38057 by @ClearlyClaire)
16+
17+
### Changed
18+
19+
- Change media description length limit for remote media attachments from 1500 to 10000 characters (#37921 by @ClearlyClaire)
20+
- Change HTTP signatures to skip the `Accept` header (#38132 by @ClearlyClaire)
21+
- Change numeric AP endpoints to redirect to short account URLs when HTML is requested (#38056 by @ClearlyClaire)
22+
23+
### Fixed
24+
25+
- Fix some model definitions in `tootctl maintenance fix-duplicates` (#38214 by @ClearlyClaire)
26+
- Fix overly strict checks for current username on account migration page (#38183 by @mjankowski)
27+
- Fix OpenStack Swift Keystone token rate limiting (#38145 by @hugogameiro)
28+
- Fix poll expiration notification being re-triggered on implicit updates (#38078 by @ClearlyClaire)
29+
- Fix incorrect translation string in webauthn mailers (#38062 by @mjankowski)
30+
- Fix “Unblock” and “Unmute” actions being disabled when blocked (#38075 by @ClearlyClaire)
31+
- Fix username availability check being wrongly applied on race conditions (#37975 by @ClearlyClaire)
32+
- Fix hover card unintentionally being shown in some cases (#38039 and #38112 by @diondiondion)
33+
- Fix existing posts not being removed from lists when a list member is unfollowed (#38048 by @ClearlyClaire)
34+
535
## [4.5.7] - 2026-02-24
636

737
### Security

FEDERATION.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,4 @@ The following table attempts to summary those limits.
6767
| Account `attributionDomains` | 256 | List will be truncated |
6868
| Account aliases (actor `alsoKnownAs`) | 256 | List will be truncated |
6969
| Custom emoji shortcode (`Emoji` `name`) | 2048 | Emoji will be rejected |
70+
| Media descriptions (`name`/`summary`) | 10000 | Description will be truncated |

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ gem 'bootsnap', '~> 1.18.0', require: false
2828
gem 'browser'
2929
gem 'charlock_holmes', '~> 0.7.7'
3030
gem 'chewy', '~> 7.3'
31-
gem 'devise', '~> 4.9'
31+
gem 'devise'
3232
gem 'devise-two-factor'
3333

3434
group :pam_authentication, optional: true do

Gemfile.lock

Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -10,45 +10,45 @@ GIT
1010
GEM
1111
remote: https://rubygems.org/
1212
specs:
13-
actioncable (8.0.3)
14-
actionpack (= 8.0.3)
15-
activesupport (= 8.0.3)
13+
actioncable (8.0.4.1)
14+
actionpack (= 8.0.4.1)
15+
activesupport (= 8.0.4.1)
1616
nio4r (~> 2.0)
1717
websocket-driver (>= 0.6.1)
1818
zeitwerk (~> 2.6)
19-
actionmailbox (8.0.3)
20-
actionpack (= 8.0.3)
21-
activejob (= 8.0.3)
22-
activerecord (= 8.0.3)
23-
activestorage (= 8.0.3)
24-
activesupport (= 8.0.3)
19+
actionmailbox (8.0.4.1)
20+
actionpack (= 8.0.4.1)
21+
activejob (= 8.0.4.1)
22+
activerecord (= 8.0.4.1)
23+
activestorage (= 8.0.4.1)
24+
activesupport (= 8.0.4.1)
2525
mail (>= 2.8.0)
26-
actionmailer (8.0.3)
27-
actionpack (= 8.0.3)
28-
actionview (= 8.0.3)
29-
activejob (= 8.0.3)
30-
activesupport (= 8.0.3)
26+
actionmailer (8.0.4.1)
27+
actionpack (= 8.0.4.1)
28+
actionview (= 8.0.4.1)
29+
activejob (= 8.0.4.1)
30+
activesupport (= 8.0.4.1)
3131
mail (>= 2.8.0)
3232
rails-dom-testing (~> 2.2)
33-
actionpack (8.0.3)
34-
actionview (= 8.0.3)
35-
activesupport (= 8.0.3)
33+
actionpack (8.0.4.1)
34+
actionview (= 8.0.4.1)
35+
activesupport (= 8.0.4.1)
3636
nokogiri (>= 1.8.5)
3737
rack (>= 2.2.4)
3838
rack-session (>= 1.0.1)
3939
rack-test (>= 0.6.3)
4040
rails-dom-testing (~> 2.2)
4141
rails-html-sanitizer (~> 1.6)
4242
useragent (~> 0.16)
43-
actiontext (8.0.3)
44-
actionpack (= 8.0.3)
45-
activerecord (= 8.0.3)
46-
activestorage (= 8.0.3)
47-
activesupport (= 8.0.3)
43+
actiontext (8.0.4.1)
44+
actionpack (= 8.0.4.1)
45+
activerecord (= 8.0.4.1)
46+
activestorage (= 8.0.4.1)
47+
activesupport (= 8.0.4.1)
4848
globalid (>= 0.6.0)
4949
nokogiri (>= 1.8.5)
50-
actionview (8.0.3)
51-
activesupport (= 8.0.3)
50+
actionview (8.0.4.1)
51+
activesupport (= 8.0.4.1)
5252
builder (~> 3.1)
5353
erubi (~> 1.11)
5454
rails-dom-testing (~> 2.2)
@@ -58,22 +58,22 @@ GEM
5858
activemodel (>= 4.1)
5959
case_transform (>= 0.2)
6060
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
61-
activejob (8.0.3)
62-
activesupport (= 8.0.3)
61+
activejob (8.0.4.1)
62+
activesupport (= 8.0.4.1)
6363
globalid (>= 0.3.6)
64-
activemodel (8.0.3)
65-
activesupport (= 8.0.3)
66-
activerecord (8.0.3)
67-
activemodel (= 8.0.3)
68-
activesupport (= 8.0.3)
64+
activemodel (8.0.4.1)
65+
activesupport (= 8.0.4.1)
66+
activerecord (8.0.4.1)
67+
activemodel (= 8.0.4.1)
68+
activesupport (= 8.0.4.1)
6969
timeout (>= 0.4.0)
70-
activestorage (8.0.3)
71-
actionpack (= 8.0.3)
72-
activejob (= 8.0.3)
73-
activerecord (= 8.0.3)
74-
activesupport (= 8.0.3)
70+
activestorage (8.0.4.1)
71+
actionpack (= 8.0.4.1)
72+
activejob (= 8.0.4.1)
73+
activerecord (= 8.0.4.1)
74+
activesupport (= 8.0.4.1)
7575
marcel (~> 1.0)
76-
activesupport (8.0.3)
76+
activesupport (8.0.4.1)
7777
base64
7878
benchmark (>= 0.3)
7979
bigdecimal
@@ -82,7 +82,7 @@ GEM
8282
drb
8383
i18n (>= 1.6, < 2)
8484
logger (>= 1.4.2)
85-
minitest (>= 5.1)
85+
minitest (>= 5.1, < 6)
8686
securerandom (>= 0.3)
8787
tzinfo (~> 2.0, >= 2.0.5)
8888
uri (>= 0.13.1)
@@ -184,16 +184,16 @@ GEM
184184
irb (~> 1.10)
185185
reline (>= 0.3.8)
186186
debug_inspector (1.2.0)
187-
devise (4.9.4)
187+
devise (5.0.3)
188188
bcrypt (~> 3.0)
189189
orm_adapter (~> 0.1)
190-
railties (>= 4.1.0)
190+
railties (>= 7.0)
191191
responders
192192
warden (~> 1.2.3)
193-
devise-two-factor (6.2.0)
194-
activesupport (>= 7.0, < 8.2)
195-
devise (~> 4.0)
196-
railties (>= 7.0, < 8.2)
193+
devise-two-factor (6.4.0)
194+
activesupport (>= 7.2, < 8.2)
195+
devise (>= 4.0, < 6.0)
196+
railties (>= 7.2, < 8.2)
197197
rotp (~> 6.0)
198198
devise_pam_authenticatable2 (9.2.0)
199199
devise (>= 4.0.0)
@@ -233,7 +233,7 @@ GEM
233233
fabrication (3.0.0)
234234
faker (3.5.2)
235235
i18n (>= 1.8.11, < 2)
236-
faraday (2.14.0)
236+
faraday (2.14.1)
237237
faraday-net_http (>= 2.0, < 3.5)
238238
json
239239
logger
@@ -462,7 +462,7 @@ GEM
462462
net-smtp (0.5.1)
463463
net-protocol
464464
nio4r (2.7.4)
465-
nokogiri (1.18.10)
465+
nokogiri (1.19.2)
466466
mini_portile2 (~> 2.8.2)
467467
racc (~> 1.4)
468468
oj (3.16.11)
@@ -621,7 +621,7 @@ GEM
621621
activesupport (>= 3.0.0)
622622
raabro (1.4.0)
623623
racc (1.8.1)
624-
rack (3.2.4)
624+
rack (3.2.5)
625625
rack-attack (6.8.0)
626626
rack (>= 1.0, < 4)
627627
rack-cors (3.0.0)
@@ -647,20 +647,20 @@ GEM
647647
rack (>= 1.3)
648648
rackup (2.2.1)
649649
rack (>= 3)
650-
rails (8.0.3)
651-
actioncable (= 8.0.3)
652-
actionmailbox (= 8.0.3)
653-
actionmailer (= 8.0.3)
654-
actionpack (= 8.0.3)
655-
actiontext (= 8.0.3)
656-
actionview (= 8.0.3)
657-
activejob (= 8.0.3)
658-
activemodel (= 8.0.3)
659-
activerecord (= 8.0.3)
660-
activestorage (= 8.0.3)
661-
activesupport (= 8.0.3)
650+
rails (8.0.4.1)
651+
actioncable (= 8.0.4.1)
652+
actionmailbox (= 8.0.4.1)
653+
actionmailer (= 8.0.4.1)
654+
actionpack (= 8.0.4.1)
655+
actiontext (= 8.0.4.1)
656+
actionview (= 8.0.4.1)
657+
activejob (= 8.0.4.1)
658+
activemodel (= 8.0.4.1)
659+
activerecord (= 8.0.4.1)
660+
activestorage (= 8.0.4.1)
661+
activesupport (= 8.0.4.1)
662662
bundler (>= 1.15.0)
663-
railties (= 8.0.3)
663+
railties (= 8.0.4.1)
664664
rails-dom-testing (2.3.0)
665665
activesupport (>= 5.0.0)
666666
minitest
@@ -671,9 +671,9 @@ GEM
671671
rails-i18n (8.0.2)
672672
i18n (>= 0.7, < 2)
673673
railties (>= 8.0.0, < 9)
674-
railties (8.0.3)
675-
actionpack (= 8.0.3)
676-
activesupport (= 8.0.3)
674+
railties (8.0.4.1)
675+
actionpack (= 8.0.4.1)
676+
activesupport (= 8.0.4.1)
677677
irb (~> 1.13)
678678
rackup (>= 1.0.0)
679679
rake (>= 12.2)
@@ -954,7 +954,7 @@ DEPENDENCIES
954954
csv (~> 3.2)
955955
database_cleaner-active_record
956956
debug (~> 1.8)
957-
devise (~> 4.9)
957+
devise
958958
devise-two-factor
959959
devise_pam_authenticatable2 (~> 9.2)
960960
discard (~> 1.2)

app/controllers/accounts_controller.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ def show
1818
respond_to do |format|
1919
format.html do
2020
expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.hour) unless user_signed_in?
21+
22+
redirect_to short_account_path(@account) if account_id_param.present? && username_param.blank?
2123
end
2224

2325
format.rss do

app/controllers/auth/sessions_controller.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,14 +217,14 @@ def second_factor_attempts_key(user)
217217
"2fa_auth_attempts:#{user.id}:#{Time.now.utc.hour}"
218218
end
219219

220-
def respond_to_on_destroy
220+
def respond_to_on_destroy(**)
221221
respond_to do |format|
222222
format.json do
223223
render json: {
224224
redirect_to: after_sign_out_path_for(resource_name),
225225
}, status: 200
226226
end
227-
format.all { super }
227+
format.all { super(**) }
228228
end
229229
end
230230
end

app/controllers/statuses_controller.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ def show
2626
respond_to do |format|
2727
format.html do
2828
expires_in 10.seconds, public: true if current_account.nil?
29+
30+
redirect_to short_account_status_path(@account, @status) if account_id_param.present? && username_param.blank?
2931
end
3032

3133
format.json do

app/javascript/entrypoints/public.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,25 @@ function loaded() {
183183
({ target }) => {
184184
if (!(target instanceof HTMLInputElement)) return;
185185

186-
if (target.value && target.value.length > 0) {
186+
const checkedUsername = target.value;
187+
if (checkedUsername && checkedUsername.length > 0) {
187188
axios
188-
.get('/api/v1/accounts/lookup', { params: { acct: target.value } })
189+
.get('/api/v1/accounts/lookup', {
190+
params: { acct: checkedUsername },
191+
})
189192
.then(() => {
190-
target.setCustomValidity(formatMessage(messages.usernameTaken));
193+
// Only update the validity if the result is for the currently-typed username
194+
if (checkedUsername === target.value) {
195+
target.setCustomValidity(formatMessage(messages.usernameTaken));
196+
}
197+
191198
return true;
192199
})
193200
.catch(() => {
194-
target.setCustomValidity('');
201+
// Only update the validity if the result is for the currently-typed username
202+
if (checkedUsername === target.value) {
203+
target.setCustomValidity('');
204+
}
195205
});
196206
} else {
197207
target.setCustomValidity('');

app/javascript/mastodon/components/follow_button.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ export const FollowButton: React.FC<{
129129
: messages.follow;
130130

131131
let label;
132+
let disabled =
133+
relationship?.blocked_by || account?.suspended || !!account?.moved;
132134

133135
if (!signedIn) {
134136
label = intl.formatMessage(followMessage);
@@ -138,12 +140,16 @@ export const FollowButton: React.FC<{
138140
label = <LoadingIndicator />;
139141
} else if (relationship.muting) {
140142
label = intl.formatMessage(messages.unmute);
143+
disabled = false;
141144
} else if (relationship.following) {
142145
label = intl.formatMessage(messages.unfollow);
146+
disabled = false;
143147
} else if (relationship.blocking) {
144148
label = intl.formatMessage(messages.unblock);
149+
disabled = false;
145150
} else if (relationship.requested) {
146151
label = intl.formatMessage(messages.followRequestCancel);
152+
disabled = false;
147153
} else if (
148154
relationship.followed_by &&
149155
!account?.locked &&
@@ -172,11 +178,7 @@ export const FollowButton: React.FC<{
172178
return (
173179
<Button
174180
onClick={handleClick}
175-
disabled={
176-
relationship?.blocked_by ||
177-
(!(relationship?.following || relationship?.requested) &&
178-
(account?.suspended || !!account?.moved))
179-
}
181+
disabled={disabled}
180182
secondary={following}
181183
compact={compact}
182184
className={classNames(className, { 'button--destructive': following })}

0 commit comments

Comments
 (0)