mirror of
https://github.com/yingziwu/mastodon.git
synced 2026-02-04 03:25:14 +00:00
Merge tag 'v4.2.15'
This commit is contained in:
commit
18aa575996
10 changed files with 121 additions and 72 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
|
@ -2,6 +2,18 @@
|
|||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [4.2.15] - 2025-01-16
|
||||
|
||||
### Security
|
||||
|
||||
- Fix insufficient validation of account URIs ([GHSA-5wxh-3p65-r4g6](https://github.com/mastodon/mastodon/security/advisories/GHSA-5wxh-3p65-r4g6))
|
||||
- Update dependencies
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix `libyaml` missing from `Dockerfile` build stage (#33591 by @vmstan)
|
||||
- Fix deletion of unconfirmed users with Webauthn set (#33186 by @ClearlyClaire)
|
||||
|
||||
## [4.2.14] - 2024-02-03
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ RUN apt-get update && \
|
|||
libgdbm-dev \
|
||||
libgmp-dev \
|
||||
libssl-dev \
|
||||
libyaml-dev \
|
||||
libyaml-0-2 \
|
||||
ca-certificates \
|
||||
libreadline8 \
|
||||
|
|
|
|||
117
Gemfile.lock
117
Gemfile.lock
|
|
@ -28,47 +28,47 @@ GIT
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actioncable (7.0.8.6)
|
||||
actionpack (= 7.0.8.6)
|
||||
activesupport (= 7.0.8.6)
|
||||
actioncable (7.0.8.7)
|
||||
actionpack (= 7.0.8.7)
|
||||
activesupport (= 7.0.8.7)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
actionmailbox (7.0.8.6)
|
||||
actionpack (= 7.0.8.6)
|
||||
activejob (= 7.0.8.6)
|
||||
activerecord (= 7.0.8.6)
|
||||
activestorage (= 7.0.8.6)
|
||||
activesupport (= 7.0.8.6)
|
||||
actionmailbox (7.0.8.7)
|
||||
actionpack (= 7.0.8.7)
|
||||
activejob (= 7.0.8.7)
|
||||
activerecord (= 7.0.8.7)
|
||||
activestorage (= 7.0.8.7)
|
||||
activesupport (= 7.0.8.7)
|
||||
mail (>= 2.7.1)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
actionmailer (7.0.8.6)
|
||||
actionpack (= 7.0.8.6)
|
||||
actionview (= 7.0.8.6)
|
||||
activejob (= 7.0.8.6)
|
||||
activesupport (= 7.0.8.6)
|
||||
actionmailer (7.0.8.7)
|
||||
actionpack (= 7.0.8.7)
|
||||
actionview (= 7.0.8.7)
|
||||
activejob (= 7.0.8.7)
|
||||
activesupport (= 7.0.8.7)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (7.0.8.6)
|
||||
actionview (= 7.0.8.6)
|
||||
activesupport (= 7.0.8.6)
|
||||
actionpack (7.0.8.7)
|
||||
actionview (= 7.0.8.7)
|
||||
activesupport (= 7.0.8.7)
|
||||
rack (~> 2.0, >= 2.2.4)
|
||||
rack-test (>= 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||
actiontext (7.0.8.6)
|
||||
actionpack (= 7.0.8.6)
|
||||
activerecord (= 7.0.8.6)
|
||||
activestorage (= 7.0.8.6)
|
||||
activesupport (= 7.0.8.6)
|
||||
actiontext (7.0.8.7)
|
||||
actionpack (= 7.0.8.7)
|
||||
activerecord (= 7.0.8.7)
|
||||
activestorage (= 7.0.8.7)
|
||||
activesupport (= 7.0.8.7)
|
||||
globalid (>= 0.6.0)
|
||||
nokogiri (>= 1.8.5)
|
||||
actionview (7.0.8.6)
|
||||
activesupport (= 7.0.8.6)
|
||||
actionview (7.0.8.7)
|
||||
activesupport (= 7.0.8.7)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
|
|
@ -78,22 +78,22 @@ GEM
|
|||
activemodel (>= 4.1, < 7.1)
|
||||
case_transform (>= 0.2)
|
||||
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
||||
activejob (7.0.8.6)
|
||||
activesupport (= 7.0.8.6)
|
||||
activejob (7.0.8.7)
|
||||
activesupport (= 7.0.8.7)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (7.0.8.6)
|
||||
activesupport (= 7.0.8.6)
|
||||
activerecord (7.0.8.6)
|
||||
activemodel (= 7.0.8.6)
|
||||
activesupport (= 7.0.8.6)
|
||||
activestorage (7.0.8.6)
|
||||
actionpack (= 7.0.8.6)
|
||||
activejob (= 7.0.8.6)
|
||||
activerecord (= 7.0.8.6)
|
||||
activesupport (= 7.0.8.6)
|
||||
activemodel (7.0.8.7)
|
||||
activesupport (= 7.0.8.7)
|
||||
activerecord (7.0.8.7)
|
||||
activemodel (= 7.0.8.7)
|
||||
activesupport (= 7.0.8.7)
|
||||
activestorage (7.0.8.7)
|
||||
actionpack (= 7.0.8.7)
|
||||
activejob (= 7.0.8.7)
|
||||
activerecord (= 7.0.8.7)
|
||||
activesupport (= 7.0.8.7)
|
||||
marcel (~> 1.0)
|
||||
mini_mime (>= 1.1.0)
|
||||
activesupport (7.0.8.6)
|
||||
activesupport (7.0.8.7)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
|
|
@ -469,7 +469,7 @@ GEM
|
|||
net-protocol
|
||||
net-ssh (7.1.0)
|
||||
nio4r (2.7.4)
|
||||
nokogiri (1.16.7)
|
||||
nokogiri (1.16.8)
|
||||
mini_portile2 (~> 2.8.2)
|
||||
racc (~> 1.4)
|
||||
nsa (0.3.0)
|
||||
|
|
@ -550,20 +550,20 @@ GEM
|
|||
rack
|
||||
rack-test (2.1.0)
|
||||
rack (>= 1.3)
|
||||
rails (7.0.8.6)
|
||||
actioncable (= 7.0.8.6)
|
||||
actionmailbox (= 7.0.8.6)
|
||||
actionmailer (= 7.0.8.6)
|
||||
actionpack (= 7.0.8.6)
|
||||
actiontext (= 7.0.8.6)
|
||||
actionview (= 7.0.8.6)
|
||||
activejob (= 7.0.8.6)
|
||||
activemodel (= 7.0.8.6)
|
||||
activerecord (= 7.0.8.6)
|
||||
activestorage (= 7.0.8.6)
|
||||
activesupport (= 7.0.8.6)
|
||||
rails (7.0.8.7)
|
||||
actioncable (= 7.0.8.7)
|
||||
actionmailbox (= 7.0.8.7)
|
||||
actionmailer (= 7.0.8.7)
|
||||
actionpack (= 7.0.8.7)
|
||||
actiontext (= 7.0.8.7)
|
||||
actionview (= 7.0.8.7)
|
||||
activejob (= 7.0.8.7)
|
||||
activemodel (= 7.0.8.7)
|
||||
activerecord (= 7.0.8.7)
|
||||
activestorage (= 7.0.8.7)
|
||||
activesupport (= 7.0.8.7)
|
||||
bundler (>= 1.15.0)
|
||||
railties (= 7.0.8.6)
|
||||
railties (= 7.0.8.7)
|
||||
rails-controller-testing (1.0.5)
|
||||
actionpack (>= 5.0.1.rc1)
|
||||
actionview (>= 5.0.1.rc1)
|
||||
|
|
@ -572,15 +572,15 @@ GEM
|
|||
activesupport (>= 5.0.0)
|
||||
minitest
|
||||
nokogiri (>= 1.6)
|
||||
rails-html-sanitizer (1.6.0)
|
||||
rails-html-sanitizer (1.6.2)
|
||||
loofah (~> 2.21)
|
||||
nokogiri (~> 1.14)
|
||||
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
||||
rails-i18n (7.0.7)
|
||||
i18n (>= 0.7, < 2)
|
||||
railties (>= 6.0.0, < 8)
|
||||
railties (7.0.8.6)
|
||||
actionpack (= 7.0.8.6)
|
||||
activesupport (= 7.0.8.6)
|
||||
railties (7.0.8.7)
|
||||
actionpack (= 7.0.8.7)
|
||||
activesupport (= 7.0.8.7)
|
||||
method_source
|
||||
rake (>= 12.2)
|
||||
thor (~> 1.0)
|
||||
|
|
@ -743,7 +743,7 @@ GEM
|
|||
test-prof (1.2.3)
|
||||
thor (1.3.2)
|
||||
tilt (2.2.0)
|
||||
timeout (0.4.2)
|
||||
timeout (0.4.3)
|
||||
tpm-key_attestation (0.12.0)
|
||||
bindata (~> 2.4)
|
||||
openssl (> 2.0)
|
||||
|
|
@ -800,7 +800,8 @@ GEM
|
|||
railties (>= 5.2)
|
||||
semantic_range (>= 2.3.0)
|
||||
websocket (1.2.9)
|
||||
websocket-driver (0.7.6)
|
||||
websocket-driver (0.7.7)
|
||||
base64
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.5)
|
||||
wisper (2.0.1)
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ class DeliveryFailureTracker
|
|||
urls.reject do |url|
|
||||
host = Addressable::URI.parse(url).normalized_host
|
||||
unavailable_domains_map[host]
|
||||
rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ class ActivityPub::ProcessAccountService < BaseService
|
|||
SUBDOMAINS_RATELIMIT = 10
|
||||
DISCOVERIES_PER_REQUEST = 400
|
||||
|
||||
VALID_URI_SCHEMES = %w(http https).freeze
|
||||
|
||||
# Should be called with confirmed valid JSON
|
||||
# and WebFinger-resolved username and domain
|
||||
def call(username, domain, json, options = {})
|
||||
|
|
@ -96,16 +98,28 @@ class ActivityPub::ProcessAccountService < BaseService
|
|||
end
|
||||
|
||||
def set_immediate_protocol_attributes!
|
||||
@account.inbox_url = @json['inbox'] || ''
|
||||
@account.outbox_url = @json['outbox'] || ''
|
||||
@account.shared_inbox_url = (@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox']) || ''
|
||||
@account.followers_url = @json['followers'] || ''
|
||||
@account.inbox_url = valid_collection_uri(@json['inbox'])
|
||||
@account.outbox_url = valid_collection_uri(@json['outbox'])
|
||||
@account.shared_inbox_url = valid_collection_uri(@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox'])
|
||||
@account.followers_url = valid_collection_uri(@json['followers'])
|
||||
@account.url = url || @uri
|
||||
@account.uri = @uri
|
||||
@account.actor_type = actor_type
|
||||
@account.created_at = @json['published'] if @json['published'].present?
|
||||
end
|
||||
|
||||
def valid_collection_uri(uri)
|
||||
uri = uri.first if uri.is_a?(Array)
|
||||
uri = uri['id'] if uri.is_a?(Hash)
|
||||
return '' unless uri.is_a?(String)
|
||||
|
||||
parsed_uri = Addressable::URI.parse(uri)
|
||||
|
||||
VALID_URI_SCHEMES.include?(parsed_uri.scheme) && parsed_uri.host.present? ? parsed_uri : ''
|
||||
rescue Addressable::URI::InvalidURIError
|
||||
''
|
||||
end
|
||||
|
||||
def set_immediate_attributes!
|
||||
@account.featured_collection_url = @json['featured'] || ''
|
||||
@account.devices_url = @json['devices'] || ''
|
||||
|
|
@ -268,10 +282,11 @@ class ActivityPub::ProcessAccountService < BaseService
|
|||
end
|
||||
|
||||
def collection_info(type)
|
||||
return [nil, nil] if @json[type].blank?
|
||||
collection_uri = valid_collection_uri(@json[type])
|
||||
return [nil, nil] if collection_uri.blank?
|
||||
return @collections[type] if @collections.key?(type)
|
||||
|
||||
collection = fetch_resource_without_id_validation(@json[type])
|
||||
collection = fetch_resource_without_id_validation(collection_uri)
|
||||
|
||||
total_items = collection.is_a?(Hash) && collection['totalItems'].present? && collection['totalItems'].is_a?(Numeric) ? collection['totalItems'] : nil
|
||||
has_first_page = collection.is_a?(Hash) && collection['first'].present?
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ class Scheduler::UserCleanupScheduler
|
|||
User.where('confirmed_at is NULL AND confirmation_sent_at <= ?', 2.days.ago).reorder(nil).find_in_batches do |batch|
|
||||
# We have to do it separately because of missing database constraints
|
||||
AccountModerationNote.where(target_account_id: batch.map(&:account_id)).delete_all
|
||||
WebauthnCredential.where(user_id: batch.map(&:id)).delete_all
|
||||
Account.where(id: batch.map(&:account_id)).delete_all
|
||||
User.where(id: batch.map(&:id)).delete_all
|
||||
end
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ services:
|
|||
|
||||
web:
|
||||
build: .
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.14
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.15
|
||||
restart: always
|
||||
env_file: .env.production
|
||||
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
|
||||
|
|
@ -77,7 +77,7 @@ services:
|
|||
|
||||
streaming:
|
||||
build: .
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.14
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.15
|
||||
restart: always
|
||||
env_file: .env.production
|
||||
command: node ./streaming
|
||||
|
|
@ -95,7 +95,7 @@ services:
|
|||
|
||||
sidekiq:
|
||||
build: .
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.14
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.15
|
||||
restart: always
|
||||
env_file: .env.production
|
||||
command: bundle exec sidekiq
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ module Mastodon
|
|||
end
|
||||
|
||||
def patch
|
||||
14
|
||||
15
|
||||
end
|
||||
|
||||
def default_prerelease
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ describe DeliveryFailureTracker do
|
|||
Fabricate(:unavailable_domain, domain: 'foo.bar')
|
||||
end
|
||||
|
||||
it 'removes URLs that are unavailable' do
|
||||
results = described_class.without_unavailable(['http://example.com/good/inbox', 'http://foo.bar/unavailable/inbox'])
|
||||
it 'removes URLs that are bogus or unavailable' do
|
||||
results = described_class.without_unavailable(['http://example.com/good/inbox', 'http://foo.bar/unavailable/inbox', '{foo:'])
|
||||
|
||||
expect(results).to include('http://example.com/good/inbox')
|
||||
expect(results).to_not include('http://foo.bar/unavailable/inbox')
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ describe Scheduler::UserCleanupScheduler do
|
|||
let!(:old_unconfirmed_user) { Fabricate(:user) }
|
||||
let!(:confirmed_user) { Fabricate(:user) }
|
||||
let!(:moderation_note) { Fabricate(:account_moderation_note, account: Fabricate(:account), target_account: old_unconfirmed_user.account) }
|
||||
let!(:webauthn_credential) { Fabricate(:webauthn_credential, user_id: old_unconfirmed_user.id) }
|
||||
|
||||
describe '#perform' do
|
||||
before do
|
||||
|
|
@ -18,8 +19,24 @@ describe Scheduler::UserCleanupScheduler do
|
|||
confirmed_user.update!(confirmed_at: 1.day.ago)
|
||||
end
|
||||
|
||||
it 'deletes the old unconfirmed user' do
|
||||
expect { subject.perform }.to change { User.exists?(old_unconfirmed_user.id) }.from(true).to(false)
|
||||
it 'deletes the old unconfirmed user and metadata while preserving confirmed user and newer unconfirmed user' do
|
||||
expect { subject.perform }
|
||||
.to change { User.exists?(old_unconfirmed_user.id) }
|
||||
.from(true).to(false)
|
||||
.and change { Account.exists?(old_unconfirmed_user.account_id) }
|
||||
.from(true).to(false)
|
||||
expect { moderation_note.reload }
|
||||
.to raise_error(ActiveRecord::RecordNotFound)
|
||||
expect { webauthn_credential.reload }
|
||||
.to raise_error(ActiveRecord::RecordNotFound)
|
||||
expect(User.exists?(new_unconfirmed_user.id))
|
||||
.to be true
|
||||
expect(User.exists?(confirmed_user.id))
|
||||
.to be true
|
||||
expect(Account.exists?(new_unconfirmed_user.account_id))
|
||||
.to be true
|
||||
expect(Account.exists?(confirmed_user.account_id))
|
||||
.to be true
|
||||
end
|
||||
|
||||
it "deletes the old unconfirmed user's account" do
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue