0
0
Fork 0

Merge remote-tracking branch 'upstream/main'

This commit is contained in:
ASTRO:? 2025-03-14 20:25:34 +09:00
commit d564483d30
No known key found for this signature in database
GPG key ID: 2938B9B314D8EF8B
1796 changed files with 48111 additions and 29322 deletions

View file

@ -4,14 +4,4 @@
# before other initializers as Rails may otherwise memoize a list of migrations
# excluding the post deployment migrations.
unless ENV['SKIP_POST_DEPLOYMENT_MIGRATIONS']
Rails.application.config.paths['db'].each do |db_path|
path = Rails.root.join(db_path, 'post_migrate').to_s
Rails.application.config.paths['db/migrate'] << path
# Rails memoizes migrations at certain points where it won't read the above
# path just yet. As such we must also update the following list of paths.
ActiveRecord::Migrator.migrations_paths << path
end
end
Mastodon::Database.add_post_migrate_path_to_rails

View file

@ -0,0 +1,5 @@
# frozen_string_literal: true
Rails.application.configure do
config.x.private_address_exceptions = (ENV['ALLOWED_PRIVATE_ADDRESSES'] || '').split(/(?:\s*,\s*|\s+)/).map { |addr| IPAddr.new(addr) }
end

View file

@ -1,23 +0,0 @@
# frozen_string_literal: true
# TODO: remove this file some time after 4.3.0
Rails.application.config.after_initialize do
Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies|
authenticated_encrypted_cookie_salt = Rails.application.config.action_dispatch.authenticated_encrypted_cookie_salt
signed_cookie_salt = Rails.application.config.action_dispatch.signed_cookie_salt
secret_key_base = Rails.application.secret_key_base
key_generator = ActiveSupport::KeyGenerator.new(
secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA1
)
key_len = ActiveSupport::MessageEncryptor.key_len
old_encrypted_secret = key_generator.generate_key(authenticated_encrypted_cookie_salt, key_len)
old_signed_secret = key_generator.generate_key(signed_cookie_salt)
cookies.rotate :encrypted, old_encrypted_secret
cookies.rotate :signed, old_signed_secret
end
end

View file

@ -23,6 +23,7 @@ Rails.application.config.middleware.insert_before 0, Rack::Cors do
methods: %i(post put delete get patch options)
resource '/oauth/token', methods: [:post]
resource '/oauth/revoke', methods: [:post]
resource '/oauth/userinfo', methods: [:get, :post]
end
end
end

View file

@ -52,6 +52,9 @@ Doorkeeper.configure do
# Issue access tokens with refresh token (disabled by default)
# use_refresh_token
# Proof of Key Code Exchange
pkce_code_challenge_methods ['S256']
# Forbids creating/updating applications with arbitrary scopes that are
# not in configuration, i.e. `default_scopes` or `optional_scopes`.
# (Disabled by default)

View file

@ -1,13 +0,0 @@
# frozen_string_literal: true
# Automatically enable YJIT as of Ruby 3.3, as it brings very
# sizeable performance improvements.
# If you are deploying to a memory constrained environment
# you may want to delete this file, but otherwise it's free
# performance.
if defined?(RubyVM::YJIT.enable)
Rails.application.config.after_initialize do
RubyVM::YJIT.enable
end
end

View file

@ -6,5 +6,5 @@
# Use this to limit dissemination of sensitive information.
# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
Rails.application.config.filter_parameters += [
:passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
:passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :cvv, :cvc
]

View file

@ -1,7 +1,12 @@
# frozen_string_literal: true
HttpLog.configure do |config|
config.logger = Rails.logger
config.color = { color: :yellow }
config.compact_log = true
# Disable httplog in production unless log_level is `debug`
if !Rails.env.production? || Rails.configuration.log_level == :debug
require 'httplog'
HttpLog.configure do |config|
config.logger = Rails.logger
config.color = { color: :yellow }
config.compact_log = true
end
end

View file

@ -54,6 +54,9 @@ if ENV.keys.any? { |name| name.match?(/OTEL_.*_ENDPOINT/) }
'OpenTelemetry::Instrumentation::Sidekiq' => {
span_naming: :job_class, # Use the job class as the span name, otherwise this is the queue name and not very helpful
},
'OpenTelemetry::Instrumentation::Redis' => {
trace_root_spans: false, # don't start traces with Redis spans
},
})
prefix = ENV.fetch('OTEL_SERVICE_NAME_PREFIX', 'mastodon')
@ -65,7 +68,39 @@ if ENV.keys.any? { |name| name.match?(/OTEL_.*_ENDPOINT/) }
"#{prefix}#{separator}#{$PROGRAM_NAME.split('/').last}"
end
c.service_version = Mastodon::Version.to_s
if Mastodon::Version.source_commit.present?
c.resource = OpenTelemetry::SDK::Resources::Resource.create(
'vcs.repository.ref.revision' => Mastodon::Version.source_commit,
'vcs.repository.url.full' => Mastodon::Version.source_base_url
)
end
end
# This middleware adds the trace_id and span_id to the Rails logging tags for every requests
class TelemetryLoggingMiddleware
def initialize(app)
@app = app
end
def call(env)
span = OpenTelemetry::Trace.current_span
return @app.call(env) unless span.recording?
span_id = span.context.hex_span_id
trace_id = span.context.hex_trace_id
Rails.logger.tagged("trace_id=#{trace_id}", "span_id=#{span_id}") do
@app.call(env)
end
end
end
Rails.application.configure do
config.middleware.insert_before Rails::Rack::Logger, TelemetryLoggingMiddleware
end
end
MastodonOTELTracer = OpenTelemetry.tracer_provider.tracer('mastodon')

