Merge tag 'v4.3.0-rc.1'
This commit is contained in:
commit
26c9b9ba39
3459 changed files with 130932 additions and 69993 deletions
|
@ -5,16 +5,15 @@ require_relative 'boot'
|
|||
require 'rails'
|
||||
|
||||
require 'active_record/railtie'
|
||||
#require 'active_storage/engine'
|
||||
# require 'active_storage/engine'
|
||||
require 'action_controller/railtie'
|
||||
require 'action_view/railtie'
|
||||
require 'action_mailer/railtie'
|
||||
require 'active_job/railtie'
|
||||
#require 'action_cable/engine'
|
||||
#require 'action_mailbox/engine'
|
||||
#require 'action_text/engine'
|
||||
#require 'rails/test_unit/railtie'
|
||||
require 'sprockets/railtie'
|
||||
# require 'action_cable/engine'
|
||||
# require 'action_mailbox/engine'
|
||||
# require 'action_text/engine'
|
||||
# require 'rails/test_unit/railtie'
|
||||
|
||||
# Used to be implicitly required in action_mailbox/engine
|
||||
require 'mail'
|
||||
|
@ -28,7 +27,7 @@ require_relative '../lib/sanitize_ext/sanitize_config'
|
|||
require_relative '../lib/redis/namespace_extensions'
|
||||
require_relative '../lib/paperclip/url_generator_extensions'
|
||||
require_relative '../lib/paperclip/attachment_extensions'
|
||||
require_relative '../lib/paperclip/lazy_thumbnail'
|
||||
|
||||
require_relative '../lib/paperclip/gif_transcoder'
|
||||
require_relative '../lib/paperclip/media_type_spoof_detector_extensions'
|
||||
require_relative '../lib/paperclip/transcoder'
|
||||
|
@ -39,8 +38,9 @@ require_relative '../lib/mastodon/snowflake'
|
|||
require_relative '../lib/mastodon/version'
|
||||
require_relative '../lib/mastodon/rack_middleware'
|
||||
require_relative '../lib/public_file_server_middleware'
|
||||
require_relative '../lib/devise/two_factor_ldap_authenticatable'
|
||||
require_relative '../lib/devise/two_factor_pam_authenticatable'
|
||||
require_relative '../lib/devise/strategies/two_factor_ldap_authenticatable'
|
||||
require_relative '../lib/devise/strategies/two_factor_pam_authenticatable'
|
||||
require_relative '../lib/elasticsearch/client_extensions'
|
||||
require_relative '../lib/chewy/settings_extensions'
|
||||
require_relative '../lib/chewy/index_extensions'
|
||||
require_relative '../lib/chewy/strategy/mastodon'
|
||||
|
@ -49,147 +49,37 @@ require_relative '../lib/webpacker/manifest_extensions'
|
|||
require_relative '../lib/webpacker/helper_extensions'
|
||||
require_relative '../lib/rails/engine_extensions'
|
||||
require_relative '../lib/action_dispatch/remote_ip_extensions'
|
||||
require_relative '../lib/stoplight/redis_data_store_extensions'
|
||||
require_relative '../lib/active_record/database_tasks_extensions'
|
||||
require_relative '../lib/active_record/batches'
|
||||
require_relative '../lib/active_record/with_recursive'
|
||||
require_relative '../lib/arel/union_parenthesizing'
|
||||
require_relative '../lib/simple_navigation/item_extensions'
|
||||
require_relative '../lib/http_extensions'
|
||||
|
||||
Dotenv::Railtie.load
|
||||
|
||||
Bundler.require(:pam_authentication) if ENV['PAM_ENABLED'] == 'true'
|
||||
|
||||
require_relative '../lib/mastodon/redis_config'
|
||||
|
||||
module Mastodon
|
||||
class Application < Rails::Application
|
||||
# Initialize configuration defaults for originally generated Rails version.
|
||||
config.load_defaults 7.0
|
||||
config.load_defaults 7.1
|
||||
|
||||
# TODO: Release a version which uses the 7.0 defaults as specified above,
|
||||
# but preserves the 6.1 cache format as set below. In a subsequent change,
|
||||
# remove this line setting to 6.1 cache format, and then release another version.
|
||||
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#new-activesupport-cache-serialization-format
|
||||
# https://github.com/mastodon/mastodon/pull/24241#discussion_r1162890242
|
||||
config.active_support.cache_format_version = 6.1
|
||||
# Explicitly set the cache format version to align with Rails version
|
||||
config.active_support.cache_format_version = 7.1
|
||||
|
||||
config.add_autoload_paths_to_load_path = false
|
||||
# Please, add to the `ignore` list any other `lib` subdirectories that do
|
||||
# not contain `.rb` files, or that should not be reloaded or eager loaded.
|
||||
# Common ones are `templates`, `generators`, or `middleware`, for example.
|
||||
# config.autoload_lib(ignore: %w(assets tasks templates generators))
|
||||
# TODO: We should enable this eventually, but for now there are many things
|
||||
# in the wrong path from the perspective of zeitwerk.
|
||||
|
||||
# Settings in config/environments/* take precedence over those specified here.
|
||||
# Application configuration should go into files in config/initializers
|
||||
# -- all .rb files in that directory are automatically loaded.
|
||||
|
||||
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
||||
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
||||
# config.time_zone = 'Central Time (US & Canada)'
|
||||
|
||||
# All translations from config/locales/*.rb,yml are auto loaded.
|
||||
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
||||
config.i18n.available_locales = [
|
||||
:af,
|
||||
:an,
|
||||
:ar,
|
||||
:ast,
|
||||
:be,
|
||||
:bg,
|
||||
:bn,
|
||||
:br,
|
||||
:bs,
|
||||
:ca,
|
||||
:ckb,
|
||||
:co,
|
||||
:cs,
|
||||
:cy,
|
||||
:da,
|
||||
:de,
|
||||
:el,
|
||||
:en,
|
||||
:'en-GB',
|
||||
:eo,
|
||||
:es,
|
||||
:'es-AR',
|
||||
:'es-MX',
|
||||
:et,
|
||||
:eu,
|
||||
:fa,
|
||||
:fi,
|
||||
:fo,
|
||||
:fr,
|
||||
:'fr-QC',
|
||||
:fy,
|
||||
:ga,
|
||||
:gd,
|
||||
:gl,
|
||||
:he,
|
||||
:hi,
|
||||
:hr,
|
||||
:hu,
|
||||
:hy,
|
||||
:id,
|
||||
:ig,
|
||||
:io,
|
||||
:is,
|
||||
:it,
|
||||
:ja,
|
||||
:ka,
|
||||
:kab,
|
||||
:kk,
|
||||
:kn,
|
||||
:ko,
|
||||
:ku,
|
||||
:kw,
|
||||
:la,
|
||||
:lt,
|
||||
:lv,
|
||||
:mk,
|
||||
:ml,
|
||||
:mr,
|
||||
:ms,
|
||||
:my,
|
||||
:nl,
|
||||
:nn,
|
||||
:no,
|
||||
:oc,
|
||||
:pa,
|
||||
:pl,
|
||||
:'pt-BR',
|
||||
:'pt-PT',
|
||||
:ro,
|
||||
:ru,
|
||||
:sa,
|
||||
:sc,
|
||||
:sco,
|
||||
:si,
|
||||
:sk,
|
||||
:sl,
|
||||
:sq,
|
||||
:sr,
|
||||
:'sr-Latn',
|
||||
:sv,
|
||||
:szl,
|
||||
:ta,
|
||||
:te,
|
||||
:th,
|
||||
:tr,
|
||||
:tt,
|
||||
:ug,
|
||||
:uk,
|
||||
:ur,
|
||||
:vi,
|
||||
:zgh,
|
||||
:'zh-CN',
|
||||
:'zh-HK',
|
||||
:'zh-TW',
|
||||
]
|
||||
|
||||
config.i18n.default_locale = begin
|
||||
custom_default_locale = ENV['DEFAULT_LOCALE']&.to_sym
|
||||
|
||||
if config.i18n.available_locales.include?(custom_default_locale)
|
||||
custom_default_locale
|
||||
else
|
||||
:en
|
||||
end
|
||||
end
|
||||
# Configuration for the application, engines, and railties goes here.
|
||||
#
|
||||
# These settings can be overridden in specific environments using the files
|
||||
# in config/environments, which are processed later.
|
||||
#
|
||||
# config.time_zone = "Central Time (US & Canada)"
|
||||
# config.eager_load_paths << Rails.root.join("extras")
|
||||
|
||||
config.public_file_server.headers = {
|
||||
'X-Content-Type-Options' => 'nosniff',
|
||||
|
@ -201,20 +91,39 @@ module Mastodon
|
|||
config.active_job.queue_adapter = :sidekiq
|
||||
|
||||
config.action_mailer.deliver_later_queue_name = 'mailers'
|
||||
config.action_mailer.preview_path = Rails.root.join('spec', 'mailers', 'previews')
|
||||
config.action_mailer.preview_paths << Rails.root.join('spec', 'mailers', 'previews')
|
||||
|
||||
# We use our own middleware for this
|
||||
config.public_file_server.enabled = false
|
||||
|
||||
config.middleware.use PublicFileServerMiddleware if Rails.env.development? || Rails.env.test? || ENV['RAILS_SERVE_STATIC_FILES'] == 'true'
|
||||
config.middleware.use PublicFileServerMiddleware if Rails.env.local? || ENV['RAILS_SERVE_STATIC_FILES'] == 'true'
|
||||
config.middleware.use Rack::Attack
|
||||
config.middleware.use Mastodon::RackMiddleware
|
||||
|
||||
initializer :deprecator do |app|
|
||||
app.deprecators[:mastodon] = ActiveSupport::Deprecation.new('4.3', 'mastodon/mastodon')
|
||||
end
|
||||
|
||||
config.before_configuration do
|
||||
require 'mastodon/redis_configuration'
|
||||
::REDIS_CONFIGURATION = Mastodon::RedisConfiguration.new
|
||||
|
||||
config.x.use_vips = ENV['MASTODON_USE_LIBVIPS'] == 'true'
|
||||
|
||||
if config.x.use_vips
|
||||
require_relative '../lib/paperclip/vips_lazy_thumbnail'
|
||||
else
|
||||
require_relative '../lib/paperclip/lazy_thumbnail'
|
||||
end
|
||||
end
|
||||
|
||||
config.to_prepare do
|
||||
Doorkeeper::AuthorizationsController.layout 'modal'
|
||||
Doorkeeper::AuthorizedApplicationsController.layout 'admin'
|
||||
Doorkeeper::Application.include ApplicationExtension
|
||||
Doorkeeper::AccessGrant.include AccessGrantExtension
|
||||
Doorkeeper::AccessToken.include AccessTokenExtension
|
||||
Doorkeeper::OAuth::PreAuthorization.include OauthPreAuthorizationExtension
|
||||
Devise::FailureApp.include AbstractController::Callbacks
|
||||
Devise::FailureApp.include Localized
|
||||
end
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
unless ENV.key?('RAILS_ENV')
|
||||
STDERR.puts 'ERROR: Missing RAILS_ENV environment variable, please set it to "production", "development", or "test".'
|
||||
exit 1
|
||||
abort <<~ERROR
|
||||
The RAILS_ENV environment variable is not set.
|
||||
|
||||
Please set it correctly depending on context:
|
||||
|
||||
- Use "production" for a live deployment of the application
|
||||
- Use "development" for local feature work
|
||||
- Use "test" when running the automated spec suite
|
||||
ERROR
|
||||
end
|
||||
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
{
|
||||
"ignored_warnings": [
|
||||
{
|
||||
"warning_type": "Cross-Site Scripting",
|
||||
"warning_code": 2,
|
||||
"fingerprint": "71cf98c8235b5cfa9946b5db8fdc1a2f3a862566abb34e4542be6f3acae78233",
|
||||
"check_name": "CrossSiteScripting",
|
||||
"message": "Unescaped model attribute",
|
||||
"file": "app/views/admin/disputes/appeals/_appeal.html.haml",
|
||||
"line": 7,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/cross_site_scripting",
|
||||
"code": "t((Unresolved Model).new.strike.action, :scope => \"admin.strikes.actions\", :name => content_tag(:span, (Unresolved Model).new.strike.account.username, :class => \"username\"), :target => content_tag(:span, (Unresolved Model).new.account.username, :class => \"target\"))",
|
||||
"render_path": [
|
||||
{
|
||||
"type": "template",
|
||||
"name": "admin/disputes/appeals/index",
|
||||
"line": 20,
|
||||
"file": "app/views/admin/disputes/appeals/index.html.haml",
|
||||
"rendered": {
|
||||
"name": "admin/disputes/appeals/_appeal",
|
||||
"file": "app/views/admin/disputes/appeals/_appeal.html.haml"
|
||||
}
|
||||
}
|
||||
],
|
||||
"location": {
|
||||
"type": "template",
|
||||
"template": "admin/disputes/appeals/_appeal"
|
||||
},
|
||||
"user_input": "(Unresolved Model).new.strike",
|
||||
"confidence": "Weak",
|
||||
"cwe_id": [
|
||||
79
|
||||
],
|
||||
"note": ""
|
||||
},
|
||||
{
|
||||
"warning_type": "Denial of Service",
|
||||
"warning_code": 76,
|
||||
"fingerprint": "7b6abba5699755348e7ee82a4694bfbf574b41c7cce2d0db0f7c11ae3f983c72",
|
||||
"check_name": "RegexDoS",
|
||||
"message": "Model attribute used in regular expression",
|
||||
"file": "lib/mastodon/cli/domains.rb",
|
||||
"line": 128,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/denial_of_service/",
|
||||
"code": "/\\.?(#{DomainBlock.where(:severity => 1).pluck(:domain).map do\n Regexp.escape(domain)\n end.join(\"|\")})$/",
|
||||
"render_path": null,
|
||||
"location": {
|
||||
"type": "method",
|
||||
"class": "Mastodon::CLI::Domains",
|
||||
"method": "crawl"
|
||||
},
|
||||
"user_input": "DomainBlock.where(:severity => 1).pluck(:domain)",
|
||||
"confidence": "Weak",
|
||||
"cwe_id": [
|
||||
20,
|
||||
185
|
||||
],
|
||||
"note": ""
|
||||
},
|
||||
{
|
||||
"warning_type": "Cross-Site Scripting",
|
||||
"warning_code": 4,
|
||||
"fingerprint": "cd5cfd7f40037fbfa753e494d7129df16e358bfc43ef0da3febafbf4ee1ed3ac",
|
||||
"check_name": "LinkToHref",
|
||||
"message": "Potentially unsafe model attribute in `link_to` href",
|
||||
"file": "app/views/admin/trends/links/_preview_card.html.haml",
|
||||
"line": 7,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
|
||||
"code": "link_to((Unresolved Model).new.title, (Unresolved Model).new.url)",
|
||||
"render_path": [
|
||||
{
|
||||
"type": "template",
|
||||
"name": "admin/trends/links/index",
|
||||
"line": 49,
|
||||
"file": "app/views/admin/trends/links/index.html.haml",
|
||||
"rendered": {
|
||||
"name": "admin/trends/links/_preview_card",
|
||||
"file": "app/views/admin/trends/links/_preview_card.html.haml"
|
||||
}
|
||||
}
|
||||
],
|
||||
"location": {
|
||||
"type": "template",
|
||||
"template": "admin/trends/links/_preview_card"
|
||||
},
|
||||
"user_input": "(Unresolved Model).new.url",
|
||||
"confidence": "Weak",
|
||||
"cwe_id": [
|
||||
79
|
||||
],
|
||||
"note": ""
|
||||
}
|
||||
],
|
||||
"updated": "2023-07-12 11:20:51 -0400",
|
||||
"brakeman_version": "6.0.0"
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
---
|
||||
:skip_checks:
|
||||
- CheckPermitAttributes
|
||||
:url_safe_methods:
|
||||
- url_for_preview_card
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
default: &default
|
||||
adapter: postgresql
|
||||
pool: <%= ENV["DB_POOL"] || ENV['MAX_THREADS'] || 5 %>
|
||||
pool: <%= ENV["DB_POOL"] || (if Sidekiq.server? then Sidekiq[:concurrency] else ENV['MAX_THREADS'] end) || 5 %>
|
||||
timeout: 5000
|
||||
connect_timeout: 15
|
||||
encoding: unicode
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
lock '3.17.2'
|
||||
|
||||
set :repo_url, ENV.fetch('REPO', 'https://github.com/mastodon/mastodon.git')
|
||||
set :branch, ENV.fetch('BRANCH', 'main')
|
||||
|
||||
set :application, 'mastodon'
|
||||
set :rbenv_type, :user
|
||||
set :rbenv_ruby, File.read('.ruby-version').strip
|
||||
set :migration_role, :app
|
||||
|
||||
append :linked_files, '.env.production', 'public/robots.txt'
|
||||
append :linked_dirs, 'vendor/bundle', 'node_modules', 'public/system'
|
||||
|
||||
SYSTEMD_SERVICES = %i[sidekiq streaming web].freeze
|
||||
SERVICE_ACTIONS = %i[reload restart status].freeze
|
||||
|
||||
namespace :systemd do
|
||||
SYSTEMD_SERVICES.each do |service|
|
||||
SERVICE_ACTIONS.each do |action|
|
||||
desc "Perform a #{action} on #{service} service"
|
||||
task "#{service}:#{action}".to_sym do
|
||||
on roles(:app) do
|
||||
# runs e.g. "sudo restart mastodon-sidekiq.service"
|
||||
sudo :systemctl, action, "#{fetch(:application)}-#{service}.service"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
after 'deploy:publishing', 'systemd:web:reload'
|
||||
after 'deploy:publishing', 'systemd:sidekiq:restart'
|
||||
after 'deploy:publishing', 'systemd:streaming:restart'
|
|
@ -8,7 +8,7 @@ Rails.application.configure do
|
|||
# In the development environment your application's code is reloaded any time
|
||||
# it changes. This slows down response time but is perfect for development
|
||||
# since you don't have to restart the web server when you make code changes.
|
||||
config.cache_classes = false
|
||||
config.enable_reloading = true
|
||||
|
||||
# Do not eager load code on boot.
|
||||
config.eager_load = false
|
||||
|
@ -25,7 +25,7 @@ Rails.application.configure do
|
|||
config.action_controller.perform_caching = true
|
||||
config.action_controller.enable_fragment_cache_logging = true
|
||||
|
||||
config.cache_store = :redis_cache_store, REDIS_CACHE_PARAMS
|
||||
config.cache_store = :redis_cache_store, REDIS_CONFIGURATION.cache
|
||||
config.public_file_server.headers = {
|
||||
'Cache-Control' => "public, max-age=#{2.days.to_i}",
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ Rails.application.configure do
|
|||
|
||||
config.action_controller.forgery_protection_origin_check = ENV['DISABLE_FORGERY_REQUEST_PROTECTION'].nil?
|
||||
|
||||
ActiveSupport::Logger.new(STDOUT).tap do |logger|
|
||||
ActiveSupport::Logger.new($stdout).tap do |logger|
|
||||
logger.formatter = config.log_formatter
|
||||
config.logger = ActiveSupport::TaggedLogging.new(logger)
|
||||
end
|
||||
|
@ -68,16 +68,8 @@ Rails.application.configure do
|
|||
# Highlight code that triggered database queries in logs.
|
||||
config.active_record.verbose_query_logs = true
|
||||
|
||||
# Debug mode disables concatenation and preprocessing of assets.
|
||||
config.assets.debug = true
|
||||
|
||||
# Suppress logger output for asset requests.
|
||||
config.assets.quiet = true
|
||||
|
||||
# Adds additional error checking when serving assets at runtime.
|
||||
# Checks for improperly declared sprockets dependencies.
|
||||
# Raises helpful error messages.
|
||||
config.assets.raise_runtime_errors = true
|
||||
# Highlight code that enqueued background job in logs.
|
||||
config.active_job.verbose_enqueue_logs = true
|
||||
|
||||
# Raises error for missing translations.
|
||||
# config.i18n.raise_on_missing_translations = true
|
||||
|
@ -93,11 +85,13 @@ Rails.application.configure do
|
|||
# If using a Heroku, Vagrant or generic remote development environment,
|
||||
# use letter_opener_web, accessible at /letter_opener.
|
||||
# Otherwise, use letter_opener, which launches a browser window to view sent mail.
|
||||
config.action_mailer.delivery_method = (ENV['HEROKU'] || ENV['VAGRANT'] || ENV['REMOTE_DEV']) ? :letter_opener_web : :letter_opener
|
||||
config.action_mailer.delivery_method = ENV['HEROKU'] || ENV['VAGRANT'] || ENV['REMOTE_DEV'] ? :letter_opener_web : :letter_opener
|
||||
|
||||
# We provide a default secret for the development environment here.
|
||||
# This value should not be used in production environments!
|
||||
# TODO: Remove once devise-two-factor data migration complete
|
||||
config.x.otp_secret = ENV.fetch('OTP_SECRET', '1fc2b87989afa6351912abeebe31ffc5c476ead9bf8b3d74cbc4a302c7b69a45b40b1bbef3506ddad73e942e15ed5ca4b402bf9a66423626051104f4b5f05109')
|
||||
|
||||
# Raise error when a before_action's only/except options reference missing actions
|
||||
config.action_controller.raise_on_missing_callback_actions = true
|
||||
end
|
||||
|
||||
Redis.raise_deprecations = true
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "active_support/core_ext/integer/time"
|
||||
require 'active_support/core_ext/integer/time'
|
||||
|
||||
Rails.application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb.
|
||||
|
||||
# Code is not reloaded between requests.
|
||||
config.cache_classes = true
|
||||
config.enable_reloading = false
|
||||
|
||||
# Eager load code on boot. This eager loads most of Rails and
|
||||
# your application in memory, allowing both threaded web servers
|
||||
|
@ -19,8 +19,8 @@ Rails.application.configure do
|
|||
config.action_controller.perform_caching = true
|
||||
config.action_controller.asset_host = ENV['CDN_HOST'] if ENV['CDN_HOST'].present?
|
||||
|
||||
# Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
|
||||
# or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
|
||||
# Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment
|
||||
# key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files).
|
||||
# config.require_master_key = true
|
||||
|
||||
# Compress CSS using a preprocessor.
|
||||
|
@ -44,21 +44,20 @@ Rails.application.configure do
|
|||
config.force_ssl = true
|
||||
config.ssl_options = {
|
||||
redirect: {
|
||||
exclude: -> request { request.path.start_with?('/health') || request.headers["Host"].end_with?('.onion') || request.headers["Host"].end_with?('.i2p') }
|
||||
}
|
||||
exclude: ->(request) { request.path.start_with?('/health') || request.headers['Host'].end_with?('.onion') || request.headers['Host'].end_with?('.i2p') },
|
||||
},
|
||||
}
|
||||
|
||||
# Include generic and useful information about system operation, but avoid logging too much
|
||||
# information to avoid inadvertent exposure of personally identifiable information (PII).
|
||||
# Use the lowest log level to ensure availability of diagnostic information
|
||||
# when problems arise.
|
||||
# Info include generic and useful information about system operation, but avoids logging too much
|
||||
# information to avoid inadvertent exposure of personally identifiable information (PII). If you
|
||||
# want to log everything, set the level to "debug".
|
||||
config.log_level = ENV.fetch('RAILS_LOG_LEVEL', 'info').to_sym
|
||||
|
||||
# Prepend all log lines with the following tags.
|
||||
config.log_tags = [:request_id]
|
||||
|
||||
# Use a different cache store in production.
|
||||
config.cache_store = :redis_cache_store, REDIS_CACHE_PARAMS
|
||||
config.cache_store = :redis_cache_store, REDIS_CONFIGURATION.cache
|
||||
|
||||
# Use a real queuing backend for Active Job (and separate queues per environment).
|
||||
# config.active_job.queue_adapter = :resque
|
||||
|
@ -72,10 +71,13 @@ Rails.application.configure do
|
|||
|
||||
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
|
||||
# English when a translation cannot be found).
|
||||
config.i18n.fallbacks = true
|
||||
# This setting would typically be `true` to use the `I18n.default_locale`.
|
||||
# Some locales are missing translation entries and would have errors:
|
||||
# https://github.com/mastodon/mastodon/pull/24727
|
||||
config.i18n.fallbacks = [:en]
|
||||
|
||||
# Send deprecation notices to registered listeners.
|
||||
config.active_support.deprecation = :notify
|
||||
# Don't log any deprecations.
|
||||
config.active_support.report_deprecations = false
|
||||
|
||||
# Use default logging formatter so that PID and timestamp are not suppressed.
|
||||
config.log_formatter = ::Logger::Formatter.new
|
||||
|
@ -84,19 +86,17 @@ Rails.application.configure do
|
|||
config.lograge.enabled = true
|
||||
|
||||
config.lograge.custom_payload do |controller|
|
||||
if controller.respond_to?(:signed_request?) && controller.signed_request?
|
||||
{ key: controller.signature_key_id }
|
||||
end
|
||||
{ key: controller.signature_key_id } if controller.respond_to?(:signed_request?) && controller.signed_request?
|
||||
end
|
||||
|
||||
# Use a different logger for distributed setups.
|
||||
# require "syslog/logger"
|
||||
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new "app-name")
|
||||
|
||||
ActiveSupport::Logger.new(STDOUT).tap do |logger|
|
||||
logger.formatter = config.log_formatter
|
||||
config.logger = ActiveSupport::TaggedLogging.new(logger)
|
||||
end
|
||||
# Log to STDOUT by default
|
||||
config.logger = ActiveSupport::Logger.new($stdout)
|
||||
.tap { |logger| logger.formatter = ::Logger::Formatter.new }
|
||||
.then { |logger| ActiveSupport::TaggedLogging.new(logger) }
|
||||
|
||||
# Do not dump schema after migrations.
|
||||
config.active_record.dump_schema_after_migration = false
|
||||
|
@ -148,12 +148,25 @@ Rails.application.configure do
|
|||
config.action_mailer.delivery_method = ENV.fetch('SMTP_DELIVERY_METHOD', 'smtp').to_sym
|
||||
|
||||
config.action_dispatch.default_headers = {
|
||||
'Server' => 'Mastodon',
|
||||
'X-Frame-Options' => 'DENY',
|
||||
'Server' => 'Mastodon',
|
||||
'X-Frame-Options' => 'DENY',
|
||||
'X-Content-Type-Options' => 'nosniff',
|
||||
'X-XSS-Protection' => '0',
|
||||
'Referrer-Policy' => 'same-origin',
|
||||
'X-XSS-Protection' => '0',
|
||||
'Referrer-Policy' => 'same-origin',
|
||||
}
|
||||
|
||||
config.x.otp_secret = ENV.fetch('OTP_SECRET')
|
||||
# TODO: Remove once devise-two-factor data migration complete
|
||||
config.x.otp_secret = if ENV['SECRET_KEY_BASE_DUMMY']
|
||||
SecureRandom.hex(64)
|
||||
else
|
||||
ENV.fetch('OTP_SECRET')
|
||||
end
|
||||
|
||||
# Enable DNS rebinding protection and other `Host` header attacks.
|
||||
# config.hosts = [
|
||||
# "example.com", # Allow requests from example.com
|
||||
# /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
|
||||
# ]
|
||||
# Skip DNS rebinding protection for the default health check endpoint.
|
||||
# config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
|
||||
end
|
||||
|
|
|
@ -10,12 +10,13 @@ require 'active_support/core_ext/integer/time'
|
|||
Rails.application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb.
|
||||
|
||||
# Turn false under Spring and add config.action_view.cache_template_loading = true.
|
||||
config.cache_classes = true
|
||||
# While tests run files are not watched, reloading is not necessary.
|
||||
config.enable_reloading = false
|
||||
|
||||
# Eager loading loads your whole application. When running a single test locally,
|
||||
# this probably isn't necessary. It's a good idea to do in a continuous integration
|
||||
# system, or in some way before deploying your code.
|
||||
# Eager loading loads your entire application. When running a single test locally,
|
||||
# this is usually not necessary, and can slow down your test suite. However, it's
|
||||
# recommended that you enable it in continuous integration systems to ensure eager
|
||||
# loading is working properly before deploying your code.
|
||||
config.eager_load = ENV['CI'].present?
|
||||
|
||||
config.assets_digest = false
|
||||
|
@ -26,7 +27,7 @@ Rails.application.configure do
|
|||
config.cache_store = :memory_store
|
||||
|
||||
# Raise exceptions instead of rendering exception templates.
|
||||
config.action_dispatch.show_exceptions = false
|
||||
config.action_dispatch.show_exceptions = :rescuable
|
||||
|
||||
# Disable request forgery protection in test environment.
|
||||
config.action_controller.allow_forgery_protection = false
|
||||
|
@ -43,6 +44,7 @@ Rails.application.configure do
|
|||
# Print deprecation notices to the stderr.
|
||||
config.active_support.deprecation = :stderr
|
||||
|
||||
# TODO: Remove once devise-two-factor data migration complete
|
||||
config.x.otp_secret = '100c7faeef00caa29242f6b04156742bf76065771fd4117990c4282b8748ff3d99f8fdae97c982ab5bd2e6756a159121377cce4421f4a8ecd2d67bd7749a3fb4'
|
||||
|
||||
# Generate random VAPID keys
|
||||
|
@ -59,12 +61,6 @@ Rails.application.configure do
|
|||
config.i18n.default_locale = :en
|
||||
config.i18n.fallbacks = true
|
||||
|
||||
config.to_prepare do
|
||||
# Force Status to always be SHAPE_TOO_COMPLEX
|
||||
# Ref: https://github.com/mastodon/mastodon/issues/23644
|
||||
10.times { |i| Status.allocate.instance_variable_set(:"@ivar_#{i}", nil) }
|
||||
end
|
||||
|
||||
# Tell Active Support which deprecation messages to disallow.
|
||||
config.active_support.disallowed_deprecation_warnings = []
|
||||
|
||||
|
@ -73,18 +69,21 @@ Rails.application.configure do
|
|||
|
||||
# Annotate rendered view with file names.
|
||||
# config.action_view.annotate_rendered_view_with_filenames = true
|
||||
|
||||
# Raise error when a before_action's only/except options reference missing actions
|
||||
config.action_controller.raise_on_missing_callback_actions = true
|
||||
end
|
||||
|
||||
Paperclip::Attachment.default_options[:path] = Rails.root.join('spec', 'test_files', ':class', ':id_partition', ':style.:extension')
|
||||
|
||||
# set fake_data for pam, don't do real calls, just use fake data
|
||||
# Enable fake_data for PAM
|
||||
if ENV['PAM_ENABLED'] == 'true'
|
||||
Rpam2.fake_data =
|
||||
{
|
||||
usernames: Set['pam_user1', 'pam_user2'],
|
||||
servicenames: Set['pam_test', 'pam_test_controlled'],
|
||||
password: '123456',
|
||||
env: { email: 'pam@example.com' }
|
||||
env: { email: 'pam@example.com' },
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -64,11 +64,13 @@ ignore_unused:
|
|||
- 'statuses.attached.*'
|
||||
- 'move_handler.carry_{mutes,blocks}_over_text'
|
||||
- 'admin_mailer.*.subject'
|
||||
- 'user_mailer.*.subject'
|
||||
- 'notification_mailer.*'
|
||||
- 'imports.overwrite_preambles.{following,blocking,muting,domain_blocking,bookmarks,lists}_html'
|
||||
- 'imports.preambles.{following,blocking,muting,domain_blocking,bookmarks,lists}_html'
|
||||
- 'mail_subscriptions.unsubscribe.emails.*'
|
||||
- 'preferences.other' # some locales are missing other keys, therefore leading i18n-tasks to detect `preferences` as plural and not finding use
|
||||
- 'edit_profile.other' # some locales are missing other keys, therefore leading i18n-tasks to detect `preferences` as plural and not finding use
|
||||
|
||||
ignore_inconsistent_interpolations:
|
||||
- '*.one'
|
||||
|
|
|
@ -23,7 +23,7 @@ Rails.application.configure do
|
|||
if Rails.env.production?
|
||||
"ws#{https ? 's' : ''}://#{web_host}"
|
||||
else
|
||||
"ws://#{ENV['REMOTE_DEV'] == 'true' ? host.split(':').first : 'localhost'}:4000"
|
||||
"ws://#{host.split(':').first}:4000"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -9,9 +9,6 @@ Rails.application.config.middleware.use OmniAuth::Builder do
|
|||
end
|
||||
|
||||
Devise.setup do |config|
|
||||
# Devise omniauth strategies
|
||||
options = {}
|
||||
|
||||
# CAS strategy
|
||||
if ENV['CAS_ENABLED'] == 'true'
|
||||
cas_options = {}
|
||||
|
@ -76,35 +73,36 @@ Devise.setup do |config|
|
|||
# OpenID Connect Strategy
|
||||
if ENV['OIDC_ENABLED'] == 'true'
|
||||
oidc_options = {}
|
||||
oidc_options[:display_name] = ENV['OIDC_DISPLAY_NAME'] #OPTIONAL
|
||||
oidc_options[:issuer] = ENV['OIDC_ISSUER'] if ENV['OIDC_ISSUER'] #NEED
|
||||
oidc_options[:discovery] = ENV['OIDC_DISCOVERY'] == 'true' if ENV['OIDC_DISCOVERY'] #OPTIONAL (default: false)
|
||||
oidc_options[:client_auth_method] = ENV['OIDC_CLIENT_AUTH_METHOD'] if ENV['OIDC_CLIENT_AUTH_METHOD'] #OPTIONAL (default: basic)
|
||||
scope_string = ENV['OIDC_SCOPE'] if ENV['OIDC_SCOPE'] #NEED
|
||||
oidc_options[:display_name] = ENV['OIDC_DISPLAY_NAME'] # OPTIONAL
|
||||
oidc_options[:issuer] = ENV['OIDC_ISSUER'] if ENV['OIDC_ISSUER'] # NEED
|
||||
oidc_options[:discovery] = ENV['OIDC_DISCOVERY'] == 'true' if ENV['OIDC_DISCOVERY'] # OPTIONAL (default: false)
|
||||
oidc_options[:client_auth_method] = ENV['OIDC_CLIENT_AUTH_METHOD'] if ENV['OIDC_CLIENT_AUTH_METHOD'] # OPTIONAL (default: basic)
|
||||
scope_string = ENV['OIDC_SCOPE'] if ENV['OIDC_SCOPE'] # NEED
|
||||
scopes = scope_string.split(',')
|
||||
oidc_options[:scope] = scopes.map { |x| x.to_sym }
|
||||
oidc_options[:response_type] = ENV['OIDC_RESPONSE_TYPE'] if ENV['OIDC_RESPONSE_TYPE'] #OPTIONAL (default: code)
|
||||
oidc_options[:response_mode] = ENV['OIDC_RESPONSE_MODE'] if ENV['OIDC_RESPONSE_MODE'] #OPTIONAL (default: query)
|
||||
oidc_options[:display] = ENV['OIDC_DISPLAY'] if ENV['OIDC_DISPLAY'] #OPTIONAL (default: page)
|
||||
oidc_options[:prompt] = ENV['OIDC_PROMPT'] if ENV['OIDC_PROMPT'] #OPTIONAL
|
||||
oidc_options[:send_nonce] = ENV['OIDC_SEND_NONCE'] == 'true' if ENV['OIDC_SEND_NONCE'] #OPTIONAL (default: true)
|
||||
oidc_options[:send_scope_to_token_endpoint] = ENV['OIDC_SEND_SCOPE_TO_TOKEN_ENDPOINT'] == 'true' if ENV['OIDC_SEND_SCOPE_TO_TOKEN_ENDPOINT'] #OPTIONAL (default: true)
|
||||
oidc_options[:post_logout_redirect_uri] = ENV['OIDC_IDP_LOGOUT_REDIRECT_URI'] if ENV['OIDC_IDP_LOGOUT_REDIRECT_URI'] #OPTIONAL
|
||||
oidc_options[:uid_field] = ENV['OIDC_UID_FIELD'] if ENV['OIDC_UID_FIELD'] #NEED
|
||||
oidc_options[:scope] = scopes.map(&:to_sym)
|
||||
oidc_options[:response_type] = ENV['OIDC_RESPONSE_TYPE'] if ENV['OIDC_RESPONSE_TYPE'] # OPTIONAL (default: code)
|
||||
oidc_options[:response_mode] = ENV['OIDC_RESPONSE_MODE'] if ENV['OIDC_RESPONSE_MODE'] # OPTIONAL (default: query)
|
||||
oidc_options[:display] = ENV['OIDC_DISPLAY'] if ENV['OIDC_DISPLAY'] # OPTIONAL (default: page)
|
||||
oidc_options[:prompt] = ENV['OIDC_PROMPT'] if ENV['OIDC_PROMPT'] # OPTIONAL
|
||||
oidc_options[:pkce] = ENV['OIDC_USE_PKCE'] == 'true' if ENV['OIDC_USE_PKCE'] # OPTIONAL (default: false)
|
||||
oidc_options[:send_nonce] = ENV['OIDC_SEND_NONCE'] == 'true' if ENV['OIDC_SEND_NONCE'] # OPTIONAL (default: true)
|
||||
oidc_options[:send_scope_to_token_endpoint] = ENV['OIDC_SEND_SCOPE_TO_TOKEN_ENDPOINT'] == 'true' if ENV['OIDC_SEND_SCOPE_TO_TOKEN_ENDPOINT'] # OPTIONAL (default: true)
|
||||
oidc_options[:post_logout_redirect_uri] = ENV['OIDC_IDP_LOGOUT_REDIRECT_URI'] if ENV['OIDC_IDP_LOGOUT_REDIRECT_URI'] # OPTIONAL
|
||||
oidc_options[:uid_field] = ENV['OIDC_UID_FIELD'] if ENV['OIDC_UID_FIELD'] # NEED
|
||||
oidc_options[:client_options] = {}
|
||||
oidc_options[:client_options][:identifier] = ENV['OIDC_CLIENT_ID'] if ENV['OIDC_CLIENT_ID'] #NEED
|
||||
oidc_options[:client_options][:secret] = ENV['OIDC_CLIENT_SECRET'] if ENV['OIDC_CLIENT_SECRET'] #NEED
|
||||
oidc_options[:client_options][:redirect_uri] = ENV['OIDC_REDIRECT_URI'] if ENV['OIDC_REDIRECT_URI'] #NEED
|
||||
oidc_options[:client_options][:scheme] = ENV['OIDC_HTTP_SCHEME'] if ENV['OIDC_HTTP_SCHEME'] #OPTIONAL (default: https)
|
||||
oidc_options[:client_options][:host] = ENV['OIDC_HOST'] if ENV['OIDC_HOST'] #OPTIONAL
|
||||
oidc_options[:client_options][:port] = ENV['OIDC_PORT'] if ENV['OIDC_PORT'] #OPTIONAL
|
||||
oidc_options[:client_options][:authorization_endpoint] = ENV['OIDC_AUTH_ENDPOINT'] if ENV['OIDC_AUTH_ENDPOINT'] #NEED when discovery != true
|
||||
oidc_options[:client_options][:token_endpoint] = ENV['OIDC_TOKEN_ENDPOINT'] if ENV['OIDC_TOKEN_ENDPOINT'] #NEED when discovery != true
|
||||
oidc_options[:client_options][:userinfo_endpoint] = ENV['OIDC_USER_INFO_ENDPOINT'] if ENV['OIDC_USER_INFO_ENDPOINT'] #NEED when discovery != true
|
||||
oidc_options[:client_options][:jwks_uri] = ENV['OIDC_JWKS_URI'] if ENV['OIDC_JWKS_URI'] #NEED when discovery != true
|
||||
oidc_options[:client_options][:end_session_endpoint] = ENV['OIDC_END_SESSION_ENDPOINT'] if ENV['OIDC_END_SESSION_ENDPOINT'] #OPTIONAL
|
||||
oidc_options[:client_options][:identifier] = ENV['OIDC_CLIENT_ID'] if ENV['OIDC_CLIENT_ID'] # NEED
|
||||
oidc_options[:client_options][:secret] = ENV['OIDC_CLIENT_SECRET'] if ENV['OIDC_CLIENT_SECRET'] # NEED
|
||||
oidc_options[:client_options][:redirect_uri] = ENV['OIDC_REDIRECT_URI'] if ENV['OIDC_REDIRECT_URI'] # NEED
|
||||
oidc_options[:client_options][:scheme] = ENV['OIDC_HTTP_SCHEME'] if ENV['OIDC_HTTP_SCHEME'] # OPTIONAL (default: https)
|
||||
oidc_options[:client_options][:host] = ENV['OIDC_HOST'] if ENV['OIDC_HOST'] # OPTIONAL
|
||||
oidc_options[:client_options][:port] = ENV['OIDC_PORT'] if ENV['OIDC_PORT'] # OPTIONAL
|
||||
oidc_options[:client_options][:authorization_endpoint] = ENV['OIDC_AUTH_ENDPOINT'] if ENV['OIDC_AUTH_ENDPOINT'] # NEED when discovery != true
|
||||
oidc_options[:client_options][:token_endpoint] = ENV['OIDC_TOKEN_ENDPOINT'] if ENV['OIDC_TOKEN_ENDPOINT'] # NEED when discovery != true
|
||||
oidc_options[:client_options][:userinfo_endpoint] = ENV['OIDC_USER_INFO_ENDPOINT'] if ENV['OIDC_USER_INFO_ENDPOINT'] # NEED when discovery != true
|
||||
oidc_options[:client_options][:jwks_uri] = ENV['OIDC_JWKS_URI'] if ENV['OIDC_JWKS_URI'] # NEED when discovery != true
|
||||
oidc_options[:client_options][:end_session_endpoint] = ENV['OIDC_END_SESSION_ENDPOINT'] if ENV['OIDC_END_SESSION_ENDPOINT'] # OPTIONAL
|
||||
oidc_options[:security] = {}
|
||||
oidc_options[:security][:assume_email_is_verified] = ENV['OIDC_SECURITY_ASSUME_EMAIL_IS_VERIFIED'] == 'true' #OPTIONAL
|
||||
oidc_options[:security][:assume_email_is_verified] = ENV['OIDC_SECURITY_ASSUME_EMAIL_IS_VERIFIED'] == 'true' # OPTIONAL
|
||||
config.omniauth :openid_connect, oidc_options
|
||||
end
|
||||
end
|
||||
|
|
41
config/initializers/active_record_encryption.rb
Normal file
41
config/initializers/active_record_encryption.rb
Normal file
|
@ -0,0 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
%w(
|
||||
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY
|
||||
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT
|
||||
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY
|
||||
).each do |key|
|
||||
if ENV['SECRET_KEY_BASE_DUMMY']
|
||||
# Use placeholder value during production env asset compilation
|
||||
ENV[key] = SecureRandom.hex(64)
|
||||
end
|
||||
|
||||
value = ENV.fetch(key) do
|
||||
abort <<~MESSAGE
|
||||
|
||||
Mastodon now requires that these variables are set:
|
||||
|
||||
- ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY
|
||||
- ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT
|
||||
- ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY
|
||||
|
||||
Run `bin/rails db:encryption:init` to generate new secrets and then assign the environment variables.
|
||||
MESSAGE
|
||||
end
|
||||
|
||||
next unless Rails.env.production? && value.end_with?('DO_NOT_USE_IN_PRODUCTION')
|
||||
|
||||
abort <<~MESSAGE
|
||||
|
||||
It looks like you are trying to run Mastodon in production with a #{key} value from the test environment.
|
||||
|
||||
Please generate fresh secrets using `bin/rails db:encryption:init` and use them instead.
|
||||
MESSAGE
|
||||
end
|
||||
|
||||
Rails.application.configure do
|
||||
config.active_record.encryption.deterministic_key = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY')
|
||||
config.active_record.encryption.key_derivation_salt = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT')
|
||||
config.active_record.encryption.primary_key = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY')
|
||||
config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true
|
||||
end
|
|
@ -1,4 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# ActiveSupport::Reloader.to_prepare do
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Version of your assets, change this if you want to expire all your assets.
|
||||
Rails.application.config.assets.version = '1.0'
|
||||
|
||||
# Add additional assets to the asset load path.
|
||||
# Rails.application.config.assets.paths << Emoji.images_path
|
||||
|
||||
# Precompile additional assets.
|
||||
# application.js, application.css, and all non-JS/CSS in the app/assets
|
||||
# folder are already added.
|
||||
# Rails.application.config.assets.precompile += %w( admin.js admin.css )
|
||||
|
||||
Rails.application.config.assets.initialize_on_precompile = true
|
|
@ -7,4 +7,4 @@
|
|||
|
||||
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code
|
||||
# by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'".
|
||||
Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"]
|
||||
Rails.backtrace_cleaner.remove_silencers! if ENV['BACKTRACE']
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.configure do
|
||||
config.x.email_domains_blacklist = (ENV['EMAIL_DOMAIN_DENYLIST'] || ENV['EMAIL_DOMAIN_BLACKLIST']) || ''
|
||||
config.x.email_domains_whitelist = (ENV['EMAIL_DOMAIN_ALLOWLIST'] || ENV['EMAIL_DOMAIN_WHITELIST']) || ''
|
||||
end
|
|
@ -3,10 +3,13 @@
|
|||
enabled = ENV['ES_ENABLED'] == 'true'
|
||||
host = ENV.fetch('ES_HOST') { 'localhost' }
|
||||
port = ENV.fetch('ES_PORT') { 9200 }
|
||||
user = ENV.fetch('ES_USER') { nil }
|
||||
password = ENV.fetch('ES_PASS') { nil }
|
||||
fallback_prefix = ENV.fetch('REDIS_NAMESPACE') { nil }
|
||||
user = ENV.fetch('ES_USER', nil).presence
|
||||
password = ENV.fetch('ES_PASS', nil).presence
|
||||
fallback_prefix = ENV.fetch('REDIS_NAMESPACE', nil).presence
|
||||
prefix = ENV.fetch('ES_PREFIX') { fallback_prefix }
|
||||
ca_file = ENV.fetch('ES_CA_FILE', nil).presence
|
||||
|
||||
transport_options = { ssl: { ca_file: ca_file } } if ca_file.present?
|
||||
|
||||
Chewy.settings = {
|
||||
host: "#{host}:#{port}",
|
||||
|
@ -18,6 +21,7 @@ Chewy.settings = {
|
|||
index: {
|
||||
number_of_replicas: ['single_node_cluster', nil].include?(ENV['ES_PRESET'].presence) ? 0 : 1,
|
||||
},
|
||||
transport_options: transport_options,
|
||||
}
|
||||
|
||||
# We use our own async strategy even outside the request-response
|
||||
|
|
|
@ -1,75 +1,47 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Define an application-wide content security policy
|
||||
# For further information see the following documentation
|
||||
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
def host_to_url(str)
|
||||
return if str.blank?
|
||||
# Define an application-wide content security policy.
|
||||
# See the Securing Rails Applications Guide for more information:
|
||||
# https://guides.rubyonrails.org/security.html#content-security-policy-header
|
||||
|
||||
uri = Addressable::URI.parse("http#{Rails.configuration.x.use_https ? 's' : ''}://#{str}")
|
||||
uri.path += '/' unless uri.path.blank? || uri.path.end_with?('/')
|
||||
uri.to_s
|
||||
end
|
||||
require_relative '../../app/lib/content_security_policy'
|
||||
|
||||
base_host = Rails.configuration.x.web_domain
|
||||
|
||||
assets_host = Rails.configuration.action_controller.asset_host
|
||||
assets_host ||= host_to_url(base_host)
|
||||
|
||||
media_host = host_to_url(ENV['S3_ALIAS_HOST'])
|
||||
media_host ||= host_to_url(ENV['S3_CLOUDFRONT_HOST'])
|
||||
media_host ||= host_to_url(ENV['AZURE_ALIAS_HOST'])
|
||||
media_host ||= host_to_url(ENV['S3_HOSTNAME']) if ENV['S3_ENABLED'] == 'true'
|
||||
media_host ||= assets_host
|
||||
|
||||
def sso_host
|
||||
return unless ENV['ONE_CLICK_SSO_LOGIN'] == 'true'
|
||||
return unless ENV['OMNIAUTH_ONLY'] == 'true'
|
||||
return unless Devise.omniauth_providers.length == 1
|
||||
|
||||
provider = Devise.omniauth_configs[Devise.omniauth_providers[0]]
|
||||
@sso_host ||= begin
|
||||
case provider.provider
|
||||
when :cas
|
||||
provider.cas_url
|
||||
when :saml
|
||||
provider.options[:idp_sso_target_url]
|
||||
when :openid_connect
|
||||
provider.options.dig(:client_options, :authorization_endpoint) || OpenIDConnect::Discovery::Provider::Config.discover!(provider.options[:issuer]).authorization_endpoint
|
||||
end
|
||||
end
|
||||
end
|
||||
policy = ContentSecurityPolicy.new
|
||||
assets_host = policy.assets_host
|
||||
media_hosts = policy.media_hosts
|
||||
|
||||
Rails.application.config.content_security_policy do |p|
|
||||
p.base_uri :none
|
||||
p.default_src :none
|
||||
p.frame_ancestors :none
|
||||
p.font_src :self, assets_host
|
||||
p.img_src :self, :https, :data, :blob, assets_host
|
||||
p.img_src :self, :data, :blob, *media_hosts
|
||||
p.style_src :self, assets_host
|
||||
p.media_src :self, :https, :data, assets_host
|
||||
p.frame_src :self, :https
|
||||
p.media_src :self, :data, *media_hosts
|
||||
p.manifest_src :self, assets_host
|
||||
|
||||
if sso_host.present?
|
||||
p.form_action :self, sso_host
|
||||
if policy.sso_host.present?
|
||||
p.form_action :self, policy.sso_host
|
||||
else
|
||||
p.form_action :self
|
||||
p.form_action :self
|
||||
end
|
||||
|
||||
p.child_src :self, :blob, assets_host
|
||||
p.worker_src :self, :blob, assets_host
|
||||
p.child_src :self, :blob, assets_host
|
||||
p.worker_src :self, :blob, assets_host
|
||||
|
||||
if Rails.env.development?
|
||||
webpacker_public_host = ENV.fetch('WEBPACKER_DEV_SERVER_PUBLIC', Webpacker.config.dev_server[:public])
|
||||
webpacker_urls = %w(ws http).map { |protocol| "#{protocol}#{Webpacker.dev_server.https? ? 's' : ''}://#{webpacker_public_host}" }
|
||||
front_end_build_urls = %w(ws http).map { |protocol| "#{protocol}#{Webpacker.dev_server.https? ? 's' : ''}://#{webpacker_public_host}" }
|
||||
|
||||
p.connect_src :self, :data, :blob, assets_host, media_host, Rails.configuration.x.streaming_api_base_url, *webpacker_urls
|
||||
p.connect_src :self, :data, :blob, *media_hosts, Rails.configuration.x.streaming_api_base_url, *front_end_build_urls
|
||||
p.script_src :self, :unsafe_inline, :unsafe_eval, assets_host
|
||||
p.frame_src :self, :https, :http
|
||||
else
|
||||
p.connect_src :self, :data, :blob, assets_host, media_host, Rails.configuration.x.streaming_api_base_url
|
||||
p.connect_src :self, :data, :blob, *media_hosts, Rails.configuration.x.streaming_api_base_url
|
||||
p.script_src :self, assets_host, "'wasm-unsafe-eval'"
|
||||
p.frame_src :self, :https
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -78,7 +50,7 @@ end
|
|||
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
|
||||
# Rails.application.config.content_security_policy_report_only = true
|
||||
|
||||
Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
|
||||
Rails.application.config.content_security_policy_nonce_generator = ->(_request) { SecureRandom.base64(16) }
|
||||
|
||||
Rails.application.config.content_security_policy_nonce_directives = %w(style-src)
|
||||
|
||||
|
@ -103,7 +75,7 @@ Rails.application.reloader.to_prepare do
|
|||
p.worker_src :none
|
||||
end
|
||||
|
||||
LetterOpenerWeb::LettersController.after_action do |p|
|
||||
LetterOpenerWeb::LettersController.after_action do
|
||||
request.content_security_policy_nonce_directives = %w(script-src)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# TODO: Remove after 4.2.0
|
||||
Rails.application.configure do
|
||||
config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA1
|
||||
end
|
||||
# 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|
|
||||
|
@ -12,9 +9,8 @@ Rails.application.config.after_initialize do
|
|||
|
||||
secret_key_base = Rails.application.secret_key_base
|
||||
|
||||
# TODO: Switch to SHA1 after 4.2.0
|
||||
key_generator = ActiveSupport::KeyGenerator.new(
|
||||
secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA256
|
||||
secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA1
|
||||
)
|
||||
key_len = ActiveSupport::MessageEncryptor.key_len
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Avoid CORS issues when API is called from the frontend app.
|
||||
# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests.
|
||||
# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin Ajax requests.
|
||||
|
||||
# Read more: https://github.com/cyu/rack-cors
|
||||
|
||||
|
@ -11,26 +11,18 @@ Rails.application.config.middleware.insert_before 0, Rack::Cors do
|
|||
allow do
|
||||
origins '*'
|
||||
|
||||
resource '/.well-known/*',
|
||||
headers: :any,
|
||||
methods: [:get],
|
||||
credentials: false
|
||||
resource '/@:username',
|
||||
headers: :any,
|
||||
methods: [:get],
|
||||
credentials: false
|
||||
resource '/users/:username',
|
||||
headers: :any,
|
||||
methods: [:get],
|
||||
credentials: false
|
||||
resource '/api/*',
|
||||
headers: :any,
|
||||
methods: [:post, :put, :delete, :get, :patch, :options],
|
||||
credentials: false,
|
||||
expose: ['Link', 'X-RateLimit-Reset', 'X-RateLimit-Limit', 'X-RateLimit-Remaining', 'X-Request-Id']
|
||||
resource '/oauth/token',
|
||||
headers: :any,
|
||||
methods: [:post],
|
||||
credentials: false
|
||||
with_options headers: :any, credentials: false do
|
||||
with_options methods: [:get] do
|
||||
resource '/.well-known/*'
|
||||
resource '/nodeinfo/*'
|
||||
resource '/@:username'
|
||||
resource '/users/:username'
|
||||
end
|
||||
resource '/api/*',
|
||||
expose: %w(Link X-RateLimit-Reset X-RateLimit-Limit X-RateLimit-Remaining X-Request-Id),
|
||||
methods: %i(post put delete get patch options)
|
||||
resource '/oauth/token', methods: [:post]
|
||||
resource '/oauth/revoke', methods: [:post]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,42 +38,25 @@ Warden::Manager.before_logout do |_, warden|
|
|||
end
|
||||
|
||||
module Devise
|
||||
mattr_accessor :pam_authentication
|
||||
@@pam_authentication = false
|
||||
mattr_accessor :pam_controlled_service
|
||||
@@pam_controlled_service = nil
|
||||
mattr_accessor :pam_authentication, default: false
|
||||
mattr_accessor :pam_controlled_service, default: nil
|
||||
|
||||
mattr_accessor :check_at_sign
|
||||
@@check_at_sign = false
|
||||
mattr_accessor :check_at_sign, default: false
|
||||
|
||||
mattr_accessor :ldap_authentication
|
||||
@@ldap_authentication = false
|
||||
mattr_accessor :ldap_host
|
||||
@@ldap_host = nil
|
||||
mattr_accessor :ldap_port
|
||||
@@ldap_port = nil
|
||||
mattr_accessor :ldap_method
|
||||
@@ldap_method = nil
|
||||
mattr_accessor :ldap_base
|
||||
@@ldap_base = nil
|
||||
mattr_accessor :ldap_uid
|
||||
@@ldap_uid = nil
|
||||
mattr_accessor :ldap_mail
|
||||
@@ldap_mail = nil
|
||||
mattr_accessor :ldap_bind_dn
|
||||
@@ldap_bind_dn = nil
|
||||
mattr_accessor :ldap_password
|
||||
@@ldap_password = nil
|
||||
mattr_accessor :ldap_tls_no_verify
|
||||
@@ldap_tls_no_verify = false
|
||||
mattr_accessor :ldap_search_filter
|
||||
@@ldap_search_filter = nil
|
||||
mattr_accessor :ldap_uid_conversion_enabled
|
||||
@@ldap_uid_conversion_enabled = false
|
||||
mattr_accessor :ldap_uid_conversion_search
|
||||
@@ldap_uid_conversion_search = nil
|
||||
mattr_accessor :ldap_uid_conversion_replace
|
||||
@@ldap_uid_conversion_replace = nil
|
||||
mattr_accessor :ldap_authentication, default: false
|
||||
mattr_accessor :ldap_host, default: nil
|
||||
mattr_accessor :ldap_port, default: nil
|
||||
mattr_accessor :ldap_method, default: nil
|
||||
mattr_accessor :ldap_base, default: nil
|
||||
mattr_accessor :ldap_uid, default: nil
|
||||
mattr_accessor :ldap_mail, default: nil
|
||||
mattr_accessor :ldap_bind_dn, default: nil
|
||||
mattr_accessor :ldap_password, default: nil
|
||||
mattr_accessor :ldap_tls_no_verify, default: false
|
||||
mattr_accessor :ldap_search_filter, default: nil
|
||||
mattr_accessor :ldap_uid_conversion_enabled, default: false
|
||||
mattr_accessor :ldap_uid_conversion_search, default: nil
|
||||
mattr_accessor :ldap_uid_conversion_replace, default: nil
|
||||
|
||||
module Strategies
|
||||
class PamAuthenticatable
|
||||
|
@ -96,9 +79,7 @@ module Devise
|
|||
return pass
|
||||
end
|
||||
|
||||
if validate(resource)
|
||||
success!(resource)
|
||||
end
|
||||
success!(resource) if validate(resource)
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -124,9 +105,11 @@ Devise.setup do |config|
|
|||
# The secret key used by Devise. Devise uses this key to generate
|
||||
# random tokens. Changing this key will render invalid all existing
|
||||
# confirmation, reset password and unlock tokens in the database.
|
||||
# Devise will use the `secret_key_base` on Rails 4+ applications as its `secret_key`
|
||||
# by default. You can change it below and use your own secret key.
|
||||
# config.secret_key = '2f86974c4dd7735170fd70fbf399f7a477ffd635ef240d07a22cf4bd7cd13dbae17c4383a2996d0c1e79a991ec18a91a17424c53e4771adb75a8b21904bd1403'
|
||||
#
|
||||
# Set explicitly to Rails default to avoid deprecation warnings.
|
||||
# https://github.com/heartcombo/devise/pull/5645#issuecomment-1871849856
|
||||
# Remove when Devise changes `SecretKeyFinder` to not emit deprecations.
|
||||
config.secret_key = Rails.application.secret_key_base
|
||||
|
||||
# ==> Mailer Configuration
|
||||
# Configure the e-mail address which will be shown in Devise::Mailer,
|
||||
|
@ -394,7 +377,7 @@ Devise.setup do |config|
|
|||
config.check_at_sign = true
|
||||
config.pam_default_suffix = ENV.fetch('PAM_EMAIL_DOMAIN') { ENV['LOCAL_DOMAIN'] }
|
||||
config.pam_default_service = ENV.fetch('PAM_DEFAULT_SERVICE') { 'rpam' }
|
||||
config.pam_controlled_service = ENV.fetch('PAM_CONTROLLED_SERVICE') { nil }
|
||||
config.pam_controlled_service = ENV.fetch('PAM_CONTROLLED_SERVICE', nil).presence
|
||||
end
|
||||
|
||||
if ENV['LDAP_ENABLED'] == 'true'
|
||||
|
|
|
@ -74,7 +74,8 @@ Doorkeeper.configure do
|
|||
# For more information go to
|
||||
# https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes
|
||||
default_scopes :read
|
||||
optional_scopes :write,
|
||||
optional_scopes :profile,
|
||||
:write,
|
||||
:'write:accounts',
|
||||
:'write:blocks',
|
||||
:'write:bookmarks',
|
||||
|
@ -117,8 +118,7 @@ Doorkeeper.configure do
|
|||
:'admin:write:domain_blocks',
|
||||
:'admin:write:ip_blocks',
|
||||
:'admin:write:email_domain_blocks',
|
||||
:'admin:write:canonical_email_blocks',
|
||||
:crypto
|
||||
:'admin:write:canonical_email_blocks'
|
||||
|
||||
# Change the way client credentials are retrieved from the request object.
|
||||
# By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
|
||||
|
@ -146,11 +146,11 @@ Doorkeeper.configure do
|
|||
force_ssl_in_redirect_uri false
|
||||
|
||||
# Specify what redirect URI's you want to block during Application creation.
|
||||
# Any redirect URI is whitelisted by default.
|
||||
# Any redirect URI is allowed by default.
|
||||
#
|
||||
# You can use this option in order to forbid URI's with 'javascript' scheme
|
||||
# for example.
|
||||
forbid_redirect_uri { |uri| %w[data vbscript javascript].include?(uri.scheme.to_s.downcase) }
|
||||
forbid_redirect_uri { |uri| %w(data vbscript javascript).include?(uri.scheme.to_s.downcase) }
|
||||
|
||||
# Specify what grant flows are enabled in array of Strings. The valid
|
||||
# strings and the flows they enable are:
|
||||
|
@ -174,7 +174,7 @@ Doorkeeper.configure do
|
|||
# Under some circumstances you might want to have applications auto-approved,
|
||||
# so that the user skips the authorization step.
|
||||
# For example if dealing with a trusted application.
|
||||
skip_authorization do |resource_owner, client|
|
||||
skip_authorization do |_resource_owner, client|
|
||||
client.application.superapp?
|
||||
end
|
||||
|
||||
|
|
6
config/initializers/email_domains_lists.rb
Normal file
6
config/initializers/email_domains_lists.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.configure do
|
||||
config.x.email_domains_denylist = ENV.fetch('EMAIL_DOMAIN_DENYLIST', nil) || ENV.fetch('EMAIL_DOMAIN_BLACKLIST', '')
|
||||
config.x.email_domains_allowlist = ENV.fetch('EMAIL_DOMAIN_ALLOWLIST', nil) || ENV.fetch('EMAIL_DOMAIN_WHITELIST', '')
|
||||
end
|
13
config/initializers/enable_yjit.rb
Normal file
13
config/initializers/enable_yjit.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
# 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
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Configure parameters to be filtered from the log file. Use this to limit dissemination of
|
||||
# sensitive information. See the ActiveSupport::ParameterFilter documentation for supported
|
||||
# notations and behaviors.
|
||||
# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file.
|
||||
# Use this to limit dissemination of sensitive information.
|
||||
# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
|
||||
Rails.application.config.filter_parameters += [
|
||||
:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
|
||||
:passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
|
||||
]
|
||||
|
|
|
@ -7,7 +7,7 @@ Rails.application.configure do
|
|||
proxy = URI.parse(ENV['http_proxy'])
|
||||
|
||||
raise "Unsupported proxy type: #{proxy.scheme}" unless %w(http https).include? proxy.scheme
|
||||
raise "No proxy host" unless proxy.host
|
||||
raise 'No proxy host' unless proxy.host
|
||||
|
||||
host = proxy.host
|
||||
host = host[1...-1] if host[0] == '[' # for IPv6 address
|
||||
|
@ -24,7 +24,7 @@ Rails.application.configure do
|
|||
proxy = URI.parse(ENV['http_hidden_proxy'])
|
||||
|
||||
raise "Unsupported proxy type: #{proxy.scheme}" unless %w(http https).include? proxy.scheme
|
||||
raise "No proxy host" unless proxy.host
|
||||
raise 'No proxy host' unless proxy.host
|
||||
|
||||
host = proxy.host
|
||||
host = host[1...-1] if host[0] == '[' # for IPv6 address
|
||||
|
|
112
config/initializers/i18n.rb
Normal file
112
config/initializers/i18n.rb
Normal file
|
@ -0,0 +1,112 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.configure do
|
||||
config.i18n.available_locales = [
|
||||
:af,
|
||||
:an,
|
||||
:ar,
|
||||
:ast,
|
||||
:be,
|
||||
:bg,
|
||||
:bn,
|
||||
:br,
|
||||
:bs,
|
||||
:ca,
|
||||
:ckb,
|
||||
:co,
|
||||
:cs,
|
||||
:cy,
|
||||
:da,
|
||||
:de,
|
||||
:el,
|
||||
:en,
|
||||
:'en-GB',
|
||||
:eo,
|
||||
:es,
|
||||
:'es-AR',
|
||||
:'es-MX',
|
||||
:et,
|
||||
:eu,
|
||||
:fa,
|
||||
:fi,
|
||||
:fo,
|
||||
:fr,
|
||||
:'fr-CA',
|
||||
:fy,
|
||||
:ga,
|
||||
:gd,
|
||||
:gl,
|
||||
:he,
|
||||
:hi,
|
||||
:hr,
|
||||
:hu,
|
||||
:hy,
|
||||
:ia,
|
||||
:id,
|
||||
:ie,
|
||||
:ig,
|
||||
:io,
|
||||
:is,
|
||||
:it,
|
||||
:ja,
|
||||
:ka,
|
||||
:kab,
|
||||
:kk,
|
||||
:kn,
|
||||
:ko,
|
||||
:ku,
|
||||
:kw,
|
||||
:la,
|
||||
:lt,
|
||||
:lv,
|
||||
:mk,
|
||||
:ml,
|
||||
:mr,
|
||||
:ms,
|
||||
:my,
|
||||
:nl,
|
||||
:nn,
|
||||
:no,
|
||||
:oc,
|
||||
:pa,
|
||||
:pl,
|
||||
:'pt-BR',
|
||||
:'pt-PT',
|
||||
:ro,
|
||||
:ru,
|
||||
:sa,
|
||||
:sc,
|
||||
:sco,
|
||||
:si,
|
||||
:sk,
|
||||
:sl,
|
||||
:sq,
|
||||
:sr,
|
||||
:'sr-Latn',
|
||||
:sv,
|
||||
:szl,
|
||||
:ta,
|
||||
:te,
|
||||
:th,
|
||||
:tr,
|
||||
:tt,
|
||||
:ug,
|
||||
:uk,
|
||||
:ur,
|
||||
:vi,
|
||||
:zgh,
|
||||
:'zh-CN',
|
||||
:'zh-HK',
|
||||
:'zh-TW',
|
||||
]
|
||||
|
||||
config.i18n.default_locale = begin
|
||||
custom_default_locale = ENV['DEFAULT_LOCALE']&.to_sym
|
||||
|
||||
if Rails.configuration.i18n.available_locales.include?(custom_default_locale)
|
||||
custom_default_locale
|
||||
else
|
||||
:en
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,29 +6,33 @@
|
|||
# are locale specific, and you may define rules for as many different
|
||||
# locales as you wish. All of these examples are active by default:
|
||||
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
||||
# inflect.plural /^(ox)$/i, '\1en'
|
||||
# inflect.singular /^(ox)en/i, '\1'
|
||||
# inflect.irregular 'person', 'people'
|
||||
# inflect.plural /^(ox)$/i, "\\1en"
|
||||
# inflect.singular /^(ox)en/i, "\\1"
|
||||
# inflect.irregular "person", "people"
|
||||
# inflect.uncountable %w( fish sheep )
|
||||
# end
|
||||
|
||||
ActiveSupport::Inflector.inflections(:en) do |inflect|
|
||||
inflect.acronym 'StatsD'
|
||||
inflect.acronym 'OEmbed'
|
||||
inflect.acronym 'OStatus'
|
||||
inflect.acronym 'ActivityPub'
|
||||
inflect.acronym 'PubSubHubbub'
|
||||
inflect.acronym 'ActivityStreams'
|
||||
inflect.acronym 'JsonLd'
|
||||
inflect.acronym 'NodeInfo'
|
||||
inflect.acronym 'Ed25519'
|
||||
inflect.acronym 'TOC'
|
||||
inflect.acronym 'RSS'
|
||||
inflect.acronym 'REST'
|
||||
inflect.acronym 'URL'
|
||||
inflect.acronym 'ASCII'
|
||||
inflect.acronym 'CLI'
|
||||
inflect.acronym 'DeepL'
|
||||
inflect.acronym 'DSL'
|
||||
inflect.acronym 'JsonLd'
|
||||
inflect.acronym 'OEmbed'
|
||||
inflect.acronym 'OStatus'
|
||||
inflect.acronym 'PubSubHubbub'
|
||||
inflect.acronym 'REST'
|
||||
inflect.acronym 'RSS'
|
||||
inflect.acronym 'StatsD'
|
||||
inflect.acronym 'TOC'
|
||||
inflect.acronym 'URL'
|
||||
|
||||
inflect.singular 'data', 'data'
|
||||
end
|
||||
|
||||
# These inflection rules are supported but not enabled by default:
|
||||
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
||||
# inflect.acronym "RESTful"
|
||||
# end
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../../lib/json_ld/security'
|
||||
require_relative '../../lib/json_ld/identity'
|
86
config/initializers/json_ld_identity.rb
Normal file
86
config/initializers/json_ld_identity.rb
Normal file
|
@ -0,0 +1,86 @@
|
|||
# frozen_string_literal: true
|
||||
# This file generated automatically from http://w3id.org/identity/v1
|
||||
require 'json/ld'
|
||||
class JSON::LD::Context
|
||||
add_preloaded("http://w3id.org/identity/v1") do
|
||||
new(term_definitions: {
|
||||
"Credential" => TermDefinition.new("Credential", id: "https://w3id.org/credentials#Credential", simple: true),
|
||||
"CryptographicKey" => TermDefinition.new("CryptographicKey", id: "https://w3id.org/security#Key", simple: true),
|
||||
"CryptographicKeyCredential" => TermDefinition.new("CryptographicKeyCredential", id: "https://w3id.org/credentials#CryptographicKeyCredential", simple: true),
|
||||
"EncryptedMessage" => TermDefinition.new("EncryptedMessage", id: "https://w3id.org/security#EncryptedMessage", simple: true),
|
||||
"GraphSignature2012" => TermDefinition.new("GraphSignature2012", id: "https://w3id.org/security#GraphSignature2012", simple: true),
|
||||
"Group" => TermDefinition.new("Group", id: "https://www.w3.org/ns/activitystreams#Group", simple: true),
|
||||
"Identity" => TermDefinition.new("Identity", id: "https://w3id.org/identity#Identity", simple: true),
|
||||
"LinkedDataSignature2015" => TermDefinition.new("LinkedDataSignature2015", id: "https://w3id.org/security#LinkedDataSignature2015", simple: true),
|
||||
"Organization" => TermDefinition.new("Organization", id: "http://schema.org/Organization", simple: true),
|
||||
"Person" => TermDefinition.new("Person", id: "http://schema.org/Person", simple: true),
|
||||
"PostalAddress" => TermDefinition.new("PostalAddress", id: "http://schema.org/PostalAddress", simple: true),
|
||||
"about" => TermDefinition.new("about", id: "http://schema.org/about", type_mapping: "@id"),
|
||||
"accessControl" => TermDefinition.new("accessControl", id: "https://w3id.org/permissions#accessControl", type_mapping: "@id"),
|
||||
"address" => TermDefinition.new("address", id: "http://schema.org/address", type_mapping: "@id"),
|
||||
"addressCountry" => TermDefinition.new("addressCountry", id: "http://schema.org/addressCountry", simple: true),
|
||||
"addressLocality" => TermDefinition.new("addressLocality", id: "http://schema.org/addressLocality", simple: true),
|
||||
"addressRegion" => TermDefinition.new("addressRegion", id: "http://schema.org/addressRegion", simple: true),
|
||||
"cipherAlgorithm" => TermDefinition.new("cipherAlgorithm", id: "https://w3id.org/security#cipherAlgorithm", simple: true),
|
||||
"cipherData" => TermDefinition.new("cipherData", id: "https://w3id.org/security#cipherData", simple: true),
|
||||
"cipherKey" => TermDefinition.new("cipherKey", id: "https://w3id.org/security#cipherKey", simple: true),
|
||||
"claim" => TermDefinition.new("claim", id: "https://w3id.org/credentials#claim", type_mapping: "@id"),
|
||||
"comment" => TermDefinition.new("comment", id: "http://www.w3.org/2000/01/rdf-schema#comment", simple: true),
|
||||
"created" => TermDefinition.new("created", id: "http://purl.org/dc/terms/created", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
|
||||
"creator" => TermDefinition.new("creator", id: "http://purl.org/dc/terms/creator", type_mapping: "@id"),
|
||||
"cred" => TermDefinition.new("cred", id: "https://w3id.org/credentials#", simple: true, prefix: true),
|
||||
"credential" => TermDefinition.new("credential", id: "https://w3id.org/credentials#credential", type_mapping: "@id"),
|
||||
"dc" => TermDefinition.new("dc", id: "http://purl.org/dc/terms/", simple: true, prefix: true),
|
||||
"description" => TermDefinition.new("description", id: "http://schema.org/description", simple: true),
|
||||
"digestAlgorithm" => TermDefinition.new("digestAlgorithm", id: "https://w3id.org/security#digestAlgorithm", simple: true),
|
||||
"digestValue" => TermDefinition.new("digestValue", id: "https://w3id.org/security#digestValue", simple: true),
|
||||
"domain" => TermDefinition.new("domain", id: "https://w3id.org/security#domain", simple: true),
|
||||
"email" => TermDefinition.new("email", id: "http://schema.org/email", simple: true),
|
||||
"expires" => TermDefinition.new("expires", id: "https://w3id.org/security#expiration", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
|
||||
"familyName" => TermDefinition.new("familyName", id: "http://schema.org/familyName", simple: true),
|
||||
"givenName" => TermDefinition.new("givenName", id: "http://schema.org/givenName", simple: true),
|
||||
"id" => TermDefinition.new("id", id: "@id", simple: true),
|
||||
"identity" => TermDefinition.new("identity", id: "https://w3id.org/identity#", simple: true, prefix: true),
|
||||
"identityService" => TermDefinition.new("identityService", id: "https://w3id.org/identity#identityService", type_mapping: "@id"),
|
||||
"idp" => TermDefinition.new("idp", id: "https://w3id.org/identity#idp", type_mapping: "@id"),
|
||||
"image" => TermDefinition.new("image", id: "http://schema.org/image", type_mapping: "@id"),
|
||||
"initializationVector" => TermDefinition.new("initializationVector", id: "https://w3id.org/security#initializationVector", simple: true),
|
||||
"issued" => TermDefinition.new("issued", id: "https://w3id.org/credentials#issued", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
|
||||
"issuer" => TermDefinition.new("issuer", id: "https://w3id.org/credentials#issuer", type_mapping: "@id"),
|
||||
"label" => TermDefinition.new("label", id: "http://www.w3.org/2000/01/rdf-schema#label", simple: true),
|
||||
"member" => TermDefinition.new("member", id: "http://schema.org/member", type_mapping: "@id"),
|
||||
"memberOf" => TermDefinition.new("memberOf", id: "http://schema.org/memberOf", type_mapping: "@id"),
|
||||
"name" => TermDefinition.new("name", id: "http://schema.org/name", simple: true),
|
||||
"nonce" => TermDefinition.new("nonce", id: "https://w3id.org/security#nonce", simple: true),
|
||||
"normalizationAlgorithm" => TermDefinition.new("normalizationAlgorithm", id: "https://w3id.org/security#normalizationAlgorithm", simple: true),
|
||||
"owner" => TermDefinition.new("owner", id: "https://w3id.org/security#owner", type_mapping: "@id"),
|
||||
"password" => TermDefinition.new("password", id: "https://w3id.org/security#password", simple: true),
|
||||
"paymentProcessor" => TermDefinition.new("paymentProcessor", id: "https://w3id.org/payswarm#processor", simple: true),
|
||||
"perm" => TermDefinition.new("perm", id: "https://w3id.org/permissions#", simple: true, prefix: true),
|
||||
"postalCode" => TermDefinition.new("postalCode", id: "http://schema.org/postalCode", simple: true),
|
||||
"preferences" => TermDefinition.new("preferences", id: "https://w3id.org/payswarm#preferences", type_mapping: "@vocab"),
|
||||
"privateKey" => TermDefinition.new("privateKey", id: "https://w3id.org/security#privateKey", type_mapping: "@id"),
|
||||
"privateKeyPem" => TermDefinition.new("privateKeyPem", id: "https://w3id.org/security#privateKeyPem", simple: true),
|
||||
"ps" => TermDefinition.new("ps", id: "https://w3id.org/payswarm#", simple: true, prefix: true),
|
||||
"publicKey" => TermDefinition.new("publicKey", id: "https://w3id.org/security#publicKey", type_mapping: "@id"),
|
||||
"publicKeyPem" => TermDefinition.new("publicKeyPem", id: "https://w3id.org/security#publicKeyPem", simple: true),
|
||||
"publicKeyService" => TermDefinition.new("publicKeyService", id: "https://w3id.org/security#publicKeyService", type_mapping: "@id"),
|
||||
"rdf" => TermDefinition.new("rdf", id: "http://www.w3.org/1999/02/22-rdf-syntax-ns#", simple: true, prefix: true),
|
||||
"rdfs" => TermDefinition.new("rdfs", id: "http://www.w3.org/2000/01/rdf-schema#", simple: true, prefix: true),
|
||||
"recipient" => TermDefinition.new("recipient", id: "https://w3id.org/credentials#recipient", type_mapping: "@id"),
|
||||
"revoked" => TermDefinition.new("revoked", id: "https://w3id.org/security#revoked", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
|
||||
"schema" => TermDefinition.new("schema", id: "http://schema.org/", simple: true, prefix: true),
|
||||
"sec" => TermDefinition.new("sec", id: "https://w3id.org/security#", simple: true, prefix: true),
|
||||
"signature" => TermDefinition.new("signature", id: "https://w3id.org/security#signature", simple: true),
|
||||
"signatureAlgorithm" => TermDefinition.new("signatureAlgorithm", id: "https://w3id.org/security#signatureAlgorithm", simple: true),
|
||||
"signatureValue" => TermDefinition.new("signatureValue", id: "https://w3id.org/security#signatureValue", simple: true),
|
||||
"streetAddress" => TermDefinition.new("streetAddress", id: "http://schema.org/streetAddress", simple: true),
|
||||
"title" => TermDefinition.new("title", id: "http://purl.org/dc/terms/title", simple: true),
|
||||
"type" => TermDefinition.new("type", id: "@type", simple: true),
|
||||
"url" => TermDefinition.new("url", id: "http://schema.org/url", type_mapping: "@id"),
|
||||
"writePermission" => TermDefinition.new("writePermission", id: "https://w3id.org/permissions#writePermission", type_mapping: "@id"),
|
||||
"xsd" => TermDefinition.new("xsd", id: "http://www.w3.org/2001/XMLSchema#", simple: true, prefix: true)
|
||||
})
|
||||
end
|
||||
alias_preloaded("https://w3id.org/identity/v1", "http://w3id.org/identity/v1")
|
||||
end
|
50
config/initializers/json_ld_security.rb
Normal file
50
config/initializers/json_ld_security.rb
Normal file
|
@ -0,0 +1,50 @@
|
|||
# frozen_string_literal: true
|
||||
# This file generated automatically from http://w3id.org/security/v1
|
||||
require 'json/ld'
|
||||
class JSON::LD::Context
|
||||
add_preloaded("http://w3id.org/security/v1") do
|
||||
new(processingMode: "json-ld-1.0", term_definitions: {
|
||||
"CryptographicKey" => TermDefinition.new("CryptographicKey", id: "https://w3id.org/security#Key", simple: true),
|
||||
"EcdsaKoblitzSignature2016" => TermDefinition.new("EcdsaKoblitzSignature2016", id: "https://w3id.org/security#EcdsaKoblitzSignature2016", simple: true),
|
||||
"EncryptedMessage" => TermDefinition.new("EncryptedMessage", id: "https://w3id.org/security#EncryptedMessage", simple: true),
|
||||
"GraphSignature2012" => TermDefinition.new("GraphSignature2012", id: "https://w3id.org/security#GraphSignature2012", simple: true),
|
||||
"LinkedDataSignature2015" => TermDefinition.new("LinkedDataSignature2015", id: "https://w3id.org/security#LinkedDataSignature2015", simple: true),
|
||||
"LinkedDataSignature2016" => TermDefinition.new("LinkedDataSignature2016", id: "https://w3id.org/security#LinkedDataSignature2016", simple: true),
|
||||
"authenticationTag" => TermDefinition.new("authenticationTag", id: "https://w3id.org/security#authenticationTag", simple: true),
|
||||
"canonicalizationAlgorithm" => TermDefinition.new("canonicalizationAlgorithm", id: "https://w3id.org/security#canonicalizationAlgorithm", simple: true),
|
||||
"cipherAlgorithm" => TermDefinition.new("cipherAlgorithm", id: "https://w3id.org/security#cipherAlgorithm", simple: true),
|
||||
"cipherData" => TermDefinition.new("cipherData", id: "https://w3id.org/security#cipherData", simple: true),
|
||||
"cipherKey" => TermDefinition.new("cipherKey", id: "https://w3id.org/security#cipherKey", simple: true),
|
||||
"created" => TermDefinition.new("created", id: "http://purl.org/dc/terms/created", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
|
||||
"creator" => TermDefinition.new("creator", id: "http://purl.org/dc/terms/creator", type_mapping: "@id"),
|
||||
"dc" => TermDefinition.new("dc", id: "http://purl.org/dc/terms/", simple: true, prefix: true),
|
||||
"digestAlgorithm" => TermDefinition.new("digestAlgorithm", id: "https://w3id.org/security#digestAlgorithm", simple: true),
|
||||
"digestValue" => TermDefinition.new("digestValue", id: "https://w3id.org/security#digestValue", simple: true),
|
||||
"domain" => TermDefinition.new("domain", id: "https://w3id.org/security#domain", simple: true),
|
||||
"encryptionKey" => TermDefinition.new("encryptionKey", id: "https://w3id.org/security#encryptionKey", simple: true),
|
||||
"expiration" => TermDefinition.new("expiration", id: "https://w3id.org/security#expiration", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
|
||||
"expires" => TermDefinition.new("expires", id: "https://w3id.org/security#expiration", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
|
||||
"id" => TermDefinition.new("id", id: "@id", simple: true),
|
||||
"initializationVector" => TermDefinition.new("initializationVector", id: "https://w3id.org/security#initializationVector", simple: true),
|
||||
"iterationCount" => TermDefinition.new("iterationCount", id: "https://w3id.org/security#iterationCount", simple: true),
|
||||
"nonce" => TermDefinition.new("nonce", id: "https://w3id.org/security#nonce", simple: true),
|
||||
"normalizationAlgorithm" => TermDefinition.new("normalizationAlgorithm", id: "https://w3id.org/security#normalizationAlgorithm", simple: true),
|
||||
"owner" => TermDefinition.new("owner", id: "https://w3id.org/security#owner", type_mapping: "@id"),
|
||||
"password" => TermDefinition.new("password", id: "https://w3id.org/security#password", simple: true),
|
||||
"privateKey" => TermDefinition.new("privateKey", id: "https://w3id.org/security#privateKey", type_mapping: "@id"),
|
||||
"privateKeyPem" => TermDefinition.new("privateKeyPem", id: "https://w3id.org/security#privateKeyPem", simple: true),
|
||||
"publicKey" => TermDefinition.new("publicKey", id: "https://w3id.org/security#publicKey", type_mapping: "@id"),
|
||||
"publicKeyPem" => TermDefinition.new("publicKeyPem", id: "https://w3id.org/security#publicKeyPem", simple: true),
|
||||
"publicKeyService" => TermDefinition.new("publicKeyService", id: "https://w3id.org/security#publicKeyService", type_mapping: "@id"),
|
||||
"revoked" => TermDefinition.new("revoked", id: "https://w3id.org/security#revoked", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
|
||||
"salt" => TermDefinition.new("salt", id: "https://w3id.org/security#salt", simple: true),
|
||||
"sec" => TermDefinition.new("sec", id: "https://w3id.org/security#", simple: true, prefix: true),
|
||||
"signature" => TermDefinition.new("signature", id: "https://w3id.org/security#signature", simple: true),
|
||||
"signatureAlgorithm" => TermDefinition.new("signatureAlgorithm", id: "https://w3id.org/security#signingAlgorithm", simple: true),
|
||||
"signatureValue" => TermDefinition.new("signatureValue", id: "https://w3id.org/security#signatureValue", simple: true),
|
||||
"type" => TermDefinition.new("type", id: "@type", simple: true),
|
||||
"xsd" => TermDefinition.new("xsd", id: "http://www.w3.org/2001/XMLSchema#", simple: true, prefix: true)
|
||||
})
|
||||
end
|
||||
alias_preloaded("https://w3id.org/security/v1", "http://w3id.org/security/v1")
|
||||
end
|
|
@ -1,10 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# TODO
|
||||
# The Rails 7.0 framework default here is to set this true. However, we have a
|
||||
# location in devise that redirects where we don't have an easy ability to
|
||||
# override a method or set a config option, but where the redirect does not
|
||||
# provide this option.
|
||||
# https://github.com/heartcombo/devise/blob/v4.9.2/app/controllers/devise/confirmations_controller.rb#L28
|
||||
# Once a solution is found, this line can be removed.
|
||||
Rails.application.config.action_controller.raise_on_open_redirects = false
|
7
config/initializers/open_redirects.rb
Normal file
7
config/initializers/open_redirects.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# TODO: Starting with Rails 7.0, the framework default is true for this setting.
|
||||
# This location in devise redirects and we can't hook in or override:
|
||||
# https://github.com/heartcombo/devise/blob/v4.9.3/app/controllers/devise/confirmations_controller.rb#L28
|
||||
# When solution is found, this setting can go back to default.
|
||||
Rails.application.config.action_controller.raise_on_open_redirects = false
|
71
config/initializers/opentelemetry.rb
Normal file
71
config/initializers/opentelemetry.rb
Normal file
|
@ -0,0 +1,71 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Set OTEL_* environment variables according to OTel docs:
|
||||
# https://opentelemetry.io/docs/concepts/sdk-configuration/
|
||||
|
||||
if ENV.keys.any? { |name| name.match?(/OTEL_.*_ENDPOINT/) }
|
||||
require 'opentelemetry/sdk'
|
||||
require 'opentelemetry/exporter/otlp'
|
||||
|
||||
require 'opentelemetry/instrumentation/active_job'
|
||||
require 'opentelemetry/instrumentation/active_model_serializers'
|
||||
require 'opentelemetry/instrumentation/concurrent_ruby'
|
||||
require 'opentelemetry/instrumentation/excon'
|
||||
require 'opentelemetry/instrumentation/faraday'
|
||||
require 'opentelemetry/instrumentation/http'
|
||||
require 'opentelemetry/instrumentation/http_client'
|
||||
require 'opentelemetry/instrumentation/net/http'
|
||||
require 'opentelemetry/instrumentation/pg'
|
||||
require 'opentelemetry/instrumentation/rack'
|
||||
require 'opentelemetry/instrumentation/rails'
|
||||
require 'opentelemetry/instrumentation/redis'
|
||||
require 'opentelemetry/instrumentation/sidekiq'
|
||||
|
||||
OpenTelemetry::SDK.configure do |c|
|
||||
# use_all() attempts to load ALL the auto-instrumentations
|
||||
# currently loaded by Ruby requires.
|
||||
#
|
||||
# Load attempts will emit an INFO or WARN to the console
|
||||
# about the success/failure to wire up an auto-instrumentation.
|
||||
# "WARN -- : Instrumentation: <X> failed to install" is most
|
||||
# likely caused by <X> not being a Ruby library loaded by
|
||||
# the application or the instrumentation has been explicitly
|
||||
# disabled.
|
||||
#
|
||||
# To disable an instrumentation, set an environment variable
|
||||
# along this pattern:
|
||||
#
|
||||
# OTEL_RUBY_INSTRUMENTATION_<X>_ENABLED=false
|
||||
#
|
||||
# For example, PostgreSQL and Redis produce a lot of child spans
|
||||
# in the course of this application doing its business. To turn
|
||||
# them off, set the env vars below, but recognize that you will
|
||||
# be missing details about what particular calls to the
|
||||
# datastores are slow.
|
||||
#
|
||||
# OTEL_RUBY_INSTRUMENTATION_PG_ENABLED=false
|
||||
# OTEL_RUBY_INSTRUMENTATION_REDIS_ENABLED=false
|
||||
|
||||
c.use_all({
|
||||
'OpenTelemetry::Instrumentation::Rack' => {
|
||||
use_rack_events: false, # instead of events, use middleware; allows for untraced_endpoints to ignore child spans
|
||||
untraced_endpoints: ['/health'],
|
||||
},
|
||||
'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
|
||||
},
|
||||
})
|
||||
|
||||
prefix = ENV.fetch('OTEL_SERVICE_NAME_PREFIX', 'mastodon')
|
||||
separator = ENV.fetch('OTEL_SERVICE_NAME_SEPARATOR', '/')
|
||||
|
||||
c.service_name = case $PROGRAM_NAME
|
||||
when /puma/ then "#{prefix}#{separator}web"
|
||||
else
|
||||
"#{prefix}#{separator}#{$PROGRAM_NAME.split('/').last}"
|
||||
end
|
||||
c.service_version = Mastodon::Version.to_s
|
||||
end
|
||||
end
|
||||
|
||||
MastodonOTELTracer = OpenTelemetry.tracer_provider.tracer('mastodon')
|
|
@ -3,6 +3,8 @@
|
|||
Paperclip::DataUriAdapter.register
|
||||
Paperclip::ResponseWithLimitAdapter.register
|
||||
|
||||
PATH = ':prefix_url:class/:attachment/:id_partition/:style/:filename'
|
||||
|
||||
Paperclip.interpolates :filename do |attachment, style|
|
||||
if style == :original
|
||||
attachment.original_filename
|
||||
|
@ -11,15 +13,15 @@ Paperclip.interpolates :filename do |attachment, style|
|
|||
end
|
||||
end
|
||||
|
||||
Paperclip.interpolates :prefix_path do |attachment, style|
|
||||
Paperclip.interpolates :prefix_path do |attachment, _style|
|
||||
if attachment.storage_schema_version >= 1 && attachment.instance.respond_to?(:local?) && !attachment.instance.local?
|
||||
'cache' + File::SEPARATOR
|
||||
"cache#{File::SEPARATOR}"
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
Paperclip.interpolates :prefix_url do |attachment, style|
|
||||
Paperclip.interpolates :prefix_url do |attachment, _style|
|
||||
if attachment.storage_schema_version >= 1 && attachment.instance.respond_to?(:local?) && !attachment.instance.local?
|
||||
'cache/'
|
||||
else
|
||||
|
@ -29,7 +31,7 @@ end
|
|||
|
||||
Paperclip::Attachment.default_options.merge!(
|
||||
use_timestamp: false,
|
||||
path: ':prefix_url:class/:attachment/:id_partition/:style/:filename',
|
||||
path: PATH,
|
||||
storage: :fog
|
||||
)
|
||||
|
||||
|
@ -40,6 +42,8 @@ if ENV['S3_ENABLED'] == 'true'
|
|||
s3_protocol = ENV.fetch('S3_PROTOCOL') { 'https' }
|
||||
s3_hostname = ENV.fetch('S3_HOSTNAME') { "s3-#{s3_region}.amazonaws.com" }
|
||||
|
||||
Paperclip::Attachment.default_options[:path] = ENV.fetch('S3_KEY_PREFIX') + "/#{PATH}" if ENV.has_key?('S3_KEY_PREFIX')
|
||||
|
||||
Paperclip::Attachment.default_options.merge!(
|
||||
storage: :s3,
|
||||
s3_protocol: s3_protocol,
|
||||
|
@ -64,16 +68,16 @@ if ENV['S3_ENABLED'] == 'true'
|
|||
http_open_timeout: ENV.fetch('S3_OPEN_TIMEOUT') { '5' }.to_i,
|
||||
http_read_timeout: ENV.fetch('S3_READ_TIMEOUT') { '5' }.to_i,
|
||||
http_idle_timeout: 5,
|
||||
retry_limit: 0,
|
||||
retry_limit: ENV.fetch('S3_RETRY_LIMIT') { '0' }.to_i,
|
||||
}
|
||||
)
|
||||
|
||||
Paperclip::Attachment.default_options[:s3_permissions] = ->(*) { nil } if ENV['S3_PERMISSION'] == ''
|
||||
Paperclip::Attachment.default_options[:s3_permissions] = ->(*) {} if ENV['S3_PERMISSION'] == ''
|
||||
|
||||
if ENV.has_key?('S3_ENDPOINT')
|
||||
Paperclip::Attachment.default_options[:s3_options].merge!(
|
||||
endpoint: ENV['S3_ENDPOINT'],
|
||||
force_path_style: ENV['S3_OVERRIDE_PATH_STYLE'] != 'true',
|
||||
force_path_style: ENV['S3_OVERRIDE_PATH_STYLE'] != 'true'
|
||||
)
|
||||
|
||||
Paperclip::Attachment.default_options[:url] = ':s3_path_url'
|
||||
|
@ -156,10 +160,11 @@ elsif ENV['AZURE_ENABLED'] == 'true'
|
|||
)
|
||||
end
|
||||
else
|
||||
Rails.configuration.x.file_storage_root_path = ENV.fetch('PAPERCLIP_ROOT_PATH', File.join(':rails_root', 'public', 'system'))
|
||||
Paperclip::Attachment.default_options.merge!(
|
||||
storage: :filesystem,
|
||||
path: File.join(ENV.fetch('PAPERCLIP_ROOT_PATH', File.join(':rails_root', 'public', 'system')), ':prefix_path:class', ':attachment', ':id_partition', ':style', ':filename'),
|
||||
url: ENV.fetch('PAPERCLIP_ROOT_URL', '/system') + '/:prefix_url:class/:attachment/:id_partition/:style/:filename',
|
||||
path: File.join(Rails.configuration.x.file_storage_root_path, ':prefix_path:class', ':attachment', ':id_partition', ':style', ':filename'),
|
||||
url: ENV.fetch('PAPERCLIP_ROOT_URL', '/system') + "/#{PATH}"
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Define an application-wide HTTP permissions policy. For further
|
||||
# information see https://developers.google.com/web/updates/2018/06/feature-policy
|
||||
#
|
||||
# Rails.application.config.permissions_policy do |f|
|
||||
# f.camera :none
|
||||
# f.gyroscope :none
|
||||
# f.microphone :none
|
||||
# f.usb :none
|
||||
# f.fullscreen :self
|
||||
# f.payment :self, "https://secure.example.com"
|
||||
# information see: https://developers.google.com/web/updates/2018/06/feature-policy
|
||||
|
||||
# Rails.application.config.permissions_policy do |policy|
|
||||
# policy.camera :none
|
||||
# policy.gyroscope :none
|
||||
# policy.microphone :none
|
||||
# policy.usb :none
|
||||
# policy.fullscreen :self
|
||||
# policy.payment :self, "https://secure.example.com"
|
||||
# end
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../../lib/mastodon/premailer_webpack_strategy'
|
||||
require_relative '../../lib/premailer_bundled_asset_strategy'
|
||||
|
||||
Premailer::Rails.config.merge!(remove_ids: true,
|
||||
adapter: :nokogiri,
|
||||
generate_text_part: false,
|
||||
strategies: [PremailerWebpackStrategy])
|
||||
css_to_attributes: false,
|
||||
strategies: [PremailerBundledAssetStrategy])
|
||||
|
|
7
config/initializers/propshaft.rb
Normal file
7
config/initializers/propshaft.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# SVG icons
|
||||
Rails.application.config.assets.paths << Rails.root.join('app', 'javascript', 'images')
|
||||
|
||||
# Material Design icons
|
||||
Rails.application.config.assets.paths << Rails.root.join('app', 'javascript', 'material-icons')
|
|
@ -14,7 +14,7 @@ class Rack::Attack
|
|||
end
|
||||
|
||||
def remote_ip
|
||||
@remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s
|
||||
@remote_ip ||= (@env['action_dispatch.remote_ip'] || ip).to_s
|
||||
end
|
||||
|
||||
def throttleable_remote_ip
|
||||
|
@ -150,10 +150,10 @@ class Rack::Attack
|
|||
match_data = request.env['rack.attack.match_data']
|
||||
|
||||
headers = {
|
||||
'Content-Type' => 'application/json',
|
||||
'X-RateLimit-Limit' => match_data[:limit].to_s,
|
||||
'Content-Type' => 'application/json',
|
||||
'X-RateLimit-Limit' => match_data[:limit].to_s,
|
||||
'X-RateLimit-Remaining' => '0',
|
||||
'X-RateLimit-Reset' => (now + (match_data[:period] - (now.to_i % match_data[:period]))).iso8601(6),
|
||||
'X-RateLimit-Reset' => (now + (match_data[:period] - (now.to_i % match_data[:period]))).iso8601(6),
|
||||
}
|
||||
|
||||
[429, headers, [{ error: I18n.t('errors.429') }.to_json]]
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
ActiveSupport::Notifications.subscribe(/rack_attack/) do |_name, _start, _finish, _request_id, payload|
|
||||
req = payload[:request]
|
||||
|
||||
next unless [:throttle, :blacklist].include? req.env['rack.attack.match_type']
|
||||
next unless [:throttle, :blocklist].include? req.env['rack.attack.match_type']
|
||||
|
||||
Rails.logger.info("Rate limit hit (#{req.env['rack.attack.match_type']}): #{req.ip} #{req.request_method} #{req.fullpath}")
|
||||
end
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
Rails.application.config.session_store :cookie_store,
|
||||
key: '_mastodon_session',
|
||||
secure: false, # All cookies have their secure flag set by the force_ssl option in production
|
||||
same_site: :lax
|
||||
Rails
|
||||
.application
|
||||
.config
|
||||
.session_store :cookie_store,
|
||||
key: '_mastodon_session',
|
||||
secure: false, # All cookies have their secure flag set by the force_ssl option in production
|
||||
same_site: :lax
|
||||
|
|
|
@ -3,12 +3,24 @@
|
|||
require_relative '../../lib/mastodon/sidekiq_middleware'
|
||||
|
||||
Sidekiq.configure_server do |config|
|
||||
if Rails.configuration.database_configuration.dig('production', 'adapter') == 'postgresql_makara'
|
||||
STDERR.puts 'ERROR: Database replication is not currently supported in Sidekiq workers. Check your configuration.'
|
||||
exit 1
|
||||
end
|
||||
config.redis = REDIS_CONFIGURATION.sidekiq
|
||||
|
||||
config.redis = REDIS_SIDEKIQ_PARAMS
|
||||
# This is used in Kubernetes setups, to signal that the Sidekiq process has started and will begin processing jobs
|
||||
# This comes from https://github.com/sidekiq/sidekiq/wiki/Kubernetes#sidekiq
|
||||
ready_filename = ENV.fetch('MASTODON_SIDEKIQ_READY_FILENAME', nil)
|
||||
if ready_filename
|
||||
raise 'MASTODON_SIDEKIQ_READY_FILENAME is not a valid filename' if File.basename(ready_filename) != ready_filename
|
||||
|
||||
ready_path = Rails.root.join('tmp', ready_filename)
|
||||
|
||||
config.on(:startup) do
|
||||
FileUtils.touch(ready_path)
|
||||
end
|
||||
|
||||
config.on(:shutdown) do
|
||||
FileUtils.rm_f(ready_path)
|
||||
end
|
||||
end
|
||||
|
||||
config.server_middleware do |chain|
|
||||
chain.add Mastodon::SidekiqMiddleware
|
||||
|
@ -22,11 +34,24 @@ Sidekiq.configure_server do |config|
|
|||
chain.add SidekiqUniqueJobs::Middleware::Client
|
||||
end
|
||||
|
||||
config.on(:startup) do
|
||||
if SelfDestructHelper.self_destruct?
|
||||
Sidekiq.schedule = {
|
||||
'self_destruct_scheduler' => {
|
||||
'interval' => ['1m'],
|
||||
'class' => 'Scheduler::SelfDestructScheduler',
|
||||
'queue' => 'scheduler',
|
||||
},
|
||||
}
|
||||
SidekiqScheduler::Scheduler.instance.reload_schedule!
|
||||
end
|
||||
end
|
||||
|
||||
SidekiqUniqueJobs::Server.configure(config)
|
||||
end
|
||||
|
||||
Sidekiq.configure_client do |config|
|
||||
config.redis = REDIS_SIDEKIQ_PARAMS
|
||||
config.redis = REDIS_CONFIGURATION.sidekiq
|
||||
|
||||
config.client_middleware do |chain|
|
||||
chain.add SidekiqUniqueJobs::Middleware::Client
|
||||
|
@ -36,6 +61,7 @@ end
|
|||
Sidekiq.logger.level = ::Logger.const_get(ENV.fetch('RAILS_LOG_LEVEL', 'info').upcase.to_s)
|
||||
|
||||
SidekiqUniqueJobs.configure do |config|
|
||||
config.enabled = !Rails.env.test?
|
||||
config.reaper = :ruby
|
||||
config.reaper_count = 1000
|
||||
config.reaper_interval = 600
|
||||
|
|
19
config/initializers/simple_cov_source_file.rb
Normal file
19
config/initializers/simple_cov_source_file.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# TODO: https://github.com/simplecov-ruby/simplecov/pull/1084
|
||||
# Patches this missing condition, monitor for upstream fix
|
||||
|
||||
module SimpleCov
|
||||
module SourceFileExtensions
|
||||
def build_branches
|
||||
coverage_branch_data = coverage_data.fetch('branches', {}) || {} # Add the final empty hash in case where 'branches' is present, but returns nil
|
||||
branches = coverage_branch_data.flat_map do |condition, coverage_branches|
|
||||
build_branches_from(condition, coverage_branches)
|
||||
end
|
||||
|
||||
process_skipped_branches(branches)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SimpleCov::SourceFile.prepend(SimpleCov::SourceFileExtensions) if defined?(SimpleCov::SourceFile)
|
|
@ -164,7 +164,7 @@ SimpleForm.setup do |config|
|
|||
# config.item_wrapper_class = nil
|
||||
|
||||
# How the label text should be generated altogether with the required text.
|
||||
config.label_text = lambda { |label, required, explicit_label| "#{label} #{required}" }
|
||||
config.label_text = ->(label, required, _explicit_label) { "#{label} #{required}" }
|
||||
|
||||
# You can define the class to use on all labels. Default is nil.
|
||||
# config.label_class = nil
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
if ENV['STATSD_ADDR'].present?
|
||||
host, port = ENV['STATSD_ADDR'].split(':')
|
||||
|
||||
begin
|
||||
statsd = Statsd.new(host, port)
|
||||
statsd.namespace = ENV.fetch('STATSD_NAMESPACE') { ['Mastodon', Rails.env].join('.') }
|
||||
|
||||
NSA.inform_statsd(statsd) do |informant|
|
||||
informant.collect(:action_controller, :web)
|
||||
informant.collect(:active_record, :db)
|
||||
informant.collect(:active_support_cache, :cache)
|
||||
informant.collect(:sidekiq, :sidekiq) if ENV['STATSD_SIDEKIQ'] == 'true'
|
||||
end
|
||||
rescue
|
||||
Rails.logger.warn("statsd address #{ENV['STATSD_ADDR']} not reachable, proceeding without statsd")
|
||||
end
|
||||
end
|
|
@ -3,6 +3,6 @@
|
|||
require 'stoplight'
|
||||
|
||||
Rails.application.reloader.to_prepare do
|
||||
Stoplight::Light.default_data_store = Stoplight::DataStore::Redis.new(RedisConfiguration.new.connection)
|
||||
Stoplight::Light.default_notifiers = [Stoplight::Notifier::Logger.new(Rails.logger)]
|
||||
Stoplight.default_data_store = Stoplight::DataStore::Redis.new(RedisConnection.new.connection)
|
||||
Stoplight.default_notifiers = [Stoplight::Notifier::Logger.new(Rails.logger)]
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
StrongMigrations.start_after = 2017_09_24_022025
|
||||
StrongMigrations.target_version = 10
|
||||
StrongMigrations.target_version = 12
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Rack
|
||||
class Request
|
||||
def trusted_proxy?(ip)
|
||||
if Rails.application.config.action_dispatch.trusted_proxies.nil?
|
||||
super
|
||||
else
|
||||
Rails.application.config.action_dispatch.trusted_proxies.any? { |proxy| proxy === ip }
|
||||
end
|
||||
end
|
||||
end
|
||||
unless Rails.application.config.action_dispatch.trusted_proxies.nil?
|
||||
# Rack is configured with a default collection of trusted proxies
|
||||
# If Rails has been configured to use a specific list, configure
|
||||
# Rack to use this Proc, which enforces the Rails-configured list.
|
||||
Rack::Request.ip_filter = ->(ip) { Rails.application.config.action_dispatch.trusted_proxies.include?(ip) }
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ module Twitter::TwitterText
|
|||
|
||||
class Regex
|
||||
REGEXEN[:valid_general_url_path_chars] = /[^\p{White_Space}<>()?]/iou
|
||||
REGEXEN[:valid_url_path_ending_chars] = /[^\p{White_Space}()?!*"'「」<>;:=,.$%\[\]~&|@]|(?:#{REGEXEN[:valid_url_balanced_parens]})/iou
|
||||
REGEXEN[:valid_url_path_ending_chars] = /[^\p{White_Space}()?!*"'「」<>;:=,.$%\[\]~&|]|(?:#{REGEXEN[:valid_url_balanced_parens]})/iou
|
||||
REGEXEN[:valid_url_balanced_parens] = /
|
||||
\(
|
||||
(?:
|
||||
|
|
|
@ -5,7 +5,7 @@ Rails.application.configure do
|
|||
# You should only generate this once per instance. If you later decide to change it, all push subscription will
|
||||
# be invalidated, requiring the users to access the website again to resubscribe.
|
||||
#
|
||||
# Generate with `rake mastodon:webpush:generate_vapid_key` task (`docker-compose run --rm web rake mastodon:webpush:generate_vapid_key` if you use docker compose)
|
||||
# Generate with `bundle exec rails mastodon:webpush:generate_vapid_key` task (`docker-compose run --rm web bundle exec rails mastodon:webpush:generate_vapid_key` if you use docker compose)
|
||||
#
|
||||
# For more information visit https://rossta.net/blog/using-the-web-push-api-with-vapid.html
|
||||
|
||||
|
|
39
config/initializers/vips.rb
Normal file
39
config/initializers/vips.rb
Normal file
|
@ -0,0 +1,39 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
if Rails.configuration.x.use_vips
|
||||
ENV['VIPS_BLOCK_UNTRUSTED'] = 'true'
|
||||
|
||||
require 'vips'
|
||||
|
||||
unless Vips.at_least_libvips?(8, 13)
|
||||
abort <<~ERROR.squish
|
||||
Incompatible libvips version (#{Vips.version_string}), please install libvips >= 8.13
|
||||
ERROR
|
||||
end
|
||||
|
||||
Vips.block('VipsForeign', true)
|
||||
|
||||
%w(
|
||||
VipsForeignLoadNsgif
|
||||
VipsForeignLoadJpeg
|
||||
VipsForeignLoadPng
|
||||
VipsForeignLoadWebp
|
||||
VipsForeignLoadHeif
|
||||
VipsForeignSavePng
|
||||
VipsForeignSaveSpng
|
||||
VipsForeignSaveJpeg
|
||||
VipsForeignSaveWebp
|
||||
).each do |operation|
|
||||
Vips.block(operation, false)
|
||||
end
|
||||
|
||||
Vips.block_untrusted(true)
|
||||
end
|
||||
|
||||
# In some places of the code, we rescue this exception, but we don't always
|
||||
# load libvips, so it may be an undefined constant:
|
||||
unless defined?(Vips)
|
||||
module Vips
|
||||
class Error < StandardError; end
|
||||
end
|
||||
end
|
|
@ -6,7 +6,7 @@ WebAuthn.configure do |config|
|
|||
config.origin = "#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}"
|
||||
|
||||
# Relying Party name for display purposes
|
||||
config.rp_name = "Mastodon"
|
||||
config.rp_name = 'Mastodon'
|
||||
|
||||
# Optionally configure a client timeout hint, in milliseconds.
|
||||
# This hint specifies how long the browser should wait for an
|
||||
|
|
|
@ -53,3 +53,7 @@ af:
|
|||
position:
|
||||
elevated: kan nie hoër as jou huidige rol wees nie
|
||||
own_role: kan nie verander word met jou huidige rol nie
|
||||
webhook:
|
||||
attributes:
|
||||
events:
|
||||
invalid_permissions: geleenthede waartoe jy nie toegang het nie mag nie ingesluit word nie
|
||||
|
|
|
@ -18,7 +18,7 @@ ast:
|
|||
account:
|
||||
attributes:
|
||||
username:
|
||||
invalid: ha contener namás lletres, númberos ya guiones baxos
|
||||
invalid: ha contener namás lletres, númberos y guiones baxos
|
||||
reserved: ta acutáu
|
||||
admin/webhook:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,8 @@ be:
|
|||
user/invite_request:
|
||||
text: Прычына
|
||||
errors:
|
||||
messages:
|
||||
too_many_lines: перавышана абмежаванне ў %{limit} радкоў
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ bg:
|
|||
user/invite_request:
|
||||
text: Причина
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: не е действително име на домейн
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} не е действително име на домейн"
|
||||
too_many_lines: е над ограничение от %{limit} реда
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ ca:
|
|||
user/invite_request:
|
||||
text: Motiu
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: no és un nom de domini vàlid
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} no és un nom de domini vàlid"
|
||||
too_many_lines: sobrepassa el límit de %{limit} línies
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ cy:
|
|||
user/invite_request:
|
||||
text: Rheswm
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: "- nid yw'n enw parth dilys"
|
||||
messages:
|
||||
invalid_domain_on_line: Nid yw %{value} yn enw parth dilys
|
||||
too_many_lines: "- dros y terfyn o %{limit} llinell"
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ da:
|
|||
user/invite_request:
|
||||
text: Årsag
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: er ikke et gyldigt domænenavn
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} er ikke et gyldigt domænenavn"
|
||||
too_many_lines: overstiger grænsen på %{limit} linjer
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ de:
|
|||
user/invite_request:
|
||||
text: Begründung
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: ist kein gültiger Domain-Name
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} ist kein gültiger Domain-Name"
|
||||
too_many_lines: übersteigt das Limit von %{limit} Zeilen
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ el:
|
|||
user/invite_request:
|
||||
text: Αιτιολογία
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: δεν είναι έγκυρο όνομα τομέα
|
||||
messages:
|
||||
invalid_domain_on_line: το %{value} δεν είναι έγκυρο όνομα τομέα
|
||||
too_many_lines: υπερβαίνει το όριο των %{limit} γραμμών
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
@ -36,14 +42,14 @@ el:
|
|||
status:
|
||||
attributes:
|
||||
reblog:
|
||||
taken: της κατάστασης ήδη υπάρχει
|
||||
taken: της ανάρτησης υπάρχει ήδη
|
||||
user:
|
||||
attributes:
|
||||
email:
|
||||
blocked: χρησιμοποιεί μη επιτρεπόμενο πάροχο e-mail
|
||||
unreachable: δεν φαίνεται να υπάρχει
|
||||
role_id:
|
||||
elevated: δεν μπορεί να είναι μεγαλύτερο από τον τρέχοντα ρόλο σας
|
||||
elevated: δεν μπορεί να είναι υψηλότερο από τον τρέχοντα ρόλο σου
|
||||
user_role:
|
||||
attributes:
|
||||
permissions_as_keys:
|
||||
|
@ -53,3 +59,7 @@ el:
|
|||
position:
|
||||
elevated: δεν μπορεί να είναι μεγαλύτερο από τον τρέχοντα ρόλο σας
|
||||
own_role: δεν μπορεί να αλλάξει με τον τρέχοντα ρόλο σας
|
||||
webhook:
|
||||
attributes:
|
||||
events:
|
||||
invalid_permissions: δεν μπορείτε να συμπεριλάβετε συμβάντα για τα οποία δεν έχετε τα δικαιώματα
|
||||
|
|
|
@ -15,6 +15,12 @@ en-GB:
|
|||
user/invite_request:
|
||||
text: Reason
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: is not a valid domain name
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} is not a valid domain name"
|
||||
too_many_lines: is over the limit of %{limit} lines
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ en:
|
|||
user/invite_request:
|
||||
text: Reason
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: is not a valid domain name
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} is not a valid domain name"
|
||||
too_many_lines: is over the limit of %{limit} lines
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ eo:
|
|||
user/invite_request:
|
||||
text: Kialo
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: ne estas valida domajna nomo
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} ne estas valida domajna nomo"
|
||||
too_many_lines: superas la limon de %{limit} linioj
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ es-AR:
|
|||
user/invite_request:
|
||||
text: Motivo
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: no es un nombre de dominio válido
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} no es un nombre de dominio válido"
|
||||
too_many_lines: está por encima del límite de %{limit} líneas
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ es-MX:
|
|||
user/invite_request:
|
||||
text: Motivo
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: no es un nombre de dominio válido
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} no es un nombre de dominio válido"
|
||||
too_many_lines: excede el límite de %{limit} líneas
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ es:
|
|||
user/invite_request:
|
||||
text: Razón
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: no es un nombre de dominio válido
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} no es un nombre de dominio válido"
|
||||
too_many_lines: excede el límite de %{limit} líneas
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
@ -56,4 +62,4 @@ es:
|
|||
webhook:
|
||||
attributes:
|
||||
events:
|
||||
invalid_permissions: no se pueden incluir eventos para los que no tienes derechos
|
||||
invalid_permissions: no puede incluir eventos para los que no tienes permisos
|
||||
|
|
|
@ -15,6 +15,12 @@ et:
|
|||
user/invite_request:
|
||||
text: Põhjus
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: pole kehtiv domeeninimi
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} ei ole kehtiv domeeninimi"
|
||||
too_many_lines: on üle limiidi %{limit} rida
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -19,7 +19,7 @@ eu:
|
|||
account:
|
||||
attributes:
|
||||
username:
|
||||
invalid: letrak, zenbakiak eta gidoi baxuak besterik ez
|
||||
invalid: letrak, zenbakiak eta azpimarrak soilik izan behar ditu
|
||||
reserved: erreserbatuta dago
|
||||
admin/webhook:
|
||||
attributes:
|
||||
|
|
|
@ -4,17 +4,23 @@ fi:
|
|||
attributes:
|
||||
poll:
|
||||
expires_at: Määräaika
|
||||
options: Valinnat
|
||||
options: Vaihtoehdot
|
||||
user:
|
||||
agreement: Palvelusopimus
|
||||
email: Sähköpostiosoite
|
||||
locale: Alue
|
||||
password: Salasana
|
||||
user/account:
|
||||
username: Käyttäjätunnus
|
||||
username: Käyttäjänimi
|
||||
user/invite_request:
|
||||
text: Syy
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: ei ole kelvollinen verkkotunnus
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} ei ole kelvollinen verkkotunnus"
|
||||
too_many_lines: ylittää %{limit} rivin rajan
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
@ -28,7 +34,7 @@ fi:
|
|||
doorkeeper/application:
|
||||
attributes:
|
||||
website:
|
||||
invalid: ei ole kelvollinen verkko-osoite
|
||||
invalid: ei ole kelvollinen URL-osoite
|
||||
import:
|
||||
attributes:
|
||||
data:
|
||||
|
@ -36,19 +42,19 @@ fi:
|
|||
status:
|
||||
attributes:
|
||||
reblog:
|
||||
taken: tila on jo olemassa
|
||||
taken: tästä julkaisusta on jo tehty
|
||||
user:
|
||||
attributes:
|
||||
email:
|
||||
blocked: käyttää kiellettyä sähköpostipalvelun tarjoajaa
|
||||
blocked: käyttää kiellettyä sähköpostipalveluntarjoajaa
|
||||
unreachable: ei näytä olevan olemassa
|
||||
role_id:
|
||||
elevated: ei voi olla korkeampi kuin nykyinen roolisi
|
||||
user_role:
|
||||
attributes:
|
||||
permissions_as_keys:
|
||||
dangerous: sisältää oikeudet, jotka eivät ole turvallisia perusroolille
|
||||
elevated: ei voi sisältää oikeuksia, joita nykyisellä roolillasi ei ole
|
||||
dangerous: sisällytä käyttöoikeuksia, jotka eivät ole turvallisia perusroolille
|
||||
elevated: ei voi sisältää käyttöoikeuksia, joita nykyisellä roolillasi ei ole
|
||||
own_role: ei voi muuttaa nykyisellä roolillasi
|
||||
position:
|
||||
elevated: ei voi olla korkeampi kuin nykyinen roolisi
|
||||
|
|
1
config/locales/activerecord.fil.yml
Normal file
1
config/locales/activerecord.fil.yml
Normal file
|
@ -0,0 +1 @@
|
|||
fil:
|
|
@ -15,6 +15,12 @@ fo:
|
|||
user/invite_request:
|
||||
text: Orsøk
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: er ikki eitt virkið økisnavn
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} er ikki eitt virkið økisnavn"
|
||||
too_many_lines: er longri enn markið á %{limit} reglur
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
fr-QC:
|
||||
fr-CA:
|
||||
activerecord:
|
||||
attributes:
|
||||
poll:
|
||||
|
@ -15,6 +15,12 @@ fr-QC:
|
|||
user/invite_request:
|
||||
text: Raison
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: n'est pas un nom de domaine valide
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} n'est pas un nom de domaine valide"
|
||||
too_many_lines: dépasse la limite de %{limit} lignes
|
||||
models:
|
||||
account:
|
||||
attributes:
|
|
@ -15,6 +15,12 @@ fr:
|
|||
user/invite_request:
|
||||
text: Motif
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: n'est pas un nom de domaine valide
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} n'est pas un nom de domaine valide"
|
||||
too_many_lines: dépasse la limite de %{limit} lignes
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,12 +15,51 @@ ga:
|
|||
user/invite_request:
|
||||
text: Fáth
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: nach ainm fearainn bailí é
|
||||
messages:
|
||||
invalid_domain_on_line: Ní ainm fearainn bailí é %{value}
|
||||
too_many_lines: thar an teorainn de %{limit} línte
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
username:
|
||||
invalid: ní mór go mbeadh litreacha, uimhreacha agus pointí béime amháin
|
||||
reserved: in áirithe
|
||||
admin/webhook:
|
||||
attributes:
|
||||
url:
|
||||
invalid: nach URL bailí é
|
||||
doorkeeper/application:
|
||||
attributes:
|
||||
website:
|
||||
invalid: nach URL bailí é
|
||||
import:
|
||||
attributes:
|
||||
data:
|
||||
malformed: míchumtha
|
||||
status:
|
||||
attributes:
|
||||
reblog:
|
||||
taken: den phost cheana féin
|
||||
user:
|
||||
attributes:
|
||||
email:
|
||||
blocked: úsáideann soláthraí ríomhphoist dícheadaithe
|
||||
unreachable: ní cosúil go bhfuil sé ann
|
||||
role_id:
|
||||
elevated: ní féidir leat a bheith níos airde ná do ról reatha
|
||||
user_role:
|
||||
attributes:
|
||||
permissions_as_keys:
|
||||
dangerous: cuir san áireamh ceadanna nach bhfuil sábháilte don ról bunúsach
|
||||
elevated: ní féidir ceadanna nach bhfuil ag do ról reatha a áireamh
|
||||
own_role: ní féidir é a athrú le do ról reatha
|
||||
position:
|
||||
elevated: ní féidir leat a bheith níos airde ná do ról reatha
|
||||
own_role: ní féidir é a athrú le do ról reatha
|
||||
webhook:
|
||||
attributes:
|
||||
events:
|
||||
invalid_permissions: ní féidir imeachtaí nach bhfuil na cearta agat ina leith a chur san áireamh
|
||||
|
|
|
@ -15,6 +15,12 @@ gd:
|
|||
user/invite_request:
|
||||
text: Adhbhar
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: "– chan eil seo ’na ainm àrainne dligheach"
|
||||
messages:
|
||||
invalid_domain_on_line: Chan eil %{value} ’na ainm àrainne dligheach
|
||||
too_many_lines: "– tha seo thar crìoch de %{limit} nan loidhnichean"
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ gl:
|
|||
user/invite_request:
|
||||
text: Razón
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: non é un nome de dominio válido
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} non é un nome de dominio válido"
|
||||
too_many_lines: superou o límite de %{limit} liñas
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -9,12 +9,18 @@ he:
|
|||
agreement: הסכם שירות
|
||||
email: כתובת דוא"ל
|
||||
locale: הגדרות אזוריות
|
||||
password: סיסמא
|
||||
password: סיסמה
|
||||
user/account:
|
||||
username: שם משתמש/ת
|
||||
user/invite_request:
|
||||
text: סיבה
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: אינו שם מתחם קביל
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} אינו שם מתחם קביל"
|
||||
too_many_lines: מעבר למגבלה של %{limit} שורות
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -6,7 +6,9 @@ hr:
|
|||
expires_at: Krajnji rok
|
||||
options: Opcije
|
||||
user:
|
||||
agreement: Ugovor o uslugama
|
||||
email: E-mail adresa
|
||||
locale: Lokalitet
|
||||
password: Lozinka
|
||||
user/account:
|
||||
username: Korisničko ime
|
||||
|
@ -18,3 +20,16 @@ hr:
|
|||
attributes:
|
||||
username:
|
||||
invalid: mora sadržavati samo slova, brojeve i _
|
||||
reserved: je rezervisano
|
||||
admin/webhook:
|
||||
attributes:
|
||||
url:
|
||||
invalid: nije validan URL
|
||||
doorkeeper/application:
|
||||
attributes:
|
||||
website:
|
||||
invalid: nije validan URL
|
||||
import:
|
||||
attributes:
|
||||
data:
|
||||
malformed: je neispravan
|
||||
|
|
|
@ -15,12 +15,18 @@ hu:
|
|||
user/invite_request:
|
||||
text: Indoklás
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: nem egy érvényes domain név
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} nem egy érvényes domain név"
|
||||
too_many_lines: túllépi a(z) %{limit} soros korlátot
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
username:
|
||||
invalid: csak betűket, számokat vagy alávonást tartalmazhat
|
||||
reserved: fenntartott
|
||||
reserved: foglalt
|
||||
admin/webhook:
|
||||
attributes:
|
||||
url:
|
||||
|
|
64
config/locales/activerecord.ia.yml
Normal file
64
config/locales/activerecord.ia.yml
Normal file
|
@ -0,0 +1,64 @@
|
|||
---
|
||||
ia:
|
||||
activerecord:
|
||||
attributes:
|
||||
poll:
|
||||
expires_at: Data limite
|
||||
options: Optiones
|
||||
user:
|
||||
agreement: Accordo de servicio
|
||||
email: Adresse de e-mail
|
||||
locale: Region
|
||||
password: Contrasigno
|
||||
user/account:
|
||||
username: Nomine de usator
|
||||
user/invite_request:
|
||||
text: Motivo
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: non es un nomine de dominio valide
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} non es un nomine de dominio valide"
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
username:
|
||||
invalid: debe continer solmente litteras, numeros e lineettas basse
|
||||
reserved: es reservate
|
||||
admin/webhook:
|
||||
attributes:
|
||||
url:
|
||||
invalid: non es un URL valide
|
||||
doorkeeper/application:
|
||||
attributes:
|
||||
website:
|
||||
invalid: non es un URL valide
|
||||
import:
|
||||
attributes:
|
||||
data:
|
||||
malformed: es mal formate
|
||||
status:
|
||||
attributes:
|
||||
reblog:
|
||||
taken: del message jam existe
|
||||
user:
|
||||
attributes:
|
||||
email:
|
||||
blocked: usa un fornitor de e-mail prohibite
|
||||
unreachable: non pare exister
|
||||
role_id:
|
||||
elevated: non pote esser superior a tu rolo actual
|
||||
user_role:
|
||||
attributes:
|
||||
permissions_as_keys:
|
||||
dangerous: includer permissiones non secur pro le rolo de base
|
||||
elevated: non pote includer permissiones que tu rolo actual non possede
|
||||
own_role: non pote esser cambiate con tu rolo actual
|
||||
position:
|
||||
elevated: non pote esser superior a tu rolo actual
|
||||
own_role: non pote esser cambiate con tu rolo actual
|
||||
webhook:
|
||||
attributes:
|
||||
events:
|
||||
invalid_permissions: non pote includer eventos pro le quales tu non ha le derectos
|
59
config/locales/activerecord.ie.yml
Normal file
59
config/locales/activerecord.ie.yml
Normal file
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
ie:
|
||||
activerecord:
|
||||
attributes:
|
||||
poll:
|
||||
expires_at: Cludent date
|
||||
options: Optiones
|
||||
user:
|
||||
agreement: Acorde de servicie
|
||||
email: E-posta
|
||||
locale: Local
|
||||
password: Passa-parol
|
||||
user/account:
|
||||
username: Nómine del usator
|
||||
user/invite_request:
|
||||
text: Rason
|
||||
errors:
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
username:
|
||||
invalid: deve contener solmen lítteres, númeres e sublineas
|
||||
reserved: es reservat
|
||||
admin/webhook:
|
||||
attributes:
|
||||
url:
|
||||
invalid: ne es un valid URL
|
||||
doorkeeper/application:
|
||||
attributes:
|
||||
website:
|
||||
invalid: ne es un valid URL
|
||||
import:
|
||||
attributes:
|
||||
data:
|
||||
malformed: es malformat
|
||||
status:
|
||||
attributes:
|
||||
reblog:
|
||||
taken: de posta ja existe
|
||||
user:
|
||||
attributes:
|
||||
email:
|
||||
blocked: usa un ne-permisset provisor de e-posta
|
||||
unreachable: sembla ne exister
|
||||
role_id:
|
||||
elevated: ne posse esser plu alt quam tui actual rol
|
||||
user_role:
|
||||
attributes:
|
||||
permissions_as_keys:
|
||||
dangerous: include permissones ne secur por li rol de base
|
||||
elevated: ne posse includer permissiones ne possedet de tui rol actual
|
||||
own_role: ne posse esser changeat con tui actual rol
|
||||
position:
|
||||
elevated: ne posse esser plu alt quam tui actual rol
|
||||
own_role: ne posse esser changeat con tui actual rol
|
||||
webhook:
|
||||
attributes:
|
||||
events:
|
||||
invalid_permissions: ne posse includer evenimentes por queles tu ne have li yures
|
|
@ -15,6 +15,12 @@ io:
|
|||
user/invite_request:
|
||||
text: Rezono
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: ne esas valida domennomo
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} ne esas valida domennomo"
|
||||
too_many_lines: esas plu kam la limito qua esas %{limit} linei
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ is:
|
|||
user/invite_request:
|
||||
text: Ástæða
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: er ekki leyfilegt nafn á léni
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} er ekki leyfilegt nafn á léni"
|
||||
too_many_lines: er yfir takmörkum á %{limit} línum
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ it:
|
|||
user/invite_request:
|
||||
text: Motivo
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: non è un nome di dominio valido
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} non è un nome di dominio valido"
|
||||
too_many_lines: è oltre il limite di %{limit} righe
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -19,8 +19,20 @@ kab:
|
|||
account:
|
||||
attributes:
|
||||
username:
|
||||
invalid: isekkilen, uṭṭunen d yijerriden n wadda kan
|
||||
invalid: ilaq ad ilin isekkilen, uṭṭunen d yijerriden n wadda kan
|
||||
reserved: yettwaṭṭef
|
||||
admin/webhook:
|
||||
attributes:
|
||||
url:
|
||||
invalid: mačči d URL ameɣtu
|
||||
doorkeeper/application:
|
||||
attributes:
|
||||
website:
|
||||
invalid: mačči d URL ameɣtu
|
||||
import:
|
||||
attributes:
|
||||
data:
|
||||
malformed: yir amsal
|
||||
status:
|
||||
attributes:
|
||||
reblog:
|
||||
|
@ -28,4 +40,20 @@ kab:
|
|||
user:
|
||||
attributes:
|
||||
email:
|
||||
blocked: isseqdac asaǧǧaw n yimayl ur yettusirgen ara
|
||||
unreachable: ur d-ttban ara d akken yella
|
||||
role_id:
|
||||
elevated: ur yezmir ara ad iεeddi tamlilt-ik tamirant
|
||||
user_role:
|
||||
attributes:
|
||||
permissions_as_keys:
|
||||
dangerous: deg-s tisirag tiriɣelsanin i temlilt tazadurt
|
||||
elevated: ur yezmir ara ad yesεu tirirag ur nelli ara deg temlilit-ik tamirant
|
||||
own_role: ur yezmir ara ad yettwabeddel s temlilt-ik tamirant
|
||||
position:
|
||||
elevated: ur yezmir ara ad iεeddi tamlilt-ik tamirant
|
||||
own_role: ur yezmir ara ad yettwabeddel s temlilt-ik tamirant
|
||||
webhook:
|
||||
attributes:
|
||||
events:
|
||||
invalid_permissions: ur yezmir ara ad yesεu tidyanin iwumi ur tesεiḍ ara tisirag
|
||||
|
|
|
@ -15,6 +15,12 @@ ko:
|
|||
user/invite_request:
|
||||
text: 이유
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: 올바른 도메인 네임이 아닙니다
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value}는 올바른 도메인 네임이 아닙니다"
|
||||
too_many_lines: "%{limit}줄 제한을 초과합니다"
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
59
config/locales/activerecord.lad.yml
Normal file
59
config/locales/activerecord.lad.yml
Normal file
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
lad:
|
||||
activerecord:
|
||||
attributes:
|
||||
poll:
|
||||
expires_at: Limito temporal
|
||||
options: Opsyones
|
||||
user:
|
||||
agreement: Akodro de servisyo
|
||||
email: Adreso de posta elektronika
|
||||
locale: Lingua
|
||||
password: Kod
|
||||
user/account:
|
||||
username: Nombre de utilizador
|
||||
user/invite_request:
|
||||
text: Razon
|
||||
errors:
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
username:
|
||||
invalid: solo puede kontener letras, shifras i sulinyados
|
||||
reserved: esta rezervado
|
||||
admin/webhook:
|
||||
attributes:
|
||||
url:
|
||||
invalid: no es adreso URL valido
|
||||
doorkeeper/application:
|
||||
attributes:
|
||||
website:
|
||||
invalid: no es adreso URL valido
|
||||
import:
|
||||
attributes:
|
||||
data:
|
||||
malformed: tiene formato yerrado
|
||||
status:
|
||||
attributes:
|
||||
reblog:
|
||||
taken: de publikasyon ya existe
|
||||
user:
|
||||
attributes:
|
||||
email:
|
||||
blocked: uza un prokurador de posta no autorizado
|
||||
unreachable: no parese existir
|
||||
role_id:
|
||||
elevated: no puede ser mas alto ke tu rolo aktual
|
||||
user_role:
|
||||
attributes:
|
||||
permissions_as_keys:
|
||||
dangerous: inkluir permisos ke no son siguros para el rolo de baza
|
||||
elevated: no se puede inkluir permisos kualos no tiene tu rolo aktual
|
||||
own_role: no se puede trokar kon tu rolo aktual
|
||||
position:
|
||||
elevated: no puede ser mas alto ke tu rolo aktual
|
||||
own_role: no se puede trokar kon tu rolo aktual
|
||||
webhook:
|
||||
attributes:
|
||||
events:
|
||||
invalid_permissions: no puedes inkluir evenimientos a los kualos no estas autorizado
|
|
@ -1 +1,65 @@
|
|||
---
|
||||
lt:
|
||||
activerecord:
|
||||
attributes:
|
||||
poll:
|
||||
expires_at: Galutinė data
|
||||
options: Pasirinkimai
|
||||
user:
|
||||
agreement: Paslaugos sutartis
|
||||
email: El. laiško adresas
|
||||
locale: Lokali
|
||||
password: Slaptažodis
|
||||
user/account:
|
||||
username: Naudotojo vardas
|
||||
user/invite_request:
|
||||
text: Priežastis
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: nėra tinkamas domeno vardas.
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} nėra tinkamas domeno vardas."
|
||||
too_many_lines: yra daugiau nei %{limit} eilučių ribojimą.
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
username:
|
||||
invalid: turi būti tik raidės, skaičiai ir pabraukimai.
|
||||
reserved: užimtas.
|
||||
admin/webhook:
|
||||
attributes:
|
||||
url:
|
||||
invalid: nėra tinkamas URL adresas.
|
||||
doorkeeper/application:
|
||||
attributes:
|
||||
website:
|
||||
invalid: nėra tinkamas URL adresas.
|
||||
import:
|
||||
attributes:
|
||||
data:
|
||||
malformed: yra netaisyklinga.
|
||||
status:
|
||||
attributes:
|
||||
reblog:
|
||||
taken: įrašas jau egzistuoja.
|
||||
user:
|
||||
attributes:
|
||||
email:
|
||||
blocked: naudoja neleidžiamą el. laiško paslaugų teikėją.
|
||||
unreachable: neatrodo, kad egzistuoja.
|
||||
role_id:
|
||||
elevated: negali būti didesnis nei tavo dabartinis vaidmuo.
|
||||
user_role:
|
||||
attributes:
|
||||
permissions_as_keys:
|
||||
dangerous: apima leidimus, kurie nėra saugūs pagrindiniam vaidmeniui.
|
||||
elevated: negali apimti leidimų, kurių neturi tavo dabartinis vaidmuo.
|
||||
own_role: negali būti pakeistas tavo dabartinis vaidmuo.
|
||||
position:
|
||||
elevated: negali būti didesnis nei tavo dabartinis vaidmuo.
|
||||
own_role: negali būti pakeistas tavo dabartinis vaidmuo.
|
||||
webhook:
|
||||
attributes:
|
||||
events:
|
||||
invalid_permissions: negali įtraukti įvykių, į kuriuos neturi teisių.
|
||||
|
|
|
@ -15,6 +15,12 @@ lv:
|
|||
user/invite_request:
|
||||
text: Iemesls
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: nav derīgs domēna nosaukums
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} nav derīgs domēna nosaukums"
|
||||
too_many_lines: pārsniedz %{limit} līniju ierobežojumu
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
1
config/locales/activerecord.ne.yml
Normal file
1
config/locales/activerecord.ne.yml
Normal file
|
@ -0,0 +1 @@
|
|||
ne:
|
|
@ -15,6 +15,12 @@ nl:
|
|||
user/invite_request:
|
||||
text: Reden
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: is een ongeldige domeinnaam
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} is een ongeldige domeinnaam"
|
||||
too_many_lines: overschrijdt de limiet van %{limit} regels
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ nn:
|
|||
user/invite_request:
|
||||
text: Grunn
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: er ikkje eit gyldig domenenamn
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} er ikkje gyldig i eit domenenamn"
|
||||
too_many_lines: er over grensa på %{limit} liner
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -1 +1,23 @@
|
|||
---
|
||||
pa:
|
||||
activerecord:
|
||||
attributes:
|
||||
poll:
|
||||
expires_at: ਆਖਰੀ ਤਾਰੀਖ
|
||||
options: ਚੋਣਾਂ
|
||||
user:
|
||||
agreement: ਸੇਵਾ ਸਮਝੌਤਾ
|
||||
email: ਈਮੇਲ ਪਤਾ
|
||||
locale: ਲੋਕੇਲ
|
||||
password: ਪਾਸਵਰਡ
|
||||
user/account:
|
||||
username: ਵਰਤੋਂਕਾਰ-ਨਾਂ
|
||||
user/invite_request:
|
||||
text: ਕਾਰਨ
|
||||
errors:
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
username:
|
||||
invalid: ਸਿਰਫ਼ ਅੱਖਰ, ਅੰਕ ਅਤੇ ਹੇਠਾਂ-ਰੇਖਾ ਹੀ ਹੋੋਣੀ ਚਾਹੀਦੀ ਹੈ
|
||||
reserved: ਰਾਖਵਾਂ ਹੈ
|
||||
|
|
|
@ -15,6 +15,12 @@ pl:
|
|||
user/invite_request:
|
||||
text: Powód
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: nie jest prawidłową nazwą domeny
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} nie jest prawidłową nazwą domeny"
|
||||
too_many_lines: przekracza limit %{limit} linii
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
|
|
@ -15,6 +15,12 @@ pt-BR:
|
|||
user/invite_request:
|
||||
text: Razão
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: não é um nome de domínio válido
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} não é um nome de domínio válido"
|
||||
too_many_lines: está acima do limite de %{limit} linhas
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
@ -32,7 +38,7 @@ pt-BR:
|
|||
import:
|
||||
attributes:
|
||||
data:
|
||||
malformed: está incorreto
|
||||
malformed: está malformado
|
||||
status:
|
||||
attributes:
|
||||
reblog:
|
||||
|
@ -43,16 +49,16 @@ pt-BR:
|
|||
blocked: usa provedor de e-mail não permitido
|
||||
unreachable: parece não existir
|
||||
role_id:
|
||||
elevated: não pode ser maior que seu cargo atual
|
||||
elevated: não pode maior que sua função atual
|
||||
user_role:
|
||||
attributes:
|
||||
permissions_as_keys:
|
||||
dangerous: incluir permissões que não são seguras para o cargo base
|
||||
elevated: não pode incluir permissões que o seu cargo atual não possui
|
||||
own_role: não pode ser alterado com seu cargo atual
|
||||
dangerous: incluir permissões que não são seguras para a função base
|
||||
elevated: não pode incluir permissões que a sua função atual não possui
|
||||
own_role: não pode ser alterado com sua função atual
|
||||
position:
|
||||
elevated: não pode ser maior do que seu cargo atual
|
||||
own_role: não pode ser alterado com seu cargo atual
|
||||
elevated: não pode ser maior do que sua função atual
|
||||
own_role: não pode ser alterado com sua função atual
|
||||
webhook:
|
||||
attributes:
|
||||
events:
|
||||
|
|
|
@ -6,7 +6,7 @@ pt-PT:
|
|||
expires_at: Prazo
|
||||
options: Escolhas
|
||||
user:
|
||||
agreement: Acordo de serviço
|
||||
agreement: Contrato de prestação de serviço
|
||||
email: Endereço de correio electrónico
|
||||
locale: Região
|
||||
password: Palavra-passe
|
||||
|
@ -19,7 +19,7 @@ pt-PT:
|
|||
account:
|
||||
attributes:
|
||||
username:
|
||||
invalid: apenas letras, números e underscores
|
||||
invalid: deve conter apenas letras, números e traços inferiores
|
||||
reserved: está reservado
|
||||
admin/webhook:
|
||||
attributes:
|
||||
|
@ -43,15 +43,15 @@ pt-PT:
|
|||
blocked: usa um fornecedor de e-mail que não é permitido
|
||||
unreachable: não parece existir
|
||||
role_id:
|
||||
elevated: não pode ser maior que o da sua função atual
|
||||
elevated: não pode ser superior à sua função atual
|
||||
user_role:
|
||||
attributes:
|
||||
permissions_as_keys:
|
||||
dangerous: incluir permissões que não são seguras para a função base
|
||||
elevated: não pode incluir permissões que a sua função atual não possui
|
||||
elevated: não pode incluir permissões que a sua função atual não possua
|
||||
own_role: não pode ser alterado com a sua função atual
|
||||
position:
|
||||
elevated: não pode ser maior que o da sua função atual
|
||||
elevated: não pode ser superior à sua função atual
|
||||
own_role: não pode ser alterado com a sua função atual
|
||||
webhook:
|
||||
attributes:
|
||||
|
|
|
@ -11,15 +11,21 @@ ro:
|
|||
locale: Localizare
|
||||
password: Parolă
|
||||
user/account:
|
||||
username: Nume utilizator
|
||||
username: Nume de utilizator
|
||||
user/invite_request:
|
||||
text: Motiv
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: nu este un nume de domeniu valid
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} nu este un nume de domeniu valid"
|
||||
too_many_lines: este peste limita de %{limit} linii
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
username:
|
||||
invalid: doar litere, numere și sublinieri
|
||||
invalid: trebuie să conțină numai litere, cifre și bară jos (_)
|
||||
reserved: este rezervat
|
||||
admin/webhook:
|
||||
attributes:
|
||||
|
@ -56,4 +62,4 @@ ro:
|
|||
webhook:
|
||||
attributes:
|
||||
events:
|
||||
invalid_permissions: nu poate include evenimente la care nu aveți drepturi
|
||||
invalid_permissions: nu poate include evenimente la care nu aveți dreptul
|
||||
|
|
|
@ -15,6 +15,12 @@ ru:
|
|||
user/invite_request:
|
||||
text: Причина
|
||||
errors:
|
||||
attributes:
|
||||
domain:
|
||||
invalid: не является действующим доменным именем
|
||||
messages:
|
||||
invalid_domain_on_line: "%{value} Не является действительным доменным именем"
|
||||
too_many_lines: Превышает предел %{limit} строк
|
||||
models:
|
||||
account:
|
||||
attributes:
|
||||
|
@ -36,7 +42,7 @@ ru:
|
|||
status:
|
||||
attributes:
|
||||
reblog:
|
||||
taken: поста уже существует
|
||||
taken: пост уже существует
|
||||
user:
|
||||
attributes:
|
||||
email:
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue