Merge commit from fork

* Fix GHSA-7jvv-fhmg-wpfw

* Fix GHSA-hx34-2pfw-2qfj

* Fix GHSA-vwhj-3g83-v276

* Bump version to v4.6.4
This commit is contained in:
Claire 2026-07-27 16:02:01 +02:00 committed by Tarrien
parent 90553a2f33
commit 5d7e3bbd17
11 changed files with 67 additions and 19 deletions

View File

@ -2,6 +2,45 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## [4.6.4] - 2026-07-27
### Security
- Fix incorrect permission enforcement ([GHSA-7jvv-fhmg-wpfw](https://github.com/mastodon/mastodon/security/advisories/GHSA-7jvv-fhmg-wpfw), [GHSA-hx34-2pfw-2qfj](https://github.com/mastodon/mastodon/security/advisories/GHSA-hx34-2pfw-2qfj))
- Fix SSRF protection bypass via IPv4-compatible IPv6 addresses ([GHSA-vwhj-3g83-v276](https://github.com/mastodon/mastodon/security/advisories/GHSA-vwhj-3g83-v276))
- Update dependencies
### Changed
- Change autosuggestions to include second word in web UI (#39622 and #39696 by @Gargron and @zunda)
### Fixed
- Fix being unable to vote in polls without an expiration date (#39949 by @ClearlyClaire)
- Fix “Hide media with a warning” filters not being applied correctly (#39946 by @ClearlyClaire)
- Fix performance of user-focused queries in admin dashboard (#39929 by @ClearlyClaire)
- Fix Web Push subscription deletion endpoint incorrectly expecting anti-CSRF tokens (#39918 by @ClearlyClaire)
- Fix `ActivityPub::Activity::Create` trying to re-create known statuses when author changes (#39916 by @ClearlyClaire)
- Fix typo in quotes list error handling (#39904 by @shleeable)
- Fix lax relevancy check in inbound activity processing (#39892 by @ClearlyClaire)
- Fix `Account::Merging` concern not supporting Quotes or Collections, refactor it (#39884 by @ClearlyClaire)
- Fix various emoji search issues (#39815 by @ChaosExAnima)
- Fix swapped order of "accept/reject" actions in follow requests (#39862 by @diondiondion)
- Fix suspended accounts not being removed from follow request count in `/api/v1/accounts/verify_credentials` (#39858 by @ClearlyClaire)
- Fix "Learn more" link target in column post privacy hint (#39829 by @diondiondion)
- Fix page refresh when trying to save custom profile fields (#39828 by @diondiondion)
- Fix followed tags not being properly cleaned up when an account is deleted (#39824 by @shleeable)
- Fix CW being copied to body when editing quote posts with empty text (#39823 and #39837 by @shleeable and @ClearlyClaire)
- Fix handling of `QuoteRequest` rejections when those can't be found by `id` (#39820 by @shleeable)
- Fix autofollow option being ignored in invite moderation interface (#39819 by @shleeable)
- Fix pagination overlapping announcement reactions bar (#39814 by @diondiondion)
- Fix very wide images overflowing posts horizontally (#39812 by @diondiondion)
- Fix collections not being removed when an account is deleted (#39809 by @oneiros)
- Fix account followed languages selector (#39801 by @ChaosExAnima)
- Fix error handling in `ActivityPub::ProcessFeaturedItemService` (#39787 by @ClearlyClaire)
- Fix display of past relative times (#39742 by @ClearlyClaire)
- Fix pinned post button width (#39724 by @ChaosExAnima)
## [4.6.3] - 2026-07-03 ## [4.6.3] - 2026-07-03
### Security ### Security

View File

@ -14,7 +14,7 @@ module Admin
end end
def show def show
authorize @collection, :show? authorize [:admin, @collection], :show?
end end
def batch def batch

View File

@ -17,9 +17,9 @@ class Api::V1::Admin::MeasuresController < Api::BaseController
def set_measures def set_measures
@measures = Admin::Metrics::Measure.retrieve( @measures = Admin::Metrics::Measure.retrieve(
params[:keys], params.require(:keys),
params[:start_at], params.require(:start_at),
params[:end_at], params.require(:end_at),
params params
) )
end end

View File

@ -4,22 +4,22 @@ class Api::V1::Admin::RetentionController < Api::BaseController
include Authorization include Authorization
before_action -> { authorize_if_got_token! :'admin:read' } before_action -> { authorize_if_got_token! :'admin:read' }
before_action :set_cohorts before_action :set_retention
after_action :verify_authorized after_action :verify_authorized
def create def create
authorize :dashboard, :index? authorize :dashboard, :index?
render json: @cohorts, each_serializer: REST::Admin::CohortSerializer render json: @retention.cohorts, each_serializer: REST::Admin::CohortSerializer
end end
private private
def set_cohorts def set_retention
@cohorts = Admin::Metrics::Retention.new( @retention = Admin::Metrics::Retention.new(
params[:start_at], params.require(:start_at),
params[:end_at], params.require(:end_at),
params[:frequency] params[:frequency]
).cohorts )
end end
end end

View File

@ -17,6 +17,8 @@ class Admin::Metrics::Dimension::BaseDimension
@limit = limit&.to_i @limit = limit&.to_i
@params = params @params = params
@loaded = false @loaded = false
@start_at = [@start_at, @end_at - 2.years].max if @start_at.present? && @end_at.present?
end end
def key def key

View File

@ -12,10 +12,12 @@ class Admin::Metrics::Measure::BaseMeasure
alias loaded? loaded alias loaded? loaded
def initialize(start_at, end_at, params) def initialize(start_at, end_at, params)
@start_at = start_at&.to_datetime @start_at = start_at.to_datetime
@end_at = end_at&.to_datetime @end_at = end_at.to_datetime
@params = params @params = params
@loaded = false @loaded = false
@start_at = [@start_at, @end_at - 2.years].max
end end
def cache_key def cache_key

View File

@ -16,10 +16,13 @@ class Admin::Metrics::Retention
alias loaded? loaded alias loaded? loaded
def initialize(start_at, end_at, frequency) def initialize(start_at, end_at, frequency)
@start_at = start_at&.to_date @start_at = start_at.to_date
@end_at = end_at&.to_date @end_at = end_at.to_date
@frequency = %w(day month).include?(frequency) ? frequency : 'day' @frequency = %w(day month).include?(frequency) ? frequency : 'day'
@loaded = false @loaded = false
@start_at = [@start_at, @end_at - (@frequency == 'day' ? 31.days : 12.months)].max
end end
def cache_key def cache_key

View File

@ -34,7 +34,7 @@ module PrivateAddressCheck
module_function module_function
def private_address?(address) def private_address?(address)
address = address.native if address.ipv6? && address.ipv4_mapped? address = address.native if address.ipv6? && (address.ipv4_mapped? || address.ipv4_compat?)
address.private? || address.loopback? || address.link_local? || CIDR_LIST.any? { |cidr| cidr.include?(address) } address.private? || address.loopback? || address.link_local? || CIDR_LIST.any? { |cidr| cidr.include?(address) }
end end
end end

View File

@ -13,7 +13,7 @@ module Mastodon
end end
def patch def patch
3 4
end end
def default_prerelease def default_prerelease

View File

@ -20,6 +20,8 @@ RSpec.describe 'Admin Measures' do
domain: 'mastodon.social', domain: 'mastodon.social',
include_subdomains: true, include_subdomains: true,
}, },
start_at: '2026-01-01',
end_at: '2026-07-01',
} }
end end

View File

@ -10,7 +10,7 @@ RSpec.describe 'Admin Retention' do
describe 'GET /api/v1/admin/retention' do describe 'GET /api/v1/admin/retention' do
context 'when not authorized' do context 'when not authorized' do
it 'returns http forbidden' do it 'returns http forbidden' do
post '/api/v1/admin/retention', params: { account_id: account.id, limit: 2 } post '/api/v1/admin/retention', params: { start_at: '2025-01-04', end_at: '2025-07-05', frequency: 'month' }
expect(response) expect(response)
.to have_http_status(403) .to have_http_status(403)
@ -23,7 +23,7 @@ RSpec.describe 'Admin Retention' do
let(:scopes) { 'admin:read' } let(:scopes) { 'admin:read' }
it 'returns http success and status json' do it 'returns http success and status json' do
post '/api/v1/admin/retention', params: { account_id: account.id, limit: 2 }, headers: headers post '/api/v1/admin/retention', params: { start_at: '2025-01-04', end_at: '2025-07-05', frequency: 'month' }, headers: headers
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)