View file

@ -0,0 +1,25 @@
# frozen_string_literal: true
if ENV['MASTODON_PROMETHEUS_EXPORTER_ENABLED'] == 'true'
if ENV['MASTODON_PROMETHEUS_EXPORTER_LOCAL'] == 'true'
require 'prometheus_exporter'
require 'prometheus_exporter/server'
require 'prometheus_exporter/client'
# bind is the address, on which the webserver will listen
# port is the port that will provide the /metrics route
server = PrometheusExporter::Server::WebServer.new bind: ENV.fetch('MASTODON_PROMETHEUS_EXPORTER_HOST', 'localhost'), port: ENV.fetch('MASTODON_PROMETHEUS_EXPORTER_PORT', '9394').to_i
server.start
# wire up a default local client
PrometheusExporter::Client.default = PrometheusExporter::LocalClient.new(collector: server.collector)
end
if ENV['MASTODON_PROMETHEUS_EXPORTER_WEB_DETAILED_METRICS'] == 'true'
# Optional, as those metrics might generate extra overhead and be redundant with what OTEL provides
require 'prometheus_exporter/middleware'
# Per-action/controller request stats like HTTP status and timings
Rails.application.middleware.unshift PrometheusExporter::Middleware
end
end

View file

@ -122,7 +122,7 @@ class Rack::Attack
end
throttle('throttle_email_confirmations/ip', limit: 25, period: 5.minutes) do |req|
req.throttleable_remote_ip if req.post? && (req.path_matches?('/auth/confirmation') || req.path == '/api/v1/emails/confirmations')
req.throttleable_remote_ip if (req.post? && (req.path_matches?('/auth/confirmation') || req.path == '/api/v1/emails/confirmations')) || ((req.put? || req.patch?) && req.path_matches?('/auth/setup'))
end
throttle('throttle_email_confirmations/email', limit: 5, period: 30.minutes) do |req|
@ -133,6 +133,14 @@ class Rack::Attack
end
end
throttle('throttle_auth_setup/email', limit: 5, period: 10.minutes) do |req|
req.params.dig('user', 'email').presence if (req.put? || req.patch?) && req.path_matches?('/auth/setup')
end
throttle('throttle_auth_setup/account', limit: 5, period: 10.minutes) do |req|
req.warden_user_id if (req.put? || req.patch?) && req.path_matches?('/auth/setup')
end
throttle('throttle_login_attempts/ip', limit: 25, period: 5.minutes) do |req|
req.throttleable_remote_ip if req.post? && req.path_matches?('/auth/sign_in')
end

View file

@ -0,0 +1,18 @@
# frozen_string_literal: true
Rails.application.config.to_prepare do
custom_css = begin
Setting.custom_css
rescue ActiveRecord::AdapterError # Running without a database, not migrated, no connection, etc
nil
end
if custom_css.present?
Rails
.cache
.write(
:setting_digest_custom_css,
Digest::SHA256.hexdigest(custom_css)
)
end
end

View file

@ -22,6 +22,48 @@ Sidekiq.configure_server do |config|
end
end
if ENV['MASTODON_PROMETHEUS_EXPORTER_ENABLED'] == 'true'
require 'prometheus_exporter'
require 'prometheus_exporter/instrumentation'
config.on :startup do
# Ruby process metrics (memory, GC, etc)
PrometheusExporter::Instrumentation::Process.start type: 'sidekiq'
# Sidekiq process metrics (concurrency, busy, etc)
PrometheusExporter::Instrumentation::SidekiqProcess.start
# ActiveRecord metrics (connection pool usage)
PrometheusExporter::Instrumentation::ActiveRecord.start(
custom_labels: { type: 'sidekiq' },
config_labels: [:database, :host]
)
if ENV['MASTODON_PROMETHEUS_EXPORTER_SIDEKIQ_DETAILED_METRICS'] == 'true'
# Optional, as those metrics might generate extra overhead and be redundant with what OTEL provides
# Per-job metrics
config.server_middleware do |chain|
chain.add PrometheusExporter::Instrumentation::Sidekiq
end
config.death_handlers << PrometheusExporter::Instrumentation::Sidekiq.death_handler
# Per-queue metrics for queues handled by this process (size, latency, etc)
# They will be reported by every process handling those queues, so do not sum them up
PrometheusExporter::Instrumentation::SidekiqQueue.start
# Global Sidekiq metrics (size of the global queues, number of jobs, etc)
# Will be the same for every Sidekiq process
PrometheusExporter::Instrumentation::SidekiqStats.start
end
end
at_exit do
# Wait for the latest metrics to be reported before shutting down
PrometheusExporter::Client.default.stop(wait_timeout_seconds: 10)
end
end
config.server_middleware do |chain|
chain.add Mastodon::SidekiqMiddleware
end

View file

@ -0,0 +1,15 @@
# frozen_string_literal: true
return unless defined?(Rails::Command::StatsCommand)
[
%w(AppLibs app/lib),
%w(Policies app/policies),
%w(Presenters app/presenters),
%w(Serializers app/serializers),
%w(Services app/services),
%w(Validators app/validators),
%w(Workers app/workers),
].each do |name, directory|
Rails::CodeStatistics.register_directory(name.titleize, directory)
end

View file

@ -3,7 +3,7 @@
WebAuthn.configure do |config|
# This value needs to match `window.location.origin` evaluated by
# the User Agent during registration and authentication ceremonies.
config.origin = "#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}"
config.allowed_origins = ["#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}"]
# Relying Party name for display purposes
config.rp_name = 'Mastodon'