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:
parent
90553a2f33
commit
5d7e3bbd17
39
CHANGELOG.md
39
CHANGELOG.md
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -13,7 +13,7 @@ module Mastodon
|
|||||||
end
|
end
|
||||||
|
|
||||||
def patch
|
def patch
|
||||||
3
|
4
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_prerelease
|
def default_prerelease
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user