Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update/imastodon v4.1.17 #469

Merged
merged 27 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
142dd34
Fix CI not actually running ruby tests in 4.1 branch (#30321)
ClearlyClaire May 16, 2024
37adb14
Fix auto close registration mail (#30323)
ClearlyClaire May 16, 2024
57b72cc
Fix reference to non-existent var in CLI maintenance command (#28363)
mjankowski Dec 14, 2023
079d3e5
Add fallback redirection when getting a webfinger query `WEB_DOMAIN@W…
ClearlyClaire Jan 4, 2024
209632a
Return domain block digests from admin domain blocks API (#29092)
ThisIsMissEm Feb 6, 2024
affbb10
Fix admin account created by `mastodon:setup` not being auto-approved…
ClearlyClaire Feb 23, 2024
3ff575f
Normalize idna domain before account unblock domain (#29530)
tribela Mar 11, 2024
8ce403a
Fix results/query in `api/v1/featured_tags/suggestions` (#29597)
mjankowski Mar 22, 2024
ba5551f
Improve email address validation (#29838)
ClearlyClaire Apr 5, 2024
5973d7a
Remove caching in `cache_collection` (#29862)
ClearlyClaire Apr 8, 2024
a6089cd
Fixed crash when supplying FFMPEG_BINARY environment variable (#30022)
timothyjrogers Apr 22, 2024
70c4d70
Fix Idempotency-Key ignored when scheduling a post (#30084)
ClearlyClaire Apr 26, 2024
33a5088
Fix not being able to block a subdomain of an already-blocked domain …
ClearlyClaire May 2, 2024
984d7d3
Fix missing destory audit logs for Domain Allows (#30125)
ThisIsMissEm Apr 30, 2024
3aec33f
Fix off-by-one in `tootctl media` commands (#30306)
ClearlyClaire May 15, 2024
13bbcdf
Update dependency json-jwt to 1.15.3.1
ClearlyClaire May 16, 2024
c717b7d
Update dependency puma to 5.6.8
ClearlyClaire May 16, 2024
b39fbe7
Update dependency nokogiri to 1.16.5
ClearlyClaire May 16, 2024
b4e3a78
Update dependency rexml to 3.2.8
ClearlyClaire May 29, 2024
257f9ab
Fix leaking Elasticsearch connections in Sidekiq processes (#30450)
ClearlyClaire May 29, 2024
ba240ce
Normalize language code of incoming posts (#30403)
ClearlyClaire May 23, 2024
e292a28
Merge pull request from GHSA-5fq7-3p3j-9vrf
ClearlyClaire May 30, 2024
020228d
Merge pull request from GHSA-q3rg-xx5v-4mxh
ClearlyClaire May 30, 2024
d770b61
Merge pull request from GHSA-c2r5-cfqr-c553
ClearlyClaire May 30, 2024
95ebcff
Fix rate-limiting incorrectly triggering a session cookie on most end…
ClearlyClaire May 30, 2024
1cad857
Bump version to v4.1.17 (#30472)
ClearlyClaire May 30, 2024
012e3fe
Merge tag 'v4.1.17' into update/imastodon-v4.1.18
takayamaki Jul 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/test-ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,5 @@ jobs:

- name: Load database schema
run: './bin/rails db:create db:schema:load db:seed'

- run: bin/rspec
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,39 @@ Changelog

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

## [4.1.17] - 2024-05-30

### Security

- Update dependencies
- Fix private mention filtering ([GHSA-5fq7-3p3j-9vrf](https://github.com/mastodon/mastodon/security/advisories/GHSA-5fq7-3p3j-9vrf))
- Fix password change endpoint not being rate-limited ([GHSA-q3rg-xx5v-4mxh](https://github.com/mastodon/mastodon/security/advisories/GHSA-q3rg-xx5v-4mxh))
- Add hardening around rate-limit bypass ([GHSA-c2r5-cfqr-c553](https://github.com/mastodon/mastodon/security/advisories/GHSA-c2r5-cfqr-c553))

### Added

- Add fallback redirection when getting a webfinger query `WEB_DOMAIN@WEB_DOMAIN` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28592))
- Add `digest` attribute to `Admin::DomainBlock` entity in REST API ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/29092))

### Removed

- Remove superfluous application-level caching in some controllers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29862))

### Fixed

- Fix leaking Elasticsearch connections in Sidekiq processes ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30450))
- Fix language of remote posts not being recognized when using unusual casing ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30403))
- Fix off-by-one in `tootctl media` commands ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30306))
- Fix removal of allowed domains (in `LIMITED_FEDERATION_MODE`) not being recorded in the audit log ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/30125))
- Fix not being able to block a subdomain of an already-blocked domain through the API ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30119))
- Fix `Idempotency-Key` being ignored when scheduling a post ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30084))
- Fix crash when supplying the `FFMPEG_BINARY` environment variable ([timothyjrogers](https://github.com/mastodon/mastodon/pull/30022))
- Fix improper email address validation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29838))
- Fix results/query in `api/v1/featured_tags/suggestions` ([mjankowski](https://github.com/mastodon/mastodon/pull/29597))
- Fix unblocking internationalized domain names under certain conditions ([tribela](https://github.com/mastodon/mastodon/pull/29530))
- Fix admin account created by `mastodon:setup` not being auto-approved ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29379))
- Fix reference to non-existent var in CLI maintenance command ([mjankowski](https://github.com/mastodon/mastodon/pull/28363))

## [4.1.16] - 2024-02-23

### Added
Expand Down
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,4 @@ gem 'concurrent-ruby', require: false
gem 'connection_pool', require: false
gem 'xorcist', '~> 1.1'
gem 'cocoon', '~> 1.2'
gem 'mail', '~> 2.8'
11 changes: 7 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ GEM
jmespath (1.6.2)
json (2.6.3)
json-canonicalization (0.3.0)
json-jwt (1.15.3)
json-jwt (1.15.3.1)
activesupport (>= 4.2)
aes_key_wrap
bindata
Expand Down Expand Up @@ -424,7 +424,7 @@ GEM
net-protocol
net-ssh (7.0.1)
nio4r (2.5.9)
nokogiri (1.16.2)
nokogiri (1.16.5)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
nsa (0.2.8)
Expand Down Expand Up @@ -491,7 +491,7 @@ GEM
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (5.0.1)
puma (5.6.7)
puma (5.6.8)
nio4r (~> 2.0)
pundit (2.3.0)
activesupport (>= 3.0.0)
Expand Down Expand Up @@ -565,7 +565,8 @@ GEM
responders (3.0.1)
actionpack (>= 5.0)
railties (>= 5.0)
rexml (3.2.5)
rexml (3.2.8)
strscan (>= 3.0.9)
rotp (6.2.0)
rpam2 (4.0.2)
rqrcode (2.1.2)
Expand Down Expand Up @@ -679,6 +680,7 @@ GEM
redlock (~> 1.0)
strong_migrations (0.7.9)
activerecord (>= 5)
strscan (3.1.0)
swd (1.3.0)
activesupport (>= 3)
attr_required (>= 0.0.5)
Expand Down Expand Up @@ -816,6 +818,7 @@ DEPENDENCIES
letter_opener_web (~> 2.0)
link_header (~> 0.0)
lograge (~> 0.12)
mail (~> 2.8)
makara (~> 0.5)
mario-redis-lock (~> 1.2)
memory_profiler
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/admin/domain_allows_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def create
def destroy
authorize @domain_allow, :destroy?
UnallowDomainService.new.call(@domain_allow)
log_action :destroy, @domain_allow

redirect_to admin_instances_path, notice: I18n.t('admin.domain_allows.destroyed_msg')
end

Expand Down
9 changes: 7 additions & 2 deletions app/controllers/api/v1/admin/domain_blocks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
def create
authorize :domain_block, :create?

@domain_block = DomainBlock.new(resource_params)
existing_domain_block = resource_params[:domain].present? ? DomainBlock.rule_for(resource_params[:domain]) : nil
return render json: existing_domain_block, serializer: REST::Admin::ExistingDomainBlockErrorSerializer, status: 422 if existing_domain_block.present?
return render json: existing_domain_block, serializer: REST::Admin::ExistingDomainBlockErrorSerializer, status: 422 if conflicts_with_existing_block?(@domain_block, existing_domain_block)

@domain_block = DomainBlock.create!(resource_params)
@domain_block.save!
DomainBlockWorker.perform_async(@domain_block.id)
log_action :create, @domain_block
render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer
Expand Down Expand Up @@ -55,6 +56,10 @@ def destroy

private

def conflicts_with_existing_block?(domain_block, existing_domain_block)
existing_domain_block.present? && (existing_domain_block.domain == TagManager.instance.normalize_domain(domain_block.domain) || !domain_block.stricter_than?(existing_domain_block))
end

def set_domain_blocks
@domain_blocks = filtered_domain_blocks.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ def index
private

def set_recently_used_tags
@recently_used_tags = Tag.recently_used(current_account).where.not(id: current_account.featured_tags).limit(10)
@recently_used_tags = Tag.recently_used(current_account).where.not(id: featured_tag_ids).limit(10)
end

def featured_tag_ids
current_account.featured_tags.pluck(:tag_id)
end
end
24 changes: 7 additions & 17 deletions app/controllers/concerns/cache_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,19 @@ def set_cache_headers
response.headers['Vary'] = public_fetch_mode? ? 'Accept' : 'Accept, Signature'
end

# TODO: Rename this method, as it does not perform any caching anymore.
def cache_collection(raw, klass)
return raw unless klass.respond_to?(:with_includes)
return raw unless klass.respond_to?(:preload_cacheable_associations)

raw = raw.cache_ids.to_a if raw.is_a?(ActiveRecord::Relation)
return [] if raw.empty?
records = raw.to_a

cached_keys_with_value = Rails.cache.read_multi(*raw).transform_keys(&:id)
uncached_ids = raw.map(&:id) - cached_keys_with_value.keys
klass.preload_cacheable_associations(records)

klass.reload_stale_associations!(cached_keys_with_value.values) if klass.respond_to?(:reload_stale_associations!)

unless uncached_ids.empty?
uncached = klass.where(id: uncached_ids).with_includes.index_by(&:id)

uncached.each_value do |item|
Rails.cache.write(item, item)
end
end

raw.filter_map { |item| cached_keys_with_value[item.id] || uncached[item.id] }
records
end

# TODO: Rename this method, as it does not perform any caching anymore.
def cache_collection_paginated_by_id(raw, klass, limit, options)
cache_collection raw.cache_ids.to_a_paginated_by_id(limit, options), klass
cache_collection raw.to_a_paginated_by_id(limit, options), klass
end
end
2 changes: 1 addition & 1 deletion app/controllers/well_known/webfinger_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def show
def set_account
username = username_from_resource
@account = begin
if username == Rails.configuration.x.local_domain
if username == Rails.configuration.x.local_domain || username == Rails.configuration.x.web_domain
Account.representative
else
Account.find_local!(username)
Expand Down
11 changes: 9 additions & 2 deletions app/lib/activitypub/parser/status_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
class ActivityPub::Parser::StatusParser
include JsonLdHelper

NORMALIZED_LOCALE_NAMES = LanguagesHelper::SUPPORTED_LOCALES.keys.index_by(&:downcase).freeze

# @param [Hash] json
# @param [Hash] magic_values
# @option magic_values [String] :followers_collection
Expand Down Expand Up @@ -86,6 +88,13 @@ def visibility
end

def language
lang = raw_language_code
lang.presence && NORMALIZED_LOCALE_NAMES.fetch(lang.downcase.to_sym, lang)
end

private

def raw_language_code
if content_language_map?
@object['contentMap'].keys.first
elsif name_language_map?
Expand All @@ -95,8 +104,6 @@ def language
end
end

private

def audience_to
as_array(@object['to'] || @json['to']).map { |x| value_or_id(x) }
end
Expand Down
2 changes: 1 addition & 1 deletion app/lib/video_metadata_extractor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def valid?
private

def ffmpeg_command_output
command = Terrapin::CommandLine.new('ffprobe', '-i :path -print_format :format -show_format -show_streams -show_error -loglevel :loglevel')
command = Terrapin::CommandLine.new(Rails.configuration.x.ffprobe_binary, '-i :path -print_format :format -show_format -show_streams -show_error -loglevel :loglevel')
command.run(path: @path, format: 'json', loglevel: 'fatal')
end

Expand Down
6 changes: 5 additions & 1 deletion app/models/concerns/account_interactions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def unmute_conversation!(conversation)
end

def unblock_domain!(other_domain)
block = domain_blocks.find_by(domain: other_domain)
block = domain_blocks.find_by(domain: normalized_domain(other_domain))
block&.destroy
end

Expand Down Expand Up @@ -299,4 +299,8 @@ def local_followers_hash
def remove_potential_friendship(other_account)
PotentialFriendshipTracker.remove(id, other_account.id)
end

def normalized_domain(domain)
TagManager.instance.normalize_domain(domain)
end
end
4 changes: 4 additions & 0 deletions app/models/concerns/cacheable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ def with_includes
includes(@cache_associated)
end

def preload_cacheable_associations(records)
ActiveRecord::Associations::Preloader.new.preload(records, @cache_associated)
end

def cache_ids
select(:id, :updated_at)
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/feed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def from_redis(limit, max_id, since_id, min_id)
unhydrated = redis.zrangebyscore(key, "(#{min_id}", "(#{max_id}", limit: [0, limit], with_scores: true).map(&:first).map(&:to_i)
end

Status.where(id: unhydrated).cache_ids
Status.where(id: unhydrated)
end

def key
Expand Down
2 changes: 1 addition & 1 deletion app/models/public_feed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def get(limit, max_id = nil, since_id = nil, min_id = nil)
scope.merge!(media_only_scope) if media_only?
scope.merge!(language_scope) if account&.chosen_languages.present?

scope.cache_ids.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id)
scope.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id)
end

private
Expand Down
32 changes: 0 additions & 32 deletions app/models/status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -345,38 +345,6 @@ def pins_map(status_ids, account_id)
StatusPin.select('status_id').where(status_id: status_ids).where(account_id: account_id).each_with_object({}) { |p, h| h[p.status_id] = true }
end

def reload_stale_associations!(cached_items)
account_ids = []

cached_items.each do |item|
account_ids << item.account_id
account_ids << item.reblog.account_id if item.reblog?
end

account_ids.uniq!

status_ids = cached_items.map { |item| item.reblog? ? item.reblog_of_id : item.id }.uniq

return if account_ids.empty?

accounts = Account.where(id: account_ids).includes(:account_stat, :user).index_by(&:id)

status_stats = StatusStat.where(status_id: status_ids).index_by(&:status_id)

cached_items.each do |item|
item.account = accounts[item.account_id]
item.reblog.account = accounts[item.reblog.account_id] if item.reblog?

if item.reblog?
status_stat = status_stats[item.reblog.id]
item.reblog.status_stat = status_stat if status_stat.present?
else
status_stat = status_stats[item.id]
item.status_stat = status_stat if status_stat.present?
end
end
end

def from_text(text)
return [] if text.blank?

Expand Down
2 changes: 1 addition & 1 deletion app/models/tag_feed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def get(limit, max_id = nil, since_id = nil, min_id = nil)
scope.merge!(account_filters_scope) if account?
scope.merge!(media_only_scope) if media_only?

scope.cache_ids.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id)
scope.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id)
end

private
Expand Down
3 changes: 3 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ class User < ApplicationRecord
validates :invite_request, presence: true, on: :create, if: :invite_text_required?

validates :locale, inclusion: I18n.available_locales.map(&:to_s), if: :locale?

validates :email, presence: true, email_address: true

validates_with BlacklistedEmailValidator, if: -> { ENV['EMAIL_DOMAIN_LISTS_APPLY_AFTER_CONFIRMATION'] == 'true' || !confirmed? }
validates_with EmailMxValidator, if: :validate_email_dns?
validates :agreement, acceptance: { allow_nil: false, accept: [true, 'true', '1'] }, on: :create
Expand Down
6 changes: 5 additions & 1 deletion app/serializers/rest/admin/domain_block_serializer.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
# frozen_string_literal: true

class REST::Admin::DomainBlockSerializer < ActiveModel::Serializer
attributes :id, :domain, :created_at, :severity,
attributes :id, :domain, :digest, :created_at, :severity,
:reject_media, :reject_reports,
:private_comment, :public_comment, :obfuscate

def id
object.id.to_s
end

def digest
object.domain_digest
end
end
17 changes: 9 additions & 8 deletions app/services/notify_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,17 @@ def response_to_recipient?
LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id
WHERE s.id = :id
UNION ALL
SELECT s.id, s.in_reply_to_id, m.id, st.path || s.id, st.depth + 1
FROM ancestors st
JOIN statuses s ON s.id = st.in_reply_to_id
LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id
WHERE st.mention_id IS NULL AND NOT s.id = ANY(path) AND st.depth < :depth_limit
SELECT s.id, s.in_reply_to_id, m.id, ancestors.path || s.id, ancestors.depth + 1
FROM ancestors
JOIN statuses s ON s.id = ancestors.in_reply_to_id
/* early exit if we already have a mention matching our requirements */
LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id AND s.account_id = :recipient_id
WHERE ancestors.mention_id IS NULL AND NOT s.id = ANY(path) AND ancestors.depth < :depth_limit
)
SELECT COUNT(*)
FROM ancestors st
JOIN statuses s ON s.id = st.id
WHERE st.mention_id IS NOT NULL AND s.visibility = 3
FROM ancestors
JOIN statuses s ON s.id = ancestors.id
WHERE ancestors.mention_id IS NOT NULL AND s.account_id = :recipient_id AND s.visibility = 3
SQL
end

Expand Down
Loading
Loading