weeeeeeeee
This commit is contained in:
@@ -1,217 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'boot'
|
||||
|
||||
require 'rails'
|
||||
|
||||
require 'active_record/railtie'
|
||||
# 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'
|
||||
|
||||
# Used to be implicitly required in action_mailbox/engine
|
||||
require 'mail'
|
||||
|
||||
# Require the gems listed in Gemfile, including any gems
|
||||
# you've limited to :test, :development, or :production.
|
||||
Bundler.require(*Rails.groups)
|
||||
|
||||
require_relative '../lib/exceptions'
|
||||
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'
|
||||
require_relative '../lib/paperclip/type_corrector'
|
||||
require_relative '../lib/paperclip/response_with_limit_adapter'
|
||||
require_relative '../lib/terrapin/multi_pipe_extensions'
|
||||
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/chewy/settings_extensions'
|
||||
require_relative '../lib/chewy/index_extensions'
|
||||
require_relative '../lib/chewy/strategy/mastodon'
|
||||
require_relative '../lib/chewy/strategy/bypass_with_warning'
|
||||
require_relative '../lib/webpacker/manifest_extensions'
|
||||
require_relative '../lib/webpacker/helper_extensions'
|
||||
require_relative '../lib/rails/engine_extensions'
|
||||
require_relative '../lib/active_record/database_tasks_extensions'
|
||||
require_relative '../lib/active_record/batches'
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
config.add_autoload_paths_to_load_path = false
|
||||
|
||||
# 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
|
||||
|
||||
# config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
|
||||
# config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
|
||||
|
||||
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')
|
||||
|
||||
# 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 Rack::Attack
|
||||
config.middleware.use Mastodon::RackMiddleware
|
||||
|
||||
config.to_prepare do
|
||||
Doorkeeper::AuthorizationsController.layout 'modal'
|
||||
Doorkeeper::AuthorizedApplicationsController.layout 'admin'
|
||||
Doorkeeper::Application.include ApplicationExtension
|
||||
Doorkeeper::AccessToken.include AccessTokenExtension
|
||||
Devise::FailureApp.include AbstractController::Callbacks
|
||||
Devise::FailureApp.include Localized
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,11 +0,0 @@
|
||||
# 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
|
||||
end
|
||||
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
||||
|
||||
require 'bundler/setup' # Set up gems listed in the Gemfile.
|
||||
require 'bootsnap/setup' # Speed up boot time by caching expensive operations.
|
||||
@@ -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'
|
||||
@@ -1,9 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Load the Rails application.
|
||||
require_relative 'application'
|
||||
|
||||
# Initialize the Rails application.
|
||||
Rails.application.initialize!
|
||||
|
||||
ActiveRecord::SchemaDumper.ignore_tables = ['deprecated_preview_cards']
|
||||
@@ -1,103 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'active_support/core_ext/integer/time'
|
||||
|
||||
Rails.application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb.
|
||||
|
||||
# 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
|
||||
|
||||
# Do not eager load code on boot.
|
||||
config.eager_load = false
|
||||
|
||||
# Show full error reports.
|
||||
config.consider_all_requests_local = true
|
||||
|
||||
# Enable server timing
|
||||
config.server_timing = true
|
||||
|
||||
# Enable/disable caching. By default caching is disabled.
|
||||
# Run rails dev:cache to toggle caching.
|
||||
if Rails.root.join('tmp', 'caching-dev.txt').exist?
|
||||
config.action_controller.perform_caching = true
|
||||
config.action_controller.enable_fragment_cache_logging = true
|
||||
|
||||
config.cache_store = :redis_cache_store, REDIS_CACHE_PARAMS
|
||||
config.public_file_server.headers = {
|
||||
'Cache-Control' => "public, max-age=#{2.days.to_i}",
|
||||
}
|
||||
else
|
||||
config.action_controller.perform_caching = false
|
||||
|
||||
config.cache_store = :null_store
|
||||
end
|
||||
|
||||
config.action_controller.forgery_protection_origin_check = ENV['DISABLE_FORGERY_REQUEST_PROTECTION'].nil?
|
||||
|
||||
ActiveSupport::Logger.new(STDOUT).tap do |logger|
|
||||
logger.formatter = config.log_formatter
|
||||
config.logger = ActiveSupport::TaggedLogging.new(logger)
|
||||
end
|
||||
|
||||
# Generate random VAPID keys
|
||||
Webpush.generate_key.tap do |vapid_key|
|
||||
config.x.vapid_private_key = vapid_key.private_key
|
||||
config.x.vapid_public_key = vapid_key.public_key
|
||||
end
|
||||
|
||||
# Don't care if the mailer can't send.
|
||||
config.action_mailer.raise_delivery_errors = false
|
||||
|
||||
config.action_mailer.perform_caching = false
|
||||
|
||||
# Print deprecation notices to the Rails logger.
|
||||
config.active_support.deprecation = :log
|
||||
|
||||
# Raise exceptions for disallowed deprecations.
|
||||
config.active_support.disallowed_deprecation = :raise
|
||||
|
||||
# Tell Active Support which deprecation messages to disallow.
|
||||
config.active_support.disallowed_deprecation_warnings = []
|
||||
|
||||
# Raise an error on page load if there are pending migrations.
|
||||
config.active_record.migration_error = :page_load
|
||||
|
||||
# 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
|
||||
|
||||
# Raises error for missing translations.
|
||||
# config.i18n.raise_on_missing_translations = true
|
||||
|
||||
# Annotate rendered view with file names.
|
||||
# config.action_view.annotate_rendered_view_with_filenames = true
|
||||
|
||||
# Uncomment if you wish to allow Action Cable access from any origin.
|
||||
# config.action_cable.disable_request_forgery_protection = true
|
||||
|
||||
config.action_mailer.default_options = { from: 'notifications@localhost' }
|
||||
|
||||
# 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
|
||||
|
||||
# We provide a default secret for the development environment here.
|
||||
# This value should not be used in production environments!
|
||||
config.x.otp_secret = ENV.fetch('OTP_SECRET', '1fc2b87989afa6351912abeebe31ffc5c476ead9bf8b3d74cbc4a302c7b69a45b40b1bbef3506ddad73e942e15ed5ca4b402bf9a66423626051104f4b5f05109')
|
||||
end
|
||||
|
||||
Redis.raise_deprecations = true
|
||||
@@ -1,160 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
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
|
||||
|
||||
# Eager load code on boot. This eager loads most of Rails and
|
||||
# your application in memory, allowing both threaded web servers
|
||||
# and those relying on copy on write to perform better.
|
||||
# Rake tasks automatically ignore this option for performance.
|
||||
config.eager_load = true
|
||||
|
||||
# Full error reports are disabled and caching is turned on.
|
||||
config.consider_all_requests_local = false
|
||||
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).
|
||||
# config.require_master_key = true
|
||||
|
||||
# Compress CSS using a preprocessor.
|
||||
# config.assets.css_compressor = :sass
|
||||
|
||||
# Do not fallback to assets pipeline if a precompiled asset is missed.
|
||||
config.assets.compile = false
|
||||
|
||||
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
|
||||
# config.asset_host = "http://assets.example.com"
|
||||
|
||||
# Specifies the header that your server uses for sending files.
|
||||
config.action_dispatch.x_sendfile_header = ENV['SENDFILE_HEADER'] if ENV['SENDFILE_HEADER'].present?
|
||||
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
|
||||
# config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX
|
||||
|
||||
# Allow to specify public IP of reverse proxy if it's needed
|
||||
config.action_dispatch.trusted_proxies = ENV['TRUSTED_PROXY_IP'].split(/(?:\s*,\s*|\s+)/).map { |item| IPAddr.new(item) } if ENV['TRUSTED_PROXY_IP'].present?
|
||||
|
||||
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
||||
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') }
|
||||
}
|
||||
}
|
||||
|
||||
# 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.
|
||||
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
|
||||
|
||||
# Use a real queuing backend for Active Job (and separate queues per environment).
|
||||
# config.active_job.queue_adapter = :resque
|
||||
# config.active_job.queue_name_prefix = "mastodon_production"
|
||||
|
||||
config.action_mailer.perform_caching = false
|
||||
|
||||
# Ignore bad email addresses and do not raise email delivery errors.
|
||||
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
|
||||
# config.action_mailer.raise_delivery_errors = false
|
||||
|
||||
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
|
||||
# English when a translation cannot be found).
|
||||
config.i18n.fallbacks = [:en]
|
||||
|
||||
# Send deprecation notices to registered listeners.
|
||||
config.active_support.deprecation = :notify
|
||||
|
||||
# Use default logging formatter so that PID and timestamp are not suppressed.
|
||||
config.log_formatter = ::Logger::Formatter.new
|
||||
|
||||
# Better log formatting
|
||||
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
|
||||
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
|
||||
|
||||
# Do not dump schema after migrations.
|
||||
config.active_record.dump_schema_after_migration = false
|
||||
|
||||
config.action_mailer.perform_caching = false
|
||||
|
||||
# E-mails
|
||||
outgoing_email_address = ENV.fetch('SMTP_FROM_ADDRESS', 'notifications@localhost')
|
||||
outgoing_email_domain = Mail::Address.new(outgoing_email_address).domain
|
||||
|
||||
config.action_mailer.default_options = {
|
||||
from: outgoing_email_address,
|
||||
message_id: -> { "<#{Mail.random_tag}@#{outgoing_email_domain}>" },
|
||||
}
|
||||
|
||||
config.action_mailer.default_options[:reply_to] = ENV['SMTP_REPLY_TO'] if ENV['SMTP_REPLY_TO'].present?
|
||||
config.action_mailer.default_options[:return_path] = ENV['SMTP_RETURN_PATH'] if ENV['SMTP_RETURN_PATH'].present?
|
||||
|
||||
enable_starttls = nil
|
||||
enable_starttls_auto = nil
|
||||
|
||||
case ENV['SMTP_ENABLE_STARTTLS']
|
||||
when 'always'
|
||||
enable_starttls = true
|
||||
when 'never'
|
||||
enable_starttls = false
|
||||
when 'auto'
|
||||
enable_starttls_auto = true
|
||||
else
|
||||
enable_starttls_auto = ENV['SMTP_ENABLE_STARTTLS_AUTO'] != 'false'
|
||||
end
|
||||
|
||||
config.action_mailer.smtp_settings = {
|
||||
port: ENV['SMTP_PORT'],
|
||||
address: ENV['SMTP_SERVER'],
|
||||
user_name: ENV['SMTP_LOGIN'].presence,
|
||||
password: ENV['SMTP_PASSWORD'].presence,
|
||||
domain: ENV['SMTP_DOMAIN'] || ENV['LOCAL_DOMAIN'],
|
||||
authentication: ENV['SMTP_AUTH_METHOD'] == 'none' ? nil : ENV['SMTP_AUTH_METHOD'] || :plain,
|
||||
ca_file: ENV['SMTP_CA_FILE'].presence || '/etc/ssl/certs/ca-certificates.crt',
|
||||
openssl_verify_mode: ENV['SMTP_OPENSSL_VERIFY_MODE'],
|
||||
enable_starttls: enable_starttls,
|
||||
enable_starttls_auto: enable_starttls_auto,
|
||||
tls: ENV['SMTP_TLS'].presence && ENV['SMTP_TLS'] == 'true',
|
||||
ssl: ENV['SMTP_SSL'].presence && ENV['SMTP_SSL'] == 'true',
|
||||
read_timeout: 20,
|
||||
}
|
||||
|
||||
config.action_mailer.delivery_method = ENV.fetch('SMTP_DELIVERY_METHOD', 'smtp').to_sym
|
||||
|
||||
config.action_dispatch.default_headers = {
|
||||
'Server' => 'Mastodon',
|
||||
'X-Frame-Options' => 'DENY',
|
||||
'X-Content-Type-Options' => 'nosniff',
|
||||
'X-XSS-Protection' => '0',
|
||||
'X-Clacks-Overhead' => 'GNU Natalie Nguyen',
|
||||
'Referrer-Policy' => 'same-origin',
|
||||
}
|
||||
|
||||
config.x.otp_secret = ENV.fetch('OTP_SECRET')
|
||||
end
|
||||
@@ -1,94 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'active_support/core_ext/integer/time'
|
||||
|
||||
# The test environment is used exclusively to run your application's
|
||||
# test suite. You never need to work with it otherwise. Remember that
|
||||
# your test database is "scratch space" for the test suite and is wiped
|
||||
# and recreated between test runs. Don't rely on the data there!
|
||||
|
||||
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
|
||||
|
||||
# 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.
|
||||
config.eager_load = ENV['CI'].present?
|
||||
|
||||
config.assets_digest = false
|
||||
|
||||
# Show full error reports and disable caching.
|
||||
config.consider_all_requests_local = true
|
||||
config.action_controller.perform_caching = false
|
||||
config.cache_store = :memory_store
|
||||
|
||||
# Raise exceptions instead of rendering exception templates.
|
||||
config.action_dispatch.show_exceptions = false
|
||||
|
||||
# Disable request forgery protection in test environment.
|
||||
config.action_controller.allow_forgery_protection = false
|
||||
|
||||
config.action_mailer.perform_caching = false
|
||||
|
||||
config.action_mailer.default_options = { from: 'notifications@localhost' }
|
||||
|
||||
# Tell Action Mailer not to deliver emails to the real world.
|
||||
# The :test delivery method accumulates sent emails in the
|
||||
# ActionMailer::Base.deliveries array.
|
||||
config.action_mailer.delivery_method = :test
|
||||
|
||||
# Print deprecation notices to the stderr.
|
||||
config.active_support.deprecation = :stderr
|
||||
|
||||
config.x.otp_secret = '100c7faeef00caa29242f6b04156742bf76065771fd4117990c4282b8748ff3d99f8fdae97c982ab5bd2e6756a159121377cce4421f4a8ecd2d67bd7749a3fb4'
|
||||
|
||||
# Generate random VAPID keys
|
||||
vapid_key = Webpush.generate_key
|
||||
config.x.vapid_private_key = vapid_key.private_key
|
||||
config.x.vapid_public_key = vapid_key.public_key
|
||||
|
||||
# Raise exceptions when a reorder occurs in in_batches
|
||||
config.active_record.error_on_ignored_order = true
|
||||
|
||||
# Raise exceptions for disallowed deprecations.
|
||||
config.active_support.disallowed_deprecation = :raise
|
||||
|
||||
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 = []
|
||||
|
||||
# Raises error for missing translations.
|
||||
# config.i18n.raise_on_missing_translations = true
|
||||
|
||||
# Annotate rendered view with file names.
|
||||
# config.action_view.annotate_rendered_view_with_filenames = 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
|
||||
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' }
|
||||
}
|
||||
end
|
||||
|
||||
# Catch serialization warnings early
|
||||
Sidekiq.strict_args!
|
||||
|
||||
Redis.raise_deprecations = true
|
||||
@@ -1,82 +0,0 @@
|
||||
# i18n-tasks finds and manages missing and unused translations: https://github.com/glebm/i18n-tasks
|
||||
|
||||
# The "main" locale.
|
||||
base_locale: en
|
||||
data:
|
||||
read:
|
||||
- config/locales-glitch/%{locale}.yml
|
||||
- config/locales-glitch/*.%{locale}.yml
|
||||
|
||||
write:
|
||||
- [
|
||||
'{devise, simple_form, doorkeeper}.*',
|
||||
'config/locales-glitch/\1.%{locale}.yml',
|
||||
]
|
||||
- config/locales-glitch/%{locale}.yml
|
||||
|
||||
external:
|
||||
- config/locales/%{locale}.yml
|
||||
- config/locales/**/*.%{locale}.yml
|
||||
|
||||
yaml:
|
||||
write:
|
||||
line_width: -1
|
||||
|
||||
search:
|
||||
paths:
|
||||
- app/
|
||||
- config/navigation.rb
|
||||
|
||||
relative_roots:
|
||||
- app/controllers
|
||||
- app/helpers
|
||||
- app/mailers
|
||||
- app/views
|
||||
|
||||
exclude:
|
||||
- app/assets/images
|
||||
- app/assets/fonts
|
||||
- app/assets/videos
|
||||
|
||||
ignore_missing:
|
||||
- 'activemodel.errors.*'
|
||||
- 'activerecord.attributes.*'
|
||||
- 'activerecord.errors.*'
|
||||
- '{pagination,doorkeeper}.*'
|
||||
- '{date,datetime,time,number}.*'
|
||||
- 'errors.messages.*'
|
||||
- 'activerecord.errors.models.doorkeeper/*'
|
||||
- 'sessions.{browsers,platforms}.*'
|
||||
- 'application_mailer.salutation'
|
||||
- 'errors.500'
|
||||
- 'auth.providers.*'
|
||||
|
||||
ignore_unused:
|
||||
- 'activemodel.errors.*'
|
||||
- 'activerecord.attributes.*'
|
||||
- 'activerecord.errors.*'
|
||||
- '{devise,pagination,doorkeeper}.*'
|
||||
- '{date,datetime,time,number}.*'
|
||||
- 'simple_form.{yes,no,recommended,not_recommended,overridden,glitch_only}'
|
||||
- 'simple_form.{placeholders,hints,labels}.*'
|
||||
- 'simple_form.{error_notification,required}.:'
|
||||
- 'errors.messages.*'
|
||||
- 'activerecord.errors.models.doorkeeper/*'
|
||||
- 'errors.429'
|
||||
- 'admin.accounts.roles.*'
|
||||
- 'admin.action_logs.actions.*'
|
||||
- 'admin.reports.summary.action_preambles.*'
|
||||
- 'admin.reports.summary.actions.*'
|
||||
- 'admin_mailer.new_appeal.actions.*'
|
||||
- 'statuses.attached.*'
|
||||
- 'themes.*'
|
||||
- 'move_handler.carry_{mutes,blocks}_over_text'
|
||||
- 'admin_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
|
||||
|
||||
ignore_inconsistent_interpolations:
|
||||
- '*.one'
|
||||
@@ -1,27 +0,0 @@
|
||||
<policymap>
|
||||
<!-- Set some basic system resource limits -->
|
||||
<policy domain="resource" name="time" value="60" />
|
||||
|
||||
<policy domain="module" rights="none" pattern="URL" />
|
||||
|
||||
<policy domain="filter" rights="none" pattern="*" />
|
||||
|
||||
<!--
|
||||
Ideally, we would restrict ImageMagick to only accessing its own
|
||||
disk-backed pixel cache as well as Mastodon-created Tempfiles.
|
||||
|
||||
However, those paths depend on the operating system and environment
|
||||
variables, so they can only be known at runtime.
|
||||
|
||||
Furthermore, those paths are not necessarily shared across Mastodon
|
||||
processes, so even creating a policy.xml at runtime is impractical.
|
||||
|
||||
For the time being, only disable indirect reads.
|
||||
-->
|
||||
<policy domain="path" rights="none" pattern="@*" />
|
||||
|
||||
<!-- Disallow any coder by default, and only enable ones required by Mastodon -->
|
||||
<policy domain="coder" rights="none" pattern="*" />
|
||||
<policy domain="coder" rights="read | write" pattern="{JPEG,PNG,GIF,WEBP,HEIC,AVIF}" />
|
||||
<policy domain="coder" rights="write" pattern="{HISTOGRAM,RGB,INFO}" />
|
||||
</policymap>
|
||||
@@ -1,56 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Some migrations have been present in glitch-soc for a long time and have then
|
||||
# been merged in upstream Mastodon, under a different version number.
|
||||
#
|
||||
# This puts us in an uneasy situation in which if we remove upstream's
|
||||
# migration file, people migrating from upstream will end up having a conflict
|
||||
# with their already-ran migration.
|
||||
#
|
||||
# On the other hand, if we keep upstream's migration and remove our own,
|
||||
# any current glitch-soc user will have a conflict during migration.
|
||||
#
|
||||
# For lack of a better solution, as those migrations are indeed identical,
|
||||
# we decided monkey-patching Rails' Migrator to completely ignore the duplicate,
|
||||
# keeping only the one that has run, or an arbitrary one.
|
||||
|
||||
ALLOWED_DUPLICATES = [2018_04_10_220657, 2018_08_31_171112].freeze
|
||||
|
||||
module ActiveRecord
|
||||
class Migrator
|
||||
def self.new(direction, migrations, schema_migration, target_version = nil)
|
||||
migrated = Set.new(Base.connection.migration_context.get_all_versions)
|
||||
|
||||
migrations.group_by(&:name).each do |_name, duplicates|
|
||||
next unless duplicates.length > 1 && duplicates.all? { |m| ALLOWED_DUPLICATES.include?(m.version) }
|
||||
|
||||
# We have a set of allowed duplicates. Keep the migrated one, if any.
|
||||
non_migrated = duplicates.reject { |m| migrated.include?(m.version.to_i) }
|
||||
|
||||
migrations = begin
|
||||
if duplicates.length == non_migrated.length || non_migrated.empty?
|
||||
# There weren't any migrated one, so we have to pick one “canonical” migration
|
||||
migrations - duplicates[1..]
|
||||
else
|
||||
# Just reject every duplicate which hasn't been migrated yet
|
||||
migrations - non_migrated
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
super(direction, migrations, schema_migration, target_version)
|
||||
end
|
||||
end
|
||||
|
||||
class MigrationContext
|
||||
def needs_migration?
|
||||
# A set of duplicated migrations is considered migrated if at least one of
|
||||
# them is migrated.
|
||||
migrated = get_all_versions
|
||||
migrations.group_by(&:name).each do |_name, duplicates|
|
||||
return true unless duplicates.any? { |m| migrated.include?(m.version.to_i) }
|
||||
end
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,17 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Post deployment migrations are included by default. This file must be loaded
|
||||
# before other initializers as Rails may otherwise memoize a list of migrations
|
||||
# excluding the post deployment migrations.
|
||||
|
||||
unless ENV['SKIP_POST_DEPLOYMENT_MIGRATIONS']
|
||||
Rails.application.config.paths['db'].each do |db_path|
|
||||
path = Rails.root.join(db_path, 'post_migrate').to_s
|
||||
|
||||
Rails.application.config.paths['db/migrate'] << path
|
||||
|
||||
# Rails memoizes migrations at certain points where it won't read the above
|
||||
# path just yet. As such we must also update the following list of paths.
|
||||
ActiveRecord::Migrator.migrations_paths << path
|
||||
end
|
||||
end
|
||||
@@ -1,36 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
port = ENV.fetch('PORT') { 3000 }
|
||||
host = ENV.fetch('LOCAL_DOMAIN') { "localhost:#{port}" }
|
||||
web_host = ENV.fetch('WEB_DOMAIN') { host }
|
||||
|
||||
alternate_domains = ENV.fetch('ALTERNATE_DOMAINS') { '' }.split(/\s*,\s*/)
|
||||
|
||||
Rails.application.configure do
|
||||
https = Rails.env.production? || ENV['LOCAL_HTTPS'] == 'true'
|
||||
|
||||
config.x.local_domain = host
|
||||
config.x.web_domain = web_host
|
||||
config.x.use_https = https
|
||||
config.x.use_s3 = ENV['S3_ENABLED'] == 'true'
|
||||
config.x.use_swift = ENV['SWIFT_ENABLED'] == 'true'
|
||||
|
||||
config.x.alternate_domains = alternate_domains
|
||||
|
||||
config.action_mailer.default_url_options = { host: web_host, protocol: https ? 'https://' : 'http://', trailing_slash: false }
|
||||
|
||||
config.x.streaming_api_base_url = ENV.fetch('STREAMING_API_BASE_URL') do
|
||||
if Rails.env.production?
|
||||
"ws#{https ? 's' : ''}://#{web_host}"
|
||||
else
|
||||
"ws://#{ENV['REMOTE_DEV'] == 'true' ? host.split(':').first : 'localhost'}:4000"
|
||||
end
|
||||
end
|
||||
|
||||
unless Rails.env.test?
|
||||
config.hosts << host if host.present?
|
||||
config.hosts << web_host if web_host.present?
|
||||
config.hosts.concat(alternate_domains) if alternate_domains.present?
|
||||
config.host_authorization = { exclude: ->(request) { request.path == '/health' } }
|
||||
end
|
||||
end
|
||||
@@ -1,7 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.configure do
|
||||
config.x.limited_federation_mode = (ENV['LIMITED_FEDERATION_MODE'] || ENV['WHITELIST_MODE']) == 'true'
|
||||
|
||||
warn 'WARN: The environment variable WHITELIST_MODE has been replaced with LIMITED_FEDERATION_MODE, you should rename this environment variable in your configuration.' if ENV.key?('WHITELIST_MODE')
|
||||
end
|
||||
@@ -1,110 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# OmniAuth providers need to be initialized before the CSP initializer
|
||||
# in `config/initializers/content_security_policy.rb`, which sets the
|
||||
# `form-action` directive based on them.
|
||||
|
||||
Rails.application.config.middleware.use OmniAuth::Builder do
|
||||
# Vanilla omniauth strategies
|
||||
end
|
||||
|
||||
Devise.setup do |config|
|
||||
# Devise omniauth strategies
|
||||
options = {}
|
||||
|
||||
# CAS strategy
|
||||
if ENV['CAS_ENABLED'] == 'true'
|
||||
cas_options = {}
|
||||
cas_options[:display_name] = ENV['CAS_DISPLAY_NAME']
|
||||
cas_options[:url] = ENV['CAS_URL'] if ENV['CAS_URL']
|
||||
cas_options[:host] = ENV['CAS_HOST'] if ENV['CAS_HOST']
|
||||
cas_options[:port] = ENV['CAS_PORT'] if ENV['CAS_PORT']
|
||||
cas_options[:ssl] = ENV['CAS_SSL'] == 'true' if ENV['CAS_SSL']
|
||||
cas_options[:service_validate_url] = ENV['CAS_VALIDATE_URL'] if ENV['CAS_VALIDATE_URL']
|
||||
cas_options[:callback_url] = ENV['CAS_CALLBACK_URL'] if ENV['CAS_CALLBACK_URL']
|
||||
cas_options[:logout_url] = ENV['CAS_LOGOUT_URL'] if ENV['CAS_LOGOUT_URL']
|
||||
cas_options[:login_url] = ENV['CAS_LOGIN_URL'] if ENV['CAS_LOGIN_URL']
|
||||
cas_options[:uid_field] = ENV['CAS_UID_FIELD'] || 'user' if ENV['CAS_UID_FIELD']
|
||||
cas_options[:ca_path] = ENV['CAS_CA_PATH'] if ENV['CAS_CA_PATH']
|
||||
cas_options[:disable_ssl_verification] = ENV['CAS_DISABLE_SSL_VERIFICATION'] == 'true'
|
||||
cas_options[:uid_key] = ENV['CAS_UID_KEY'] || 'user'
|
||||
cas_options[:name_key] = ENV['CAS_NAME_KEY'] || 'name'
|
||||
cas_options[:email_key] = ENV['CAS_EMAIL_KEY'] || 'email'
|
||||
cas_options[:nickname_key] = ENV['CAS_NICKNAME_KEY'] || 'nickname'
|
||||
cas_options[:first_name_key] = ENV['CAS_FIRST_NAME_KEY'] || 'firstname'
|
||||
cas_options[:last_name_key] = ENV['CAS_LAST_NAME_KEY'] || 'lastname'
|
||||
cas_options[:location_key] = ENV['CAS_LOCATION_KEY'] || 'location'
|
||||
cas_options[:image_key] = ENV['CAS_IMAGE_KEY'] || 'image'
|
||||
cas_options[:phone_key] = ENV['CAS_PHONE_KEY'] || 'phone'
|
||||
cas_options[:security] = {}
|
||||
cas_options[:security][:assume_email_is_verified] = ENV['CAS_SECURITY_ASSUME_EMAIL_IS_VERIFIED'] == 'true'
|
||||
config.omniauth :cas, cas_options
|
||||
end
|
||||
|
||||
# SAML strategy
|
||||
if ENV['SAML_ENABLED'] == 'true'
|
||||
saml_options = {}
|
||||
saml_options[:display_name] = ENV['SAML_DISPLAY_NAME']
|
||||
saml_options[:assertion_consumer_service_url] = ENV['SAML_ACS_URL'] if ENV['SAML_ACS_URL']
|
||||
saml_options[:issuer] = ENV['SAML_ISSUER'] if ENV['SAML_ISSUER']
|
||||
saml_options[:idp_sso_target_url] = ENV['SAML_IDP_SSO_TARGET_URL'] if ENV['SAML_IDP_SSO_TARGET_URL']
|
||||
saml_options[:idp_sso_target_url_runtime_params] = ENV['SAML_IDP_SSO_TARGET_PARAMS'] if ENV['SAML_IDP_SSO_TARGET_PARAMS'] # FIXME: Should be parsable Hash
|
||||
saml_options[:idp_cert] = ENV['SAML_IDP_CERT'] if ENV['SAML_IDP_CERT']
|
||||
saml_options[:idp_cert_fingerprint] = ENV['SAML_IDP_CERT_FINGERPRINT'] if ENV['SAML_IDP_CERT_FINGERPRINT']
|
||||
saml_options[:idp_cert_fingerprint_validator] = ENV['SAML_IDP_CERT_FINGERPRINT_VALIDATOR'] if ENV['SAML_IDP_CERT_FINGERPRINT_VALIDATOR'] # FIXME: Should be Lambda { |fingerprint| }
|
||||
saml_options[:name_identifier_format] = ENV['SAML_NAME_IDENTIFIER_FORMAT'] if ENV['SAML_NAME_IDENTIFIER_FORMAT']
|
||||
saml_options[:request_attributes] = {}
|
||||
saml_options[:certificate] = ENV['SAML_CERT'] if ENV['SAML_CERT']
|
||||
saml_options[:private_key] = ENV['SAML_PRIVATE_KEY'] if ENV['SAML_PRIVATE_KEY']
|
||||
saml_options[:security] = {}
|
||||
saml_options[:security][:want_assertions_signed] = ENV['SAML_SECURITY_WANT_ASSERTION_SIGNED'] == 'true'
|
||||
saml_options[:security][:want_assertions_encrypted] = ENV['SAML_SECURITY_WANT_ASSERTION_ENCRYPTED'] == 'true'
|
||||
saml_options[:security][:assume_email_is_verified] = ENV['SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED'] == 'true'
|
||||
saml_options[:attribute_statements] = {}
|
||||
saml_options[:attribute_statements][:uid] = [ENV['SAML_ATTRIBUTES_STATEMENTS_UID']] if ENV['SAML_ATTRIBUTES_STATEMENTS_UID']
|
||||
saml_options[:attribute_statements][:email] = [ENV['SAML_ATTRIBUTES_STATEMENTS_EMAIL']] if ENV['SAML_ATTRIBUTES_STATEMENTS_EMAIL']
|
||||
saml_options[:attribute_statements][:full_name] = [ENV['SAML_ATTRIBUTES_STATEMENTS_FULL_NAME']] if ENV['SAML_ATTRIBUTES_STATEMENTS_FULL_NAME']
|
||||
saml_options[:attribute_statements][:first_name] = [ENV['SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME']] if ENV['SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME']
|
||||
saml_options[:attribute_statements][:last_name] = [ENV['SAML_ATTRIBUTES_STATEMENTS_LAST_NAME']] if ENV['SAML_ATTRIBUTES_STATEMENTS_LAST_NAME']
|
||||
saml_options[:attribute_statements][:verified] = [ENV['SAML_ATTRIBUTES_STATEMENTS_VERIFIED']] if ENV['SAML_ATTRIBUTES_STATEMENTS_VERIFIED']
|
||||
saml_options[:attribute_statements][:verified_email] = [ENV['SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL']] if ENV['SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL']
|
||||
saml_options[:uid_attribute] = ENV['SAML_UID_ATTRIBUTE'] if ENV['SAML_UID_ATTRIBUTE']
|
||||
saml_options[:allowed_clock_drift] = ENV['SAML_ALLOWED_CLOCK_DRIFT'] if ENV['SAML_ALLOWED_CLOCK_DRIFT']
|
||||
config.omniauth :saml, saml_options
|
||||
end
|
||||
|
||||
# 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
|
||||
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[: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[:security] = {}
|
||||
oidc_options[:security][:assume_email_is_verified] = ENV['OIDC_SECURITY_ASSUME_EMAIL_IS_VERIFIED'] == 'true' # OPTIONAL
|
||||
config.omniauth :openid_connect, oidc_options
|
||||
end
|
||||
end
|
||||
@@ -1,7 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
ActiveModelSerializers.config.tap do |config|
|
||||
config.default_includes = '**'
|
||||
end
|
||||
|
||||
ActiveSupport::Notifications.unsubscribe(ActiveModelSerializers::Logging::RENDER_EVENT)
|
||||
@@ -1,9 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# ActiveSupport::Reloader.to_prepare do
|
||||
# ApplicationController.renderer.defaults.merge!(
|
||||
# http_host: 'example.org',
|
||||
# https: false
|
||||
# )
|
||||
# end
|
||||
@@ -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
|
||||
@@ -1,10 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
|
||||
# Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) }
|
||||
|
||||
# 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"]
|
||||
@@ -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
|
||||
@@ -1,11 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.configure do
|
||||
config.x.cache_buster_enabled = ENV['CACHE_BUSTER_ENABLED'] == 'true'
|
||||
|
||||
config.x.cache_buster = {
|
||||
secret_header: ENV['CACHE_BUSTER_SECRET_HEADER'],
|
||||
secret: ENV['CACHE_BUSTER_SECRET'],
|
||||
http_method: ENV['CACHE_BUSTER_HTTP_METHOD'] || 'GET',
|
||||
}
|
||||
end
|
||||
@@ -1,5 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Log cache errors with Rail's logger
|
||||
# This used to be the default in old Rails versions: https://github.com/rails/rails/commit/7fcf8590e788cef8b64cc266f75931c418902ca9#diff-f0748f0be8a653eea13369ebb1cadabcad71ede7cfaf20282447e64329817befL86
|
||||
Rails.cache.logger = Rails.logger
|
||||
@@ -1,35 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
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 }
|
||||
prefix = ENV.fetch('ES_PREFIX') { fallback_prefix }
|
||||
|
||||
Chewy.settings = {
|
||||
host: "#{host}:#{port}",
|
||||
prefix: prefix,
|
||||
enabled: enabled,
|
||||
journal: false,
|
||||
user: user,
|
||||
password: password,
|
||||
index: {
|
||||
number_of_replicas: ['single_node_cluster', nil].include?(ENV['ES_PRESET'].presence) ? 0 : 1,
|
||||
},
|
||||
}
|
||||
|
||||
# We use our own async strategy even outside the request-response
|
||||
# cycle, which takes care of checking if Elasticsearch is enabled
|
||||
# or not. However, mind that for the Rails console, the :urgent
|
||||
# strategy is set automatically with no way to override it.
|
||||
Chewy.root_strategy = :bypass_with_warning if Rails.env.production?
|
||||
Chewy.request_strategy = :mastodon
|
||||
Chewy.use_after_commit_callbacks = false
|
||||
|
||||
# Elasticsearch uses Faraday internally. Faraday interprets the
|
||||
# http_proxy env variable by default which leads to issues when
|
||||
# Mastodon is run with hidden services enabled, because
|
||||
# Elasticsearch is *not* supposed to be accessed through a proxy
|
||||
Faraday.ignore_env_proxy = true
|
||||
@@ -1,107 +0,0 @@
|
||||
# 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
|
||||
|
||||
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
|
||||
|
||||
unless Rails.env.development?
|
||||
assets_host = Rails.configuration.action_controller.asset_host || "https://#{ENV['WEB_DOMAIN'] || ENV['LOCAL_DOMAIN']}"
|
||||
data_hosts = [assets_host]
|
||||
|
||||
if ENV['S3_ENABLED'] == 'true' || ENV['AZURE_ENABLED'] == 'true'
|
||||
attachments_host = "https://#{ENV['S3_ALIAS_HOST'] || ENV['S3_CLOUDFRONT_HOST'] || ENV['AZURE_ALIAS_HOST'] || ENV['S3_HOSTNAME'] || "s3-#{ENV['S3_REGION'] || 'us-east-1'}.amazonaws.com"}"
|
||||
attachments_host = "https://#{Addressable::URI.parse(attachments_host).host}"
|
||||
elsif ENV['SWIFT_ENABLED'] == 'true'
|
||||
attachments_host = ENV['SWIFT_OBJECT_URL']
|
||||
attachments_host = "https://#{Addressable::URI.parse(attachments_host).host}"
|
||||
else
|
||||
attachments_host = nil
|
||||
end
|
||||
|
||||
data_hosts << attachments_host unless attachments_host.nil?
|
||||
|
||||
if ENV['PAPERCLIP_ROOT_URL']
|
||||
url = Addressable::URI.parse(assets_host) + ENV['PAPERCLIP_ROOT_URL']
|
||||
data_hosts << "https://#{url.host}"
|
||||
end
|
||||
|
||||
data_hosts.concat(ENV['EXTRA_DATA_HOSTS'].split('|')) if ENV['EXTRA_DATA_HOSTS']
|
||||
|
||||
data_hosts.uniq!
|
||||
|
||||
Rails.application.config.content_security_policy do |p|
|
||||
p.base_uri :none
|
||||
p.default_src :none
|
||||
p.frame_ancestors :none
|
||||
p.script_src :self, assets_host, "'wasm-unsafe-eval'"
|
||||
p.font_src :self, assets_host
|
||||
p.img_src :self, :data, :blob, *data_hosts
|
||||
p.style_src :self, assets_host
|
||||
p.media_src :self, :data, *data_hosts
|
||||
p.frame_src :self, :https
|
||||
p.child_src :self, :blob, assets_host
|
||||
p.worker_src :self, :blob, assets_host
|
||||
p.connect_src :self, :blob, :data, Rails.configuration.x.streaming_api_base_url, *data_hosts
|
||||
p.manifest_src :self, assets_host
|
||||
|
||||
if sso_host.present?
|
||||
p.form_action :self, sso_host
|
||||
else
|
||||
p.form_action :self
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Report CSP violations to a specified URI
|
||||
# For further information see the following documentation:
|
||||
# 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_directives = %w(style-src)
|
||||
|
||||
Rails.application.reloader.to_prepare do
|
||||
PgHero::HomeController.content_security_policy do |p|
|
||||
p.script_src :self, :unsafe_inline, assets_host
|
||||
p.style_src :self, :unsafe_inline, assets_host
|
||||
end
|
||||
|
||||
PgHero::HomeController.after_action do
|
||||
request.content_security_policy_nonce_generator = nil
|
||||
end
|
||||
|
||||
if Rails.env.development?
|
||||
LetterOpenerWeb::LettersController.content_security_policy do |p|
|
||||
p.child_src :self
|
||||
p.connect_src :none
|
||||
p.frame_ancestors :self
|
||||
p.frame_src :self
|
||||
p.script_src :unsafe_inline
|
||||
p.style_src :unsafe_inline
|
||||
p.worker_src :none
|
||||
end
|
||||
|
||||
LetterOpenerWeb::LettersController.after_action do |p|
|
||||
request.content_security_policy_nonce_directives = %w(script-src)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,27 +0,0 @@
|
||||
# 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
|
||||
|
||||
Rails.application.config.after_initialize do
|
||||
Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies|
|
||||
authenticated_encrypted_cookie_salt = Rails.application.config.action_dispatch.authenticated_encrypted_cookie_salt
|
||||
signed_cookie_salt = Rails.application.config.action_dispatch.signed_cookie_salt
|
||||
|
||||
secret_key_base = Rails.application.secret_key_base
|
||||
|
||||
# TODO: Switch to SHA1 after 4.2.0
|
||||
key_generator = ActiveSupport::KeyGenerator.new(
|
||||
secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA256
|
||||
)
|
||||
key_len = ActiveSupport::MessageEncryptor.key_len
|
||||
|
||||
old_encrypted_secret = key_generator.generate_key(authenticated_encrypted_cookie_salt, key_len)
|
||||
old_signed_secret = key_generator.generate_key(signed_cookie_salt)
|
||||
|
||||
cookies.rotate :encrypted, old_encrypted_secret
|
||||
cookies.rotate :signed, old_signed_secret
|
||||
end
|
||||
end
|
||||
@@ -1,7 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Specify a serializer for the signed and encrypted cookie jars.
|
||||
# Valid options are :json, :marshal, and :hybrid.
|
||||
Rails.application.config.action_dispatch.cookies_serializer = :json
|
||||
@@ -1,26 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# 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.
|
||||
|
||||
# Read more: https://github.com/cyu/rack-cors
|
||||
|
||||
Rails.application.config.middleware.insert_before 0, Rack::Cors do
|
||||
allow do
|
||||
origins '*'
|
||||
|
||||
with_options headers: :any, credentials: false do
|
||||
with_options methods: [:get] do
|
||||
resource '/.well-known/*'
|
||||
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]
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,417 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'devise/strategies/authenticatable'
|
||||
|
||||
Warden::Manager.after_set_user except: :fetch do |user, warden|
|
||||
session_id = warden.cookies.signed['_session_id'] || warden.raw_session['auth_id']
|
||||
session_id = user.activate_session(warden.request) unless user.session_activations.active?(session_id)
|
||||
|
||||
warden.cookies.signed['_session_id'] = {
|
||||
value: session_id,
|
||||
expires: 1.year.from_now,
|
||||
httponly: true,
|
||||
same_site: :lax,
|
||||
}
|
||||
end
|
||||
|
||||
Warden::Manager.after_fetch do |user, warden|
|
||||
session_id = warden.cookies.signed['_session_id'] || warden.raw_session['auth_id']
|
||||
|
||||
if session_id && (session = user.session_activations.find_by(session_id: session_id))
|
||||
session.update(ip: warden.request.remote_ip) if session.ip != warden.request.remote_ip
|
||||
|
||||
warden.cookies.signed['_session_id'] = {
|
||||
value: session_id,
|
||||
expires: 1.year.from_now,
|
||||
httponly: true,
|
||||
same_site: :lax,
|
||||
}
|
||||
else
|
||||
warden.logout
|
||||
throw :warden, message: :unauthenticated
|
||||
end
|
||||
end
|
||||
|
||||
Warden::Manager.before_logout do |_, warden|
|
||||
SessionActivation.deactivate warden.cookies.signed['_session_id']
|
||||
warden.cookies.delete('_session_id')
|
||||
end
|
||||
|
||||
module Devise
|
||||
mattr_accessor :pam_authentication
|
||||
@@pam_authentication = false
|
||||
mattr_accessor :pam_controlled_service
|
||||
@@pam_controlled_service = nil
|
||||
|
||||
mattr_accessor :check_at_sign
|
||||
@@check_at_sign = 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
|
||||
|
||||
module Strategies
|
||||
class PamAuthenticatable
|
||||
def valid?
|
||||
super && ::Devise.pam_authentication
|
||||
end
|
||||
end
|
||||
|
||||
class SessionActivationRememberable < Authenticatable
|
||||
def valid?
|
||||
@session_cookie = nil
|
||||
session_cookie.present?
|
||||
end
|
||||
|
||||
def authenticate!
|
||||
resource = SessionActivation.find_by(session_id: session_cookie)&.user
|
||||
|
||||
unless resource
|
||||
cookies.delete('_session_id')
|
||||
return pass
|
||||
end
|
||||
|
||||
if validate(resource)
|
||||
success!(resource)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def session_cookie
|
||||
@session_cookie ||= cookies.signed['_session_id']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Warden::Strategies.add(:session_activation_rememberable, Devise::Strategies::SessionActivationRememberable)
|
||||
|
||||
Devise.setup do |config|
|
||||
config.warden do |manager|
|
||||
manager.default_strategies(scope: :user).unshift :two_factor_ldap_authenticatable if Devise.ldap_authentication
|
||||
manager.default_strategies(scope: :user).unshift :two_factor_pam_authenticatable if Devise.pam_authentication
|
||||
manager.default_strategies(scope: :user).unshift :session_activation_rememberable
|
||||
manager.default_strategies(scope: :user).unshift :two_factor_authenticatable
|
||||
manager.default_strategies(scope: :user).unshift :two_factor_backupable
|
||||
end
|
||||
|
||||
# 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'
|
||||
|
||||
# ==> Mailer Configuration
|
||||
# Configure the e-mail address which will be shown in Devise::Mailer,
|
||||
# note that it will be overwritten if you use your own mailer class
|
||||
# with default "from" parameter.
|
||||
# config.mailer_sender = ENV['SMTP_FROM_ADDRESS'] || 'notifications@localhost'
|
||||
|
||||
# Configure the class responsible to send e-mails.
|
||||
config.mailer = 'UserMailer'
|
||||
|
||||
# ==> ORM configuration
|
||||
# Load and configure the ORM. Supports :active_record (default) and
|
||||
# :mongoid (bson_ext recommended) by default. Other ORMs may be
|
||||
# available as additional gems.
|
||||
require 'devise/orm/active_record'
|
||||
|
||||
# ==> Configuration for any authentication mechanism
|
||||
# Configure which keys are used when authenticating a user. The default is
|
||||
# just :email. You can configure it to use [:username, :subdomain], so for
|
||||
# authenticating a user, both parameters are required. Remember that those
|
||||
# parameters are used only when authenticating and not when retrieving from
|
||||
# session. If you need permissions, you should implement that in a before filter.
|
||||
# You can also supply a hash where the value is a boolean determining whether
|
||||
# or not authentication should be aborted when the value is not present.
|
||||
# config.authentication_keys = [:email]
|
||||
|
||||
# Configure parameters from the request object used for authentication. Each entry
|
||||
# given should be a request method and it will automatically be passed to the
|
||||
# find_for_authentication method and considered in your model lookup. For instance,
|
||||
# if you set :request_keys to [:subdomain], :subdomain will be used on authentication.
|
||||
# The same considerations mentioned for authentication_keys also apply to request_keys.
|
||||
# config.request_keys = []
|
||||
|
||||
# Configure which authentication keys should be case-insensitive.
|
||||
# These keys will be lowercased upon creating or modifying a user and when used
|
||||
# to authenticate or find a user. Default is :email.
|
||||
config.case_insensitive_keys = [:email]
|
||||
|
||||
# Configure which authentication keys should have whitespace stripped.
|
||||
# These keys will have whitespace before and after removed upon creating or
|
||||
# modifying a user and when used to authenticate or find a user. Default is :email.
|
||||
config.strip_whitespace_keys = [:email]
|
||||
|
||||
# Tell if authentication through request.params is enabled. True by default.
|
||||
# It can be set to an array that will enable params authentication only for the
|
||||
# given strategies, for example, `config.params_authenticatable = [:database]` will
|
||||
# enable it only for database (email + password) authentication.
|
||||
# config.params_authenticatable = true
|
||||
|
||||
# Tell if authentication through HTTP Auth is enabled. False by default.
|
||||
# It can be set to an array that will enable http authentication only for the
|
||||
# given strategies, for example, `config.http_authenticatable = [:database]` will
|
||||
# enable it only for database authentication. The supported strategies are:
|
||||
# :database = Support basic authentication with authentication key + password
|
||||
config.http_authenticatable = [:pam, :database]
|
||||
|
||||
# If 401 status code should be returned for AJAX requests. True by default.
|
||||
# config.http_authenticatable_on_xhr = true
|
||||
|
||||
# The realm used in Http Basic Authentication. 'Application' by default.
|
||||
# config.http_authentication_realm = 'Application'
|
||||
|
||||
# It will change confirmation, password recovery and other workflows
|
||||
# to behave the same regardless if the e-mail provided was right or wrong.
|
||||
# Does not affect registerable.
|
||||
# See : https://github.com/plataformatec/devise/wiki/How-To:-Using-paranoid-mode,-avoid-user-enumeration-on-registerable
|
||||
config.paranoid = true
|
||||
|
||||
# By default Devise will store the user in session. You can skip storage for
|
||||
# particular strategies by setting this option.
|
||||
# Notice that if you are skipping storage for all authentication paths, you
|
||||
# may want to disable generating routes to Devise's sessions controller by
|
||||
# passing skip: :sessions to `devise_for` in your config/routes.rb
|
||||
config.skip_session_storage = [:http_auth]
|
||||
|
||||
# By default, Devise cleans up the CSRF token on authentication to
|
||||
# avoid CSRF token fixation attacks. This means that, when using AJAX
|
||||
# requests for sign in and sign up, you need to get a new CSRF token
|
||||
# from the server. You can disable this option at your own risk.
|
||||
# config.clean_up_csrf_token_on_authentication = true
|
||||
|
||||
# ==> Configuration for :database_authenticatable
|
||||
# For bcrypt, this is the cost for hashing the password and defaults to 10. If
|
||||
# using other encryptors, it sets how many times you want the password re-encrypted.
|
||||
#
|
||||
# Limiting the stretches to just one in testing will increase the performance of
|
||||
# your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use
|
||||
# a value less than 10 in other environments. Note that, for bcrypt (the default
|
||||
# encryptor), the cost increases exponentially with the number of stretches (e.g.
|
||||
# a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation).
|
||||
config.stretches = Rails.env.test? ? 1 : 10
|
||||
|
||||
# Setup a pepper to generate the encrypted password.
|
||||
# config.pepper = '104d16705f794923e77c5e5167b52452d00646dc952a2d30b541c24086e647012c7b9625f253c51912e455981e503446772973d5f1638631196c819d7137fad4'
|
||||
|
||||
# Send a notification to the original email when the user's email is changed.
|
||||
config.send_email_changed_notification = true
|
||||
|
||||
# Send a notification email when the user's password is changed
|
||||
config.send_password_change_notification = true
|
||||
|
||||
# ==> Configuration for :confirmable
|
||||
# A period that the user is allowed to access the website even without
|
||||
# confirming their account. For instance, if set to 2.days, the user will be
|
||||
# able to access the website for two days without confirming their account,
|
||||
# access will be blocked just in the third day. Default is 0.days, meaning
|
||||
# the user cannot access the website without confirming their account.
|
||||
# config.allow_unconfirmed_access_for = 2.days
|
||||
|
||||
# A period that the user is allowed to confirm their account before their
|
||||
# token becomes invalid. For example, if set to 3.days, the user can confirm
|
||||
# their account within 3 days after the mail was sent, but on the fourth day
|
||||
# their account can't be confirmed with the token any more.
|
||||
# Default is nil, meaning there is no restriction on how long a user can take
|
||||
# before confirming their account.
|
||||
config.confirm_within = 2.days
|
||||
|
||||
# If true, requires any email changes to be confirmed (exactly the same way as
|
||||
# initial account confirmation) to be applied. Requires additional unconfirmed_email
|
||||
# db field (see migrations). Until confirmed, new email is stored in
|
||||
# unconfirmed_email column, and copied to email column on successful confirmation.
|
||||
config.reconfirmable = true
|
||||
|
||||
# Defines which key will be used when confirming an account
|
||||
# config.confirmation_keys = [:email]
|
||||
|
||||
# ==> Configuration for :rememberable
|
||||
# The time the user will be remembered without asking for credentials again.
|
||||
config.remember_for = 1.year
|
||||
|
||||
# Invalidates all the remember me tokens when the user signs out.
|
||||
config.expire_all_remember_me_on_sign_out = true
|
||||
|
||||
# If true, extends the user's remember period when remembered via cookie.
|
||||
# config.extend_remember_period = false
|
||||
|
||||
# Options to be passed to the created cookie. For instance, you can set
|
||||
# secure: true in order to force SSL only cookies.
|
||||
config.rememberable_options = {}
|
||||
|
||||
# ==> Configuration for :validatable
|
||||
# Range for password length.
|
||||
config.password_length = 8..72
|
||||
|
||||
# Email regex used to validate email formats. It simply asserts that
|
||||
# one (and only one) @ exists in the given string. This is mainly
|
||||
# to give user feedback and not to assert the e-mail validity.
|
||||
# config.email_regexp = /\A[^@]+@[^@]+\z/
|
||||
|
||||
# ==> Configuration for :timeoutable
|
||||
# The time you want to timeout the user session without activity. After this
|
||||
# time the user will be asked for credentials again. Default is 30 minutes.
|
||||
# config.timeout_in = 30.minutes
|
||||
|
||||
# ==> Configuration for :lockable
|
||||
# Defines which strategy will be used to lock an account.
|
||||
# :failed_attempts = Locks an account after a number of failed attempts to sign in.
|
||||
# :none = No lock strategy. You should handle locking by yourself.
|
||||
# config.lock_strategy = :failed_attempts
|
||||
|
||||
# Defines which key will be used when locking and unlocking an account
|
||||
# config.unlock_keys = [:email]
|
||||
|
||||
# Defines which strategy will be used to unlock an account.
|
||||
# :email = Sends an unlock link to the user email
|
||||
# :time = Re-enables login after a certain amount of time (see :unlock_in below)
|
||||
# :both = Enables both strategies
|
||||
# :none = No unlock strategy. You should handle unlocking by yourself.
|
||||
# config.unlock_strategy = :both
|
||||
|
||||
# Number of authentication tries before locking an account if lock_strategy
|
||||
# is failed attempts.
|
||||
# config.maximum_attempts = 20
|
||||
|
||||
# Time interval to unlock the account if :time is enabled as unlock_strategy.
|
||||
# config.unlock_in = 1.hour
|
||||
|
||||
# Warn on the last attempt before the account is locked.
|
||||
# config.last_attempt_warning = true
|
||||
|
||||
# ==> Configuration for :recoverable
|
||||
#
|
||||
# Defines which key will be used when recovering the password for an account
|
||||
# config.reset_password_keys = [:email]
|
||||
|
||||
# Time interval you can reset your password with a reset password key.
|
||||
# Don't put a too small interval or your users won't have the time to
|
||||
# change their passwords.
|
||||
config.reset_password_within = 6.hours
|
||||
|
||||
# When set to false, does not sign a user in automatically after their password is
|
||||
# reset. Defaults to true, so a user is signed in automatically after a reset.
|
||||
config.sign_in_after_reset_password = false
|
||||
|
||||
# ==> Configuration for :encryptable
|
||||
# Allow you to use another encryption algorithm besides bcrypt (default). You can use
|
||||
# :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1,
|
||||
# :authlogic_sha512 (then you should set stretches above to 20 for default behavior)
|
||||
# and :restful_authentication_sha1 (then you should set stretches to 10, and copy
|
||||
# REST_AUTH_SITE_KEY to pepper).
|
||||
#
|
||||
# Require the `devise-encryptable` gem when using anything other than bcrypt
|
||||
# config.encryptor = :sha512
|
||||
|
||||
# ==> Scopes configuration
|
||||
# Turn scoped views on. Before rendering "sessions/new", it will first check for
|
||||
# "users/sessions/new". It's turned off by default because it's slower if you
|
||||
# are using only default views.
|
||||
# config.scoped_views = false
|
||||
|
||||
# Configure the default scope given to Warden. By default it's the first
|
||||
# devise role declared in your routes (usually :user).
|
||||
# config.default_scope = :user
|
||||
|
||||
# Set this configuration to false if you want /users/sign_out to sign out
|
||||
# only the current scope. By default, Devise signs out all scopes.
|
||||
# config.sign_out_all_scopes = true
|
||||
|
||||
# ==> Navigation configuration
|
||||
# Lists the formats that should be treated as navigational. Formats like
|
||||
# :html, should redirect to the sign in page when the user does not have
|
||||
# access, but formats like :xml or :json, should return 401.
|
||||
#
|
||||
# If you have any extra navigational formats, like :iphone or :mobile, you
|
||||
# should add them to the navigational formats lists.
|
||||
#
|
||||
# The "*/*" below is required to match Internet Explorer requests.
|
||||
# config.navigational_formats = ['*/*', :html]
|
||||
|
||||
# The default HTTP method used to sign out a resource. Default is :delete.
|
||||
config.sign_out_via = :delete
|
||||
|
||||
# ==> OmniAuth
|
||||
# Add a new OmniAuth provider. Check the wiki for more information on setting
|
||||
# up on your models and hooks.
|
||||
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
|
||||
|
||||
# ==> Warden configuration
|
||||
# If you want to use other strategies, that are not supported by Devise, or
|
||||
# change the failure app, you can configure them inside the config.warden block.
|
||||
#
|
||||
# config.warden do |manager|
|
||||
# manager.intercept_401 = false
|
||||
# manager.default_strategies(scope: :user).unshift :some_external_strategy
|
||||
# end
|
||||
|
||||
# ==> Mountable engine configurations
|
||||
# When using Devise inside an engine, let's call it `MyEngine`, and this engine
|
||||
# is mountable, there are some extra configurations to be taken into account.
|
||||
# The following options are available, assuming the engine is mounted as:
|
||||
#
|
||||
# mount MyEngine, at: '/my_engine'
|
||||
#
|
||||
# The router that invoked `devise_for`, in the example above, would be:
|
||||
# config.router_name = :my_engine
|
||||
#
|
||||
# When using OmniAuth, Devise cannot automatically set OmniAuth path,
|
||||
# so you need to do it manually. For the users scope, it would be:
|
||||
# config.omniauth_path_prefix = '/my_engine/users/auth'
|
||||
|
||||
if ENV['PAM_ENABLED'] == 'true'
|
||||
config.pam_authentication = true
|
||||
config.usernamefield = nil
|
||||
config.emailfield = 'email'
|
||||
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 }
|
||||
end
|
||||
|
||||
if ENV['LDAP_ENABLED'] == 'true'
|
||||
config.ldap_authentication = true
|
||||
config.check_at_sign = true
|
||||
config.ldap_host = ENV.fetch('LDAP_HOST', 'localhost')
|
||||
config.ldap_port = ENV.fetch('LDAP_PORT', 389).to_i
|
||||
config.ldap_method = ENV.fetch('LDAP_METHOD', :simple_tls).to_sym
|
||||
config.ldap_base = ENV.fetch('LDAP_BASE')
|
||||
config.ldap_bind_dn = ENV.fetch('LDAP_BIND_DN')
|
||||
config.ldap_password = ENV.fetch('LDAP_PASSWORD')
|
||||
config.ldap_uid = ENV.fetch('LDAP_UID', 'cn')
|
||||
config.ldap_mail = ENV.fetch('LDAP_MAIL', 'mail')
|
||||
config.ldap_tls_no_verify = ENV['LDAP_TLS_NO_VERIFY'] == 'true'
|
||||
config.ldap_search_filter = ENV.fetch('LDAP_SEARCH_FILTER', '(|(%{uid}=%{email})(%{mail}=%{email}))')
|
||||
config.ldap_uid_conversion_enabled = ENV['LDAP_UID_CONVERSION_ENABLED'] == 'true'
|
||||
config.ldap_uid_conversion_search = ENV.fetch('LDAP_UID_CONVERSION_SEARCH', '.,- ')
|
||||
config.ldap_uid_conversion_replace = ENV.fetch('LDAP_UID_CONVERSION_REPLACE', '_')
|
||||
end
|
||||
end
|
||||
@@ -1,178 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Doorkeeper.configure do
|
||||
# Change the ORM that doorkeeper will use (needs plugins)
|
||||
orm :active_record
|
||||
|
||||
# This block will be called to check whether the resource owner is authenticated or not.
|
||||
resource_owner_authenticator do
|
||||
current_user || redirect_to(new_user_session_url)
|
||||
end
|
||||
|
||||
resource_owner_from_credentials do |_routes|
|
||||
user = User.authenticate_with_ldap(email: request.params[:username], password: request.params[:password]) if Devise.ldap_authentication
|
||||
user ||= User.authenticate_with_pam(email: request.params[:username], password: request.params[:password]) if Devise.pam_authentication
|
||||
|
||||
if user.nil?
|
||||
user = User.find_by(email: request.params[:username])
|
||||
user = nil unless user&.valid_password?(request.params[:password])
|
||||
end
|
||||
|
||||
user unless user&.otp_required_for_login?
|
||||
end
|
||||
|
||||
# If you want to restrict access to the web interface for adding oauth authorized applications, you need to declare the block below.
|
||||
admin_authenticator do
|
||||
current_user&.admin? || redirect_to(new_user_session_url)
|
||||
end
|
||||
|
||||
# Authorization Code expiration time (default 10 minutes).
|
||||
# authorization_code_expires_in 10.minutes
|
||||
|
||||
# Access token expiration time (default 2 hours).
|
||||
# If you want to disable expiration, set this to nil.
|
||||
access_token_expires_in nil
|
||||
|
||||
# Assign a custom TTL for implicit grants.
|
||||
# custom_access_token_expires_in do |oauth_client|
|
||||
# oauth_client.application.additional_settings.implicit_oauth_expiration
|
||||
# end
|
||||
|
||||
# Use a custom class for generating the access token.
|
||||
# https://github.com/doorkeeper-gem/doorkeeper#custom-access-token-generator
|
||||
# access_token_generator "::Doorkeeper::JWT"
|
||||
|
||||
# The controller Doorkeeper::ApplicationController inherits from.
|
||||
# Defaults to ActionController::Base.
|
||||
# https://github.com/doorkeeper-gem/doorkeeper#custom-base-controller
|
||||
base_controller 'ApplicationController'
|
||||
|
||||
# Reuse access token for the same resource owner within an application (disabled by default)
|
||||
# Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
|
||||
reuse_access_token
|
||||
|
||||
# Issue access tokens with refresh token (disabled by default)
|
||||
# use_refresh_token
|
||||
|
||||
# Forbids creating/updating applications with arbitrary scopes that are
|
||||
# not in configuration, i.e. `default_scopes` or `optional_scopes`.
|
||||
# (Disabled by default)
|
||||
enforce_configured_scopes
|
||||
|
||||
# Provide support for an owner to be assigned to each registered application (disabled by default)
|
||||
# Optional parameter :confirmation => true (default false) if you want to enforce ownership of
|
||||
# a registered application
|
||||
# Note: you must also run the rails g doorkeeper:application_owner generator to provide the necessary support
|
||||
enable_application_owner
|
||||
|
||||
# Define access token scopes for your provider
|
||||
# For more information go to
|
||||
# https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes
|
||||
default_scopes :read
|
||||
optional_scopes :write,
|
||||
:'write:accounts',
|
||||
:'write:blocks',
|
||||
:'write:bookmarks',
|
||||
:'write:conversations',
|
||||
:'write:favourites',
|
||||
:'write:filters',
|
||||
:'write:follows',
|
||||
:'write:lists',
|
||||
:'write:media',
|
||||
:'write:mutes',
|
||||
:'write:notifications',
|
||||
:'write:reports',
|
||||
:'write:statuses',
|
||||
:read,
|
||||
:'read:accounts',
|
||||
:'read:blocks',
|
||||
:'read:bookmarks',
|
||||
:'read:favourites',
|
||||
:'read:filters',
|
||||
:'read:follows',
|
||||
:'read:lists',
|
||||
:'read:mutes',
|
||||
:'read:notifications',
|
||||
:'read:search',
|
||||
:'read:statuses',
|
||||
:follow,
|
||||
:push,
|
||||
:'admin:read',
|
||||
:'admin:read:accounts',
|
||||
:'admin:read:reports',
|
||||
:'admin:read:domain_allows',
|
||||
:'admin:read:domain_blocks',
|
||||
:'admin:read:ip_blocks',
|
||||
:'admin:read:email_domain_blocks',
|
||||
:'admin:read:canonical_email_blocks',
|
||||
:'admin:write',
|
||||
:'admin:write:accounts',
|
||||
:'admin:write:reports',
|
||||
:'admin:write:domain_allows',
|
||||
:'admin:write:domain_blocks',
|
||||
:'admin:write:ip_blocks',
|
||||
:'admin:write:email_domain_blocks',
|
||||
:'admin:write:canonical_email_blocks',
|
||||
:crypto
|
||||
|
||||
# Change the way client credentials are retrieved from the request object.
|
||||
# By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
|
||||
# falls back to the `:client_id` and `:client_secret` params from the `params` object.
|
||||
# Check out the wiki for more information on customization
|
||||
# client_credentials :from_basic, :from_params
|
||||
|
||||
# Change the way access token is authenticated from the request object.
|
||||
# By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
|
||||
# falls back to the `:access_token` or `:bearer_token` params from the `params` object.
|
||||
# Check out the wiki for more information on customization
|
||||
# access_token_methods :from_bearer_authorization, :from_access_token_param, :from_bearer_param
|
||||
|
||||
# Change the native redirect uri for client apps
|
||||
# When clients register with the following redirect uri, they won't be redirected to any server and the authorization code will be displayed within the provider
|
||||
# The value can be any string. Use nil to disable this feature. When disabled, clients must provide a valid URL
|
||||
# (Similar behaviour: https://developers.google.com/accounts/docs/OAuth2InstalledApp#choosingredirecturi)
|
||||
#
|
||||
# native_redirect_uri 'urn:ietf:wg:oauth:2.0:oob'
|
||||
|
||||
# Forces the usage of the HTTPS protocol in non-native redirect uris (enabled
|
||||
# by default in non-development environments). OAuth2 delegates security in
|
||||
# communication to the HTTPS protocol so it is wise to keep this enabled.
|
||||
#
|
||||
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.
|
||||
#
|
||||
# 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) }
|
||||
|
||||
# Specify what grant flows are enabled in array of Strings. The valid
|
||||
# strings and the flows they enable are:
|
||||
#
|
||||
# "authorization_code" => Authorization Code Grant Flow
|
||||
# "implicit" => Implicit Grant Flow
|
||||
# "password" => Resource Owner Password Credentials Grant Flow
|
||||
# "client_credentials" => Client Credentials Grant Flow
|
||||
#
|
||||
# If not specified, Doorkeeper enables authorization_code and
|
||||
# client_credentials.
|
||||
#
|
||||
# implicit and password grant flows have risks that you should understand
|
||||
# before enabling:
|
||||
# http://tools.ietf.org/html/rfc6819#section-4.4.2
|
||||
# http://tools.ietf.org/html/rfc6819#section-4.4.3
|
||||
#
|
||||
|
||||
grant_flows %w(authorization_code password client_credentials)
|
||||
|
||||
# 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|
|
||||
client.application.superapp?
|
||||
end
|
||||
|
||||
# WWW-Authenticate Realm (default "Doorkeeper").
|
||||
# realm "Doorkeeper"
|
||||
end
|
||||
@@ -1,7 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
if String.method_defined?(:blank_as?)
|
||||
class String
|
||||
alias blank? blank_as?
|
||||
end
|
||||
end
|
||||
@@ -1,5 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
if ENV['FFMPEG_BINARY'].present?
|
||||
FFMPEG.ffmpeg_binary = ENV['FFMPEG_BINARY']
|
||||
end
|
||||
@@ -1,10 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# 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.
|
||||
Rails.application.config.filter_parameters += [
|
||||
:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
|
||||
]
|
||||
@@ -1,41 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.configure do
|
||||
config.x.http_client_proxy = {}
|
||||
|
||||
if ENV['http_proxy'].present?
|
||||
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
|
||||
|
||||
host = proxy.host
|
||||
host = host[1...-1] if host[0] == '[' # for IPv6 address
|
||||
|
||||
config.x.http_client_proxy[:proxy] = {
|
||||
proxy_address: host,
|
||||
proxy_port: proxy.port,
|
||||
proxy_username: proxy.user,
|
||||
proxy_password: proxy.password,
|
||||
}.compact
|
||||
end
|
||||
|
||||
if ENV['http_hidden_proxy'].present?
|
||||
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
|
||||
|
||||
host = proxy.host
|
||||
host = host[1...-1] if host[0] == '[' # for IPv6 address
|
||||
|
||||
config.x.http_client_hidden_proxy[:proxy] = {
|
||||
proxy_address: host,
|
||||
proxy_port: proxy.port,
|
||||
proxy_username: proxy.user,
|
||||
proxy_password: proxy.password,
|
||||
}.compact
|
||||
end
|
||||
|
||||
config.x.access_to_hidden_service = ENV['ALLOW_ACCESS_TO_HIDDEN_SERVICE'] == 'true'
|
||||
end
|
||||
@@ -1,7 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
HttpLog.configure do |config|
|
||||
config.logger = Rails.logger
|
||||
config.color = { color: :yellow }
|
||||
config.compact_log = true
|
||||
end
|
||||
@@ -1,34 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Add new inflection rules using the following format. Inflections
|
||||
# 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.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 'DeepL'
|
||||
inflect.acronym 'DSL'
|
||||
|
||||
inflect.singular 'data', 'data'
|
||||
end
|
||||
@@ -1,4 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../../lib/json_ld/security'
|
||||
require_relative '../../lib/json_ld/identity'
|
||||
@@ -1,7 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Kaminari.configure do |config|
|
||||
config.default_per_page = 40
|
||||
config.window = 2
|
||||
config.outer_window = 1
|
||||
end
|
||||
@@ -1,9 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.configure do
|
||||
config.i18n.load_path += Dir[Rails.root.join('app', 'javascript', 'flavours', '*', 'names.{rb,yml}').to_s]
|
||||
config.i18n.load_path += Dir[Rails.root.join('app', 'javascript', 'flavours', '*', 'names', '*.{rb,yml}').to_s]
|
||||
config.i18n.load_path += Dir[Rails.root.join('app', 'javascript', 'skins', '*', '*', 'names.{rb,yml}').to_s]
|
||||
config.i18n.load_path += Dir[Rails.root.join('app', 'javascript', 'skins', '*', '*', 'names', '*.{rb,yml}').to_s]
|
||||
config.i18n.load_path += Dir[Rails.root.join('config', 'locales-glitch', '*.{rb,yml}').to_s]
|
||||
end
|
||||
@@ -1,5 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
ActionMailer::MailDeliveryJob.class_eval do
|
||||
discard_on ActiveJob::DeserializationError
|
||||
end
|
||||
@@ -1,7 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Mime::Type.register 'application/json', :json, %w(text/x-json application/jsonrequest application/jrd+json application/activity+json application/ld+json)
|
||||
Mime::Type.register 'text/xml', :xml, %w(application/xml application/atom+xml application/xrd+xml)
|
||||
|
||||
# WebP is not defined in Rack 2.2.
|
||||
Rack::Mime::MIME_TYPES['.webp'] = 'image/webp'
|
||||
@@ -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
|
||||
@@ -1,3 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Oj.default_options = { mode: :compat, time_format: :ruby, use_to_json: true }
|
||||
@@ -1,10 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'open-uri'
|
||||
|
||||
module OpenURI
|
||||
def self.redirectable?(uri1, uri2) # :nodoc:
|
||||
uri1.scheme.casecmp(uri2.scheme).zero? ||
|
||||
(/\A(?:http|https|ftp)\z/i.match?(uri1.scheme) && /\A(?:http|https|ftp)\z/i.match?(uri2.scheme))
|
||||
end
|
||||
end
|
||||
@@ -1,186 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Paperclip::DataUriAdapter.register
|
||||
Paperclip::ResponseWithLimitAdapter.register
|
||||
|
||||
Paperclip.interpolates :filename do |attachment, style|
|
||||
if style == :original
|
||||
attachment.original_filename
|
||||
else
|
||||
[basename(attachment, style), extension(attachment, style)].compact_blank!.join('.')
|
||||
end
|
||||
end
|
||||
|
||||
Paperclip.interpolates :prefix_path do |attachment, style|
|
||||
if attachment.storage_schema_version >= 1 && attachment.instance.respond_to?(:local?) && !attachment.instance.local?
|
||||
'cache' + File::SEPARATOR
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
Paperclip.interpolates :prefix_url do |attachment, style|
|
||||
if attachment.storage_schema_version >= 1 && attachment.instance.respond_to?(:local?) && !attachment.instance.local?
|
||||
'cache/'
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
Paperclip::Attachment.default_options.merge!(
|
||||
use_timestamp: false,
|
||||
path: ':prefix_url:class/:attachment/:id_partition/:style/:filename',
|
||||
storage: :fog
|
||||
)
|
||||
|
||||
if ENV['S3_ENABLED'] == 'true'
|
||||
require 'aws-sdk-s3'
|
||||
|
||||
s3_region = ENV.fetch('S3_REGION') { 'us-east-1' }
|
||||
s3_protocol = ENV.fetch('S3_PROTOCOL') { 'https' }
|
||||
s3_hostname = ENV.fetch('S3_HOSTNAME') { "s3-#{s3_region}.amazonaws.com" }
|
||||
|
||||
Paperclip::Attachment.default_options.merge!(
|
||||
storage: :s3,
|
||||
s3_protocol: s3_protocol,
|
||||
s3_host_name: s3_hostname,
|
||||
|
||||
s3_headers: {
|
||||
'X-Amz-Multipart-Threshold' => ENV.fetch('S3_MULTIPART_THRESHOLD') { 15.megabytes }.to_i,
|
||||
'Cache-Control' => 'public, max-age=315576000, immutable',
|
||||
},
|
||||
|
||||
s3_permissions: ENV.fetch('S3_PERMISSION') { 'public-read' },
|
||||
s3_region: s3_region,
|
||||
|
||||
s3_credentials: {
|
||||
bucket: ENV['S3_BUCKET'],
|
||||
access_key_id: ENV['AWS_ACCESS_KEY_ID'],
|
||||
secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
|
||||
},
|
||||
|
||||
s3_options: {
|
||||
signature_version: ENV.fetch('S3_SIGNATURE_VERSION') { 'v4' },
|
||||
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,
|
||||
}
|
||||
)
|
||||
|
||||
Paperclip::Attachment.default_options[:s3_permissions] = ->(*) { nil } 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',
|
||||
)
|
||||
|
||||
Paperclip::Attachment.default_options[:url] = ':s3_path_url'
|
||||
end
|
||||
|
||||
if ENV.has_key?('S3_ALIAS_HOST') || ENV.has_key?('S3_CLOUDFRONT_HOST')
|
||||
Paperclip::Attachment.default_options.merge!(
|
||||
url: ':s3_alias_url',
|
||||
s3_host_alias: ENV['S3_ALIAS_HOST'] || ENV['S3_CLOUDFRONT_HOST']
|
||||
)
|
||||
end
|
||||
|
||||
Paperclip::Attachment.default_options[:s3_headers]['X-Amz-Storage-Class'] = ENV['S3_STORAGE_CLASS'] if ENV.has_key?('S3_STORAGE_CLASS')
|
||||
|
||||
# Some S3-compatible providers might not actually be compatible with some APIs
|
||||
# used by kt-paperclip, see https://github.com/mastodon/mastodon/issues/16822
|
||||
# and https://github.com/mastodon/mastodon/issues/26394
|
||||
module Paperclip
|
||||
module Storage
|
||||
module S3Extensions
|
||||
def copy_to_local_file(style, local_dest_path)
|
||||
log("copying #{path(style)} to local file #{local_dest_path}")
|
||||
|
||||
options = {}
|
||||
options[:mode] = 'single_request' if ENV['S3_FORCE_SINGLE_REQUEST'] == 'true'
|
||||
options[:checksum_mode] = 'DISABLED' unless ENV['S3_ENABLE_CHECKSUM_MODE'] == 'true'
|
||||
|
||||
s3_object(style).download_file(local_dest_path, options)
|
||||
rescue Aws::Errors::ServiceError => e
|
||||
warn("#{e} - cannot copy #{path(style)} to local file #{local_dest_path}")
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Paperclip::Storage::S3.prepend(Paperclip::Storage::S3Extensions)
|
||||
elsif ENV['SWIFT_ENABLED'] == 'true'
|
||||
require 'fog/openstack'
|
||||
|
||||
Paperclip::Attachment.default_options.merge!(
|
||||
fog_credentials: {
|
||||
provider: 'OpenStack',
|
||||
openstack_username: ENV['SWIFT_USERNAME'],
|
||||
openstack_project_id: ENV['SWIFT_PROJECT_ID'],
|
||||
openstack_project_name: ENV['SWIFT_TENANT'],
|
||||
openstack_tenant: ENV['SWIFT_TENANT'], # Some OpenStack-v2 ignores project_name but needs tenant
|
||||
openstack_api_key: ENV['SWIFT_PASSWORD'],
|
||||
openstack_auth_url: ENV['SWIFT_AUTH_URL'],
|
||||
openstack_domain_name: ENV.fetch('SWIFT_DOMAIN_NAME') { 'default' },
|
||||
openstack_region: ENV['SWIFT_REGION'],
|
||||
openstack_cache_ttl: ENV.fetch('SWIFT_CACHE_TTL') { 60 },
|
||||
openstack_temp_url_key: ENV['SWIFT_TEMP_URL_KEY'],
|
||||
},
|
||||
|
||||
fog_file: { 'Cache-Control' => 'public, max-age=315576000, immutable' },
|
||||
|
||||
fog_directory: ENV['SWIFT_CONTAINER'],
|
||||
fog_host: ENV['SWIFT_OBJECT_URL'],
|
||||
fog_public: true
|
||||
)
|
||||
elsif ENV['AZURE_ENABLED'] == 'true'
|
||||
require 'paperclip-azure'
|
||||
|
||||
Paperclip::Attachment.default_options.merge!(
|
||||
storage: :azure,
|
||||
azure_options: {
|
||||
protocol: 'https',
|
||||
},
|
||||
azure_credentials: {
|
||||
storage_account_name: ENV['AZURE_STORAGE_ACCOUNT'],
|
||||
storage_access_key: ENV['AZURE_STORAGE_ACCESS_KEY'],
|
||||
container: ENV['AZURE_CONTAINER_NAME'],
|
||||
}
|
||||
)
|
||||
if ENV.has_key?('AZURE_ALIAS_HOST')
|
||||
Paperclip::Attachment.default_options.merge!(
|
||||
url: ':azure_alias_url',
|
||||
azure_host_alias: ENV['AZURE_ALIAS_HOST']
|
||||
)
|
||||
end
|
||||
else
|
||||
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',
|
||||
)
|
||||
end
|
||||
|
||||
Rails.application.reloader.to_prepare do
|
||||
Paperclip.options[:content_type_mappings] = { csv: Import::FILE_TYPES }
|
||||
end
|
||||
|
||||
# In some places in the code, we rescue this exception, but we don't always
|
||||
# load the S3 library, so it may be an undefined constant:
|
||||
|
||||
unless defined?(Seahorse)
|
||||
module Seahorse
|
||||
module Client
|
||||
class NetworkingError < StandardError; end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Set our ImageMagick security policy, but allow admins to override it
|
||||
ENV['MAGICK_CONFIGURE_PATH'] = begin
|
||||
imagemagick_config_paths = ENV.fetch('MAGICK_CONFIGURE_PATH', '').split(File::PATH_SEPARATOR)
|
||||
imagemagick_config_paths << Rails.root.join('config', 'imagemagick').expand_path.to_s
|
||||
imagemagick_config_paths.join(File::PATH_SEPARATOR)
|
||||
end
|
||||
@@ -1,12 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
# 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"
|
||||
# end
|
||||
@@ -1,3 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
PgHero.show_migrations = Rails.env.development?
|
||||
@@ -1,10 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Since Rails 6.1, ActionView adds preload links for javascript files
|
||||
# in the Links header per default.
|
||||
|
||||
# In our case, that will bloat headers too much and potentially cause
|
||||
# issues with reverse proxies. Furthermore, we don't need those links,
|
||||
# as we already output them as HTML link tags.
|
||||
|
||||
Rails.application.config.action_view.preload_links_header = false
|
||||
@@ -1,8 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../../lib/mastodon/premailer_webpack_strategy'
|
||||
|
||||
Premailer::Rails.config.merge!(remove_ids: true,
|
||||
adapter: :nokogiri,
|
||||
generate_text_part: false,
|
||||
strategies: [PremailerWebpackStrategy])
|
||||
@@ -1,153 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'doorkeeper/grape/authorization_decorator'
|
||||
|
||||
class Rack::Attack
|
||||
class Request
|
||||
def authenticated_token
|
||||
return @authenticated_token if defined?(@authenticated_token)
|
||||
|
||||
@authenticated_token = Doorkeeper::OAuth::Token.authenticate(
|
||||
Doorkeeper::Grape::AuthorizationDecorator.new(self),
|
||||
*Doorkeeper.configuration.access_token_methods
|
||||
)
|
||||
end
|
||||
|
||||
def remote_ip
|
||||
@remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s
|
||||
end
|
||||
|
||||
def throttleable_remote_ip
|
||||
@throttleable_remote_ip ||= begin
|
||||
ip = IPAddr.new(remote_ip)
|
||||
|
||||
if ip.ipv6?
|
||||
ip.mask(64)
|
||||
else
|
||||
ip
|
||||
end
|
||||
end.to_s
|
||||
end
|
||||
|
||||
def authenticated_user_id
|
||||
authenticated_token&.resource_owner_id
|
||||
end
|
||||
|
||||
def authenticated_token_id
|
||||
authenticated_token&.id
|
||||
end
|
||||
|
||||
def unauthenticated?
|
||||
!authenticated_user_id
|
||||
end
|
||||
|
||||
def api_request?
|
||||
path.start_with?('/api')
|
||||
end
|
||||
|
||||
def path_matches?(other_path)
|
||||
/\A#{Regexp.escape(other_path)}(\..*)?\z/ =~ path
|
||||
end
|
||||
|
||||
def web_request?
|
||||
!api_request?
|
||||
end
|
||||
|
||||
def paging_request?
|
||||
params['page'].present? || params['min_id'].present? || params['max_id'].present? || params['since_id'].present?
|
||||
end
|
||||
end
|
||||
|
||||
Rack::Attack.safelist('allow from localhost') do |req|
|
||||
req.remote_ip == '127.0.0.1' || req.remote_ip == '::1'
|
||||
end
|
||||
|
||||
Rack::Attack.blocklist('deny from blocklist') do |req|
|
||||
IpBlock.blocked?(req.remote_ip)
|
||||
end
|
||||
|
||||
throttle('throttle_authenticated_api', limit: 1_500, period: 5.minutes) do |req|
|
||||
req.authenticated_user_id if req.api_request?
|
||||
end
|
||||
|
||||
throttle('throttle_per_token_api', limit: 300, period: 5.minutes) do |req|
|
||||
req.authenticated_token_id if req.api_request?
|
||||
end
|
||||
|
||||
throttle('throttle_unauthenticated_api', limit: 300, period: 5.minutes) do |req|
|
||||
req.throttleable_remote_ip if req.api_request? && req.unauthenticated?
|
||||
end
|
||||
|
||||
throttle('throttle_api_media', limit: 30, period: 30.minutes) do |req|
|
||||
req.authenticated_user_id if req.post? && req.path.match?(%r{\A/api/v\d+/media\z}i)
|
||||
end
|
||||
|
||||
throttle('throttle_media_proxy', limit: 30, period: 10.minutes) do |req|
|
||||
req.throttleable_remote_ip if req.path.start_with?('/media_proxy')
|
||||
end
|
||||
|
||||
throttle('throttle_api_sign_up', limit: 5, period: 30.minutes) do |req|
|
||||
req.throttleable_remote_ip if req.post? && req.path == '/api/v1/accounts'
|
||||
end
|
||||
|
||||
throttle('throttle_authenticated_paging', limit: 300, period: 15.minutes) do |req|
|
||||
req.authenticated_user_id if req.paging_request?
|
||||
end
|
||||
|
||||
throttle('throttle_unauthenticated_paging', limit: 300, period: 15.minutes) do |req|
|
||||
req.throttleable_remote_ip if req.paging_request? && req.unauthenticated?
|
||||
end
|
||||
|
||||
API_DELETE_REBLOG_REGEX = %r{\A/api/v1/statuses/\d+/unreblog\z}
|
||||
API_DELETE_STATUS_REGEX = %r{\A/api/v1/statuses/\d+\z}
|
||||
|
||||
throttle('throttle_api_delete', limit: 30, period: 30.minutes) do |req|
|
||||
req.authenticated_user_id if (req.post? && req.path.match?(API_DELETE_REBLOG_REGEX)) || (req.delete? && req.path.match?(API_DELETE_STATUS_REGEX))
|
||||
end
|
||||
|
||||
throttle('throttle_sign_up_attempts/ip', limit: 25, period: 5.minutes) do |req|
|
||||
req.throttleable_remote_ip if req.post? && req.path_matches?('/auth')
|
||||
end
|
||||
|
||||
throttle('throttle_password_resets/ip', limit: 25, period: 5.minutes) do |req|
|
||||
req.throttleable_remote_ip if req.post? && req.path_matches?('/auth/password')
|
||||
end
|
||||
|
||||
throttle('throttle_password_resets/email', limit: 5, period: 30.minutes) do |req|
|
||||
req.params.dig('user', 'email').presence if req.post? && req.path_matches?('/auth/password')
|
||||
end
|
||||
|
||||
throttle('throttle_email_confirmations/ip', limit: 25, period: 5.minutes) do |req|
|
||||
req.throttleable_remote_ip if req.post? && (req.path_matches?('/auth/confirmation') || req.path == '/api/v1/emails/confirmations')
|
||||
end
|
||||
|
||||
throttle('throttle_email_confirmations/email', limit: 5, period: 30.minutes) do |req|
|
||||
if req.post? && req.path_matches?('/auth/password')
|
||||
req.params.dig('user', 'email').presence
|
||||
elsif req.post? && req.path == '/api/v1/emails/confirmations'
|
||||
req.authenticated_user_id
|
||||
end
|
||||
end
|
||||
|
||||
throttle('throttle_login_attempts/ip', limit: 25, period: 5.minutes) do |req|
|
||||
req.throttleable_remote_ip if req.post? && req.path_matches?('/auth/sign_in')
|
||||
end
|
||||
|
||||
throttle('throttle_login_attempts/email', limit: 25, period: 1.hour) do |req|
|
||||
req.session[:attempt_user_id] || req.params.dig('user', 'email').presence if req.post? && req.path_matches?('/auth/sign_in')
|
||||
end
|
||||
|
||||
self.throttled_responder = lambda do |request|
|
||||
now = Time.now.utc
|
||||
match_data = request.env['rack.attack.match_data']
|
||||
|
||||
headers = {
|
||||
'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),
|
||||
}
|
||||
|
||||
[429, headers, [{ error: I18n.t('errors.429') }.to_json]]
|
||||
end
|
||||
end
|
||||
@@ -1,9 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
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']
|
||||
|
||||
Rails.logger.info("Rate limit hit (#{req.env['rack.attack.match_type']}): #{req.ip} #{req.request_method} #{req.fullpath}")
|
||||
end
|
||||
@@ -1,3 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Redis.sadd_returns_boolean = false
|
||||
@@ -1,5 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.configure do
|
||||
config.x.max_session_activations = ENV['MAX_SESSION_ACTIVATIONS'] || 10
|
||||
end
|
||||
@@ -1,11 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# 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
|
||||
@@ -1,39 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../../lib/mastodon/sidekiq_middleware'
|
||||
|
||||
Sidekiq.configure_server do |config|
|
||||
config.redis = REDIS_SIDEKIQ_PARAMS
|
||||
|
||||
config.server_middleware do |chain|
|
||||
chain.add Mastodon::SidekiqMiddleware
|
||||
end
|
||||
|
||||
config.server_middleware do |chain|
|
||||
chain.add SidekiqUniqueJobs::Middleware::Server
|
||||
end
|
||||
|
||||
config.client_middleware do |chain|
|
||||
chain.add SidekiqUniqueJobs::Middleware::Client
|
||||
end
|
||||
|
||||
SidekiqUniqueJobs::Server.configure(config)
|
||||
end
|
||||
|
||||
Sidekiq.configure_client do |config|
|
||||
config.redis = REDIS_SIDEKIQ_PARAMS
|
||||
|
||||
config.client_middleware do |chain|
|
||||
chain.add SidekiqUniqueJobs::Middleware::Client
|
||||
end
|
||||
end
|
||||
|
||||
Sidekiq.logger.level = ::Logger.const_get(ENV.fetch('RAILS_LOG_LEVEL', 'info').upcase.to_s)
|
||||
|
||||
SidekiqUniqueJobs.configure do |config|
|
||||
config.reaper = :ruby
|
||||
config.reaper_count = 1000
|
||||
config.reaper_interval = 600
|
||||
config.reaper_timeout = 150
|
||||
config.lock_ttl = 50.days.to_i
|
||||
end
|
||||
@@ -1,243 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Use this setup block to configure all options available in SimpleForm.
|
||||
|
||||
module AppendComponent
|
||||
def append(_wrapper_options = nil)
|
||||
@append ||= begin
|
||||
options[:append].to_s.html_safe if options[:append].present?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module RecommendedComponent
|
||||
def recommended(_wrapper_options = nil)
|
||||
return unless options[:recommended]
|
||||
|
||||
key = options[:recommended].is_a?(Symbol) ? options[:recommended] : :recommended
|
||||
options[:label_text] = ->(raw_label_text, _required_label_text, _label_present) { safe_join([raw_label_text, ' ', content_tag(:span, I18n.t(key, scope: 'simple_form'), class: key)]) }
|
||||
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
module WarningHintComponent
|
||||
def warning_hint(_wrapper_options = nil)
|
||||
@warning_hint ||= begin
|
||||
options[:warning_hint].to_s.html_safe if options[:warning_hint].present?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module GlitchOnlyComponent
|
||||
def glitch_only(_wrapper_options = nil)
|
||||
return unless options[:glitch_only]
|
||||
|
||||
options[:label_text] = ->(raw_label_text, _required_label_text, _label_present) { safe_join([raw_label_text, ' ', content_tag(:span, I18n.t('simple_form.glitch_only'), class: 'glitch_only')]) }
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
SimpleForm.include_component(AppendComponent)
|
||||
SimpleForm.include_component(RecommendedComponent)
|
||||
SimpleForm.include_component(WarningHintComponent)
|
||||
SimpleForm.include_component(GlitchOnlyComponent)
|
||||
|
||||
SimpleForm.setup do |config|
|
||||
# Wrappers are used by the form builder to generate a
|
||||
# complete input. You can remove any component from the
|
||||
# wrapper, change the order or even add your own to the
|
||||
# stack. The options given below are used to wrap the
|
||||
# whole input.
|
||||
config.wrappers :default, class: :input, hint_class: :field_with_hint, error_class: :field_with_errors do |b|
|
||||
## Extensions enabled by default
|
||||
# Any of these extensions can be disabled for a
|
||||
# given input by passing: `f.input EXTENSION_NAME => false`.
|
||||
# You can make any of these extensions optional by
|
||||
# renaming `b.use` to `b.optional`.
|
||||
|
||||
# Determines whether to use HTML5 (:email, :url, ...)
|
||||
# and required attributes
|
||||
b.use :html5
|
||||
|
||||
# Calculates placeholders automatically from I18n
|
||||
# You can also pass a string as f.input placeholder: "Placeholder"
|
||||
b.use :placeholder
|
||||
|
||||
## Optional extensions
|
||||
# They are disabled unless you pass `f.input EXTENSION_NAME => true`
|
||||
# to the input. If so, they will retrieve the values from the model
|
||||
# if any exists. If you want to enable any of those
|
||||
# extensions by default, you can change `b.optional` to `b.use`.
|
||||
|
||||
# Calculates maxlength from length validations for string inputs
|
||||
b.optional :maxlength
|
||||
|
||||
# Calculates pattern from format validations for string inputs
|
||||
b.optional :pattern
|
||||
|
||||
# Calculates min and max from length validations for numeric inputs
|
||||
b.optional :min_max
|
||||
|
||||
# Calculates readonly automatically from readonly attributes
|
||||
b.optional :readonly
|
||||
|
||||
## Inputs
|
||||
b.use :input
|
||||
b.use :hint, wrap_with: { tag: :span, class: :hint }
|
||||
b.use :error, wrap_with: { tag: :span, class: :error }
|
||||
|
||||
## full_messages_for
|
||||
# If you want to display the full error message for the attribute, you can
|
||||
# use the component :full_error, like:
|
||||
#
|
||||
# b.use :full_error, wrap_with: { tag: :span, class: :error }
|
||||
end
|
||||
|
||||
config.wrappers :with_label, class: [:input, :with_label], hint_class: :field_with_hint, error_class: :field_with_errors do |b|
|
||||
b.use :html5
|
||||
|
||||
b.wrapper tag: :div, class: :label_input do |ba|
|
||||
ba.optional :recommended
|
||||
ba.optional :glitch_only
|
||||
ba.use :label
|
||||
|
||||
ba.wrapper tag: :div, class: :label_input__wrapper do |bb|
|
||||
bb.use :input
|
||||
bb.optional :append, wrap_with: { tag: :div, class: 'label_input__append' }
|
||||
end
|
||||
end
|
||||
|
||||
b.use :warning_hint, wrap_with: { tag: :span, class: [:hint, 'warning-hint'] }
|
||||
b.use :hint, wrap_with: { tag: :span, class: :hint }
|
||||
b.use :error, wrap_with: { tag: :span, class: :error }
|
||||
end
|
||||
|
||||
config.wrappers :with_floating_label, class: [:input, :with_floating_label], hint_class: :field_with_hint, error_class: :field_with_errors do |b|
|
||||
b.use :html5
|
||||
b.use :label_input, wrap_with: { tag: :div, class: :label_input }
|
||||
b.use :hint, wrap_with: { tag: :span, class: :hint }
|
||||
b.use :error, wrap_with: { tag: :span, class: :error }
|
||||
end
|
||||
|
||||
config.wrappers :with_block_label, class: [:input, :with_block_label], hint_class: :field_with_hint, error_class: :field_with_errors do |b|
|
||||
b.use :html5
|
||||
b.use :label
|
||||
b.use :warning_hint, wrap_with: { tag: :span, class: [:hint, 'warning-hint'] }
|
||||
b.use :hint, wrap_with: { tag: :span, class: :hint }
|
||||
b.use :input, wrap_with: { tag: :div, class: :label_input }
|
||||
b.use :error, wrap_with: { tag: :span, class: :error }
|
||||
end
|
||||
|
||||
# The default wrapper to be used by the FormBuilder.
|
||||
config.default_wrapper = :default
|
||||
|
||||
# Define the way to render check boxes / radio buttons with labels.
|
||||
# Defaults to :nested for bootstrap config.
|
||||
# inline: input + label
|
||||
# nested: label > input
|
||||
config.boolean_style = :nested
|
||||
|
||||
# Default class for buttons
|
||||
config.button_class = 'btn'
|
||||
|
||||
# Method used to tidy up errors. Specify any Rails Array method.
|
||||
# :first lists the first message for each field.
|
||||
# Use :to_sentence to list all errors for each field.
|
||||
# config.error_method = :first
|
||||
|
||||
# Default tag used for error notification helper.
|
||||
config.error_notification_tag = :div
|
||||
|
||||
# CSS class to add for error notification helper.
|
||||
config.error_notification_class = 'error_notification'
|
||||
|
||||
# ID to add for error notification helper.
|
||||
# config.error_notification_id = nil
|
||||
|
||||
# Series of attempts to detect a default label method for collection.
|
||||
# config.collection_label_methods = [ :to_label, :name, :title, :to_s ]
|
||||
|
||||
# Series of attempts to detect a default value method for collection.
|
||||
# config.collection_value_methods = [ :id, :to_s ]
|
||||
|
||||
# You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
|
||||
# config.collection_wrapper_tag = nil
|
||||
|
||||
# You can define the class to use on all collection wrappers. Defaulting to none.
|
||||
# config.collection_wrapper_class = nil
|
||||
|
||||
# You can wrap each item in a collection of radio/check boxes with a tag,
|
||||
# defaulting to :span.
|
||||
# config.item_wrapper_tag = :span
|
||||
|
||||
# You can define a class to use in all item wrappers. Defaulting to none.
|
||||
# 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}" }
|
||||
|
||||
# You can define the class to use on all labels. Default is nil.
|
||||
# config.label_class = nil
|
||||
|
||||
# You can define the default class to be used on forms. Can be overridden
|
||||
# with `html: { :class }`. Defaulting to none.
|
||||
# config.default_form_class = nil
|
||||
|
||||
# You can define which elements should obtain additional classes
|
||||
# config.generate_additional_classes_for = [:wrapper, :label, :input]
|
||||
|
||||
# Whether attributes are required by default (or not). Default is true.
|
||||
# config.required_by_default = true
|
||||
|
||||
# Tell browsers whether to use the native HTML5 validations (novalidate form option).
|
||||
# These validations are enabled in SimpleForm's internal config but disabled by default
|
||||
# in this configuration, which is recommended due to some quirks from different browsers.
|
||||
# To stop SimpleForm from generating the novalidate option, enabling the HTML5 validations,
|
||||
# change this configuration to true.
|
||||
config.browser_validations = false
|
||||
|
||||
# Collection of methods to detect if a file type was given.
|
||||
# config.file_methods = [ :mounted_as, :file?, :public_filename ]
|
||||
|
||||
# Custom mappings for input types. This should be a hash containing a regexp
|
||||
# to match as key, and the input type that will be used when the field name
|
||||
# matches the regexp as value.
|
||||
# config.input_mappings = { /count/ => :integer }
|
||||
|
||||
# Custom wrappers for input types. This should be a hash containing an input
|
||||
# type as key and the wrapper that will be used for all inputs with specified type.
|
||||
# config.wrapper_mappings = { string: :prepend }
|
||||
|
||||
# Namespaces where SimpleForm should look for custom input classes that
|
||||
# override default inputs.
|
||||
# config.custom_inputs_namespaces << "CustomInputs"
|
||||
|
||||
# Default priority for time_zone inputs.
|
||||
# config.time_zone_priority = nil
|
||||
|
||||
# Default priority for country inputs.
|
||||
# config.country_priority = nil
|
||||
|
||||
# When false, do not use translations for labels.
|
||||
# config.translate_labels = true
|
||||
|
||||
# Automatically discover new inputs in Rails' autoload path.
|
||||
# config.inputs_discovery = true
|
||||
|
||||
# Cache SimpleForm inputs discovery
|
||||
# config.cache_discovery = !Rails.env.development?
|
||||
|
||||
# Default class for inputs
|
||||
# config.input_class = nil
|
||||
|
||||
# Define the default class of the input wrapper of the boolean input.
|
||||
config.boolean_label_class = 'checkbox'
|
||||
|
||||
# Defines if the default input wrapper class should be included in radio
|
||||
# collection wrappers.
|
||||
# config.include_default_input_wrapper_class = true
|
||||
|
||||
# Defines which i18n scope will be used in Simple Form.
|
||||
# config.i18n_scope = 'simple_form'
|
||||
end
|
||||
@@ -1,5 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.configure do
|
||||
config.x.single_user_mode = ENV['SINGLE_USER_MODE'] == 'true'
|
||||
end
|
||||
@@ -1,15 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
if ENV['STATSD_ADDR'].present?
|
||||
host, port = ENV['STATSD_ADDR'].split(':')
|
||||
|
||||
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
|
||||
end
|
||||
@@ -1,8 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
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)]
|
||||
end
|
||||
@@ -1,4 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
StrongMigrations.start_after = 2017_09_24_022025
|
||||
StrongMigrations.target_version = 10
|
||||
@@ -1,5 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.reloader.to_prepare do
|
||||
ActionController::Base.log_warning_on_csrf_failure = false
|
||||
end
|
||||
@@ -1,13 +0,0 @@
|
||||
# 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
|
||||
end
|
||||
@@ -1,82 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Twitter::TwitterText
|
||||
class Configuration
|
||||
def emoji_parsing_enabled
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
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_balanced_parens] = /
|
||||
\(
|
||||
(?:
|
||||
#{REGEXEN[:valid_general_url_path_chars]}+
|
||||
|
|
||||
# allow one nested level of balanced parentheses
|
||||
(?:
|
||||
#{REGEXEN[:valid_general_url_path_chars]}*
|
||||
\(
|
||||
#{REGEXEN[:valid_general_url_path_chars]}+
|
||||
\)
|
||||
#{REGEXEN[:valid_general_url_path_chars]}*
|
||||
)
|
||||
)
|
||||
\)
|
||||
/iox
|
||||
# rubocop:disable Layout/LineLength
|
||||
UCHARS = '\u{A0}-\u{D7FF}\u{F900}-\u{FDCF}\u{FDF0}-\u{FFEF}\u{10000}-\u{1FFFD}\u{20000}-\u{2FFFD}\u{30000}-\u{3FFFD}\u{40000}-\u{4FFFD}\u{50000}-\u{5FFFD}\u{60000}-\u{6FFFD}\u{70000}-\u{7FFFD}\u{80000}-\u{8FFFD}\u{90000}-\u{9FFFD}\u{A0000}-\u{AFFFD}\u{B0000}-\u{BFFFD}\u{C0000}-\u{CFFFD}\u{D0000}-\u{DFFFD}\u{E1000}-\u{EFFFD}\u{E000}-\u{F8FF}\u{F0000}-\u{FFFFD}\u{100000}-\u{10FFFD}'
|
||||
# rubocop:enable Layout/LineLength
|
||||
REGEXEN[:valid_url_query_chars] = %r{[a-z0-9!?*'();:&=+$/%#\[\]\-_.,~|@\^#{UCHARS}]}iou
|
||||
REGEXEN[:valid_url_query_ending_chars] = %r{[a-z0-9_&=#/\-#{UCHARS}]}iou
|
||||
REGEXEN[:valid_url_path] = %r{(?:
|
||||
(?:
|
||||
#{REGEXEN[:valid_general_url_path_chars]}*
|
||||
(?:#{REGEXEN[:valid_url_balanced_parens]} #{REGEXEN[:valid_general_url_path_chars]}*)*
|
||||
#{REGEXEN[:valid_url_path_ending_chars]}
|
||||
)|(?:#{REGEXEN[:valid_general_url_path_chars]}+/)
|
||||
)}iox
|
||||
REGEXEN[:valid_url] = %r{
|
||||
( # $1 total match
|
||||
(#{REGEXEN[:valid_url_preceding_chars]}) # $2 Preceding character
|
||||
( # $3 URL
|
||||
((?:https?|dat|dweb|ipfs|ipns|ssb|gopher|gemini)://)? # $4 Protocol (optional)
|
||||
(#{REGEXEN[:valid_domain]}) # $5 Domain(s)
|
||||
(?::(#{REGEXEN[:valid_port_number]}))? # $6 Port number (optional)
|
||||
(/#{REGEXEN[:valid_url_path]}*)? # $7 URL Path and anchor
|
||||
(\?#{REGEXEN[:valid_url_query_chars]}*#{REGEXEN[:valid_url_query_ending_chars]})? # $8 Query String
|
||||
)
|
||||
)
|
||||
}iox
|
||||
REGEXEN[:validate_nodeid] = /(?:
|
||||
#{REGEXEN[:validate_url_unreserved]}|
|
||||
#{REGEXEN[:validate_url_pct_encoded]}|
|
||||
[!$()*+,;=]
|
||||
)/iox
|
||||
REGEXEN[:validate_resid] = /(?:
|
||||
#{REGEXEN[:validate_url_unreserved]}|
|
||||
#{REGEXEN[:validate_url_pct_encoded]}|
|
||||
#{REGEXEN[:validate_url_sub_delims]}
|
||||
)/iox
|
||||
REGEXEN[:valid_extended_uri] = %r{
|
||||
( # $1 total match
|
||||
(#{REGEXEN[:valid_url_preceding_chars]}) # $2 Preceding character
|
||||
( # $3 URL
|
||||
(
|
||||
(xmpp:) # Protocol
|
||||
(//#{REGEXEN[:validate_nodeid]}+@#{REGEXEN[:valid_domain]}/)? # Authority (optional)
|
||||
(#{REGEXEN[:validate_nodeid]}+@)? # Username in path (optional)
|
||||
(#{REGEXEN[:valid_domain]}) # Domain in path
|
||||
(/#{REGEXEN[:validate_resid]}+)? # Resource in path (optional)
|
||||
(\?#{REGEXEN[:valid_url_query_chars]}*#{REGEXEN[:valid_url_query_ending_chars]})? # Query String
|
||||
) | (
|
||||
(magnet:) # Protocol
|
||||
(\?#{REGEXEN[:valid_url_query_chars]}*#{REGEXEN[:valid_url_query_ending_chars]}) # Query String
|
||||
)
|
||||
)
|
||||
)
|
||||
}iox
|
||||
end
|
||||
end
|
||||
@@ -1,16 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.configure do
|
||||
# You can generate the keys using the following command (first is the private key, second is the public one)
|
||||
# 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)
|
||||
#
|
||||
# For more information visit https://rossta.net/blog/using-the-web-push-api-with-vapid.html
|
||||
|
||||
if Rails.env.production?
|
||||
config.x.vapid_private_key = ENV['VAPID_PRIVATE_KEY']
|
||||
config.x.vapid_public_key = ENV['VAPID_PUBLIC_KEY']
|
||||
end
|
||||
end
|
||||
@@ -1,26 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
WebAuthn.configure do |config|
|
||||
# This value needs to match `window.location.origin` evaluated by
|
||||
# the User Agent during registration and authentication ceremonies.
|
||||
config.origin = "#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}"
|
||||
|
||||
# Relying Party name for display purposes
|
||||
config.rp_name = "Mastodon"
|
||||
|
||||
# Optionally configure a client timeout hint, in milliseconds.
|
||||
# This hint specifies how long the browser should wait for an
|
||||
# attestation or an assertion response.
|
||||
# This hint may be overridden by the browser.
|
||||
# https://www.w3.org/TR/webauthn/#dom-publickeycredentialcreationoptions-timeout
|
||||
config.credential_options_timeout = 120_000
|
||||
|
||||
# You can optionally specify a different Relying Party ID
|
||||
# (https://www.w3.org/TR/webauthn/#relying-party-identifier)
|
||||
# if it differs from the default one.
|
||||
#
|
||||
# In this case the default would be "auth.example.com", but you can set it to
|
||||
# the suffix "example.com"
|
||||
#
|
||||
# config.rp_id = "example.com"
|
||||
end
|
||||
@@ -1,16 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# This file contains settings for ActionController::ParamsWrapper which
|
||||
# is enabled by default.
|
||||
|
||||
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
|
||||
ActiveSupport.on_load(:action_controller) do
|
||||
wrap_parameters format: [:json]
|
||||
end
|
||||
|
||||
# To enable root element in JSON for ActiveRecord objects.
|
||||
# ActiveSupport.on_load(:active_record) do
|
||||
# self.include_root_in_json = true
|
||||
# end
|
||||
@@ -1,73 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
SimpleNavigation::Configuration.run do |navigation|
|
||||
navigation.items do |n|
|
||||
n.item :web, safe_join([fa_icon('chevron-left fw'), t('settings.back')]), root_path
|
||||
|
||||
n.item :software_updates, safe_join([fa_icon('exclamation-circle fw'), t('admin.critical_update_pending')]), admin_software_updates_path, if: -> { ENV['UPDATE_CHECK_URL'] != '' && current_user.can?(:view_devops) && SoftwareUpdate.urgent_pending? }, html: { class: 'warning' }
|
||||
|
||||
n.item :profile, safe_join([fa_icon('user fw'), t('settings.profile')]), settings_profile_path, if: -> { current_user.functional? }, highlights_on: %r{/settings/profile|/settings/featured_tags|/settings/verification|/settings/privacy}
|
||||
|
||||
n.item :preferences, safe_join([fa_icon('cog fw'), t('settings.preferences')]), settings_preferences_path, if: -> { current_user.functional? } do |s|
|
||||
s.item :appearance, safe_join([fa_icon('desktop fw'), t('settings.appearance')]), settings_preferences_appearance_path
|
||||
s.item :notifications, safe_join([fa_icon('bell fw'), t('settings.notifications')]), settings_preferences_notifications_path
|
||||
s.item :other, safe_join([fa_icon('cog fw'), t('preferences.other')]), settings_preferences_other_path
|
||||
end
|
||||
|
||||
n.item :flavours, safe_join([fa_icon('paint-brush fw'), t('settings.flavours')]), settings_flavours_path do |flavours|
|
||||
Themes.instance.flavours.each do |flavour|
|
||||
flavours.item flavour.to_sym, safe_join([fa_icon('star fw'), t("flavours.#{flavour}.name", default: flavour)]), settings_flavour_path(flavour)
|
||||
end
|
||||
end
|
||||
|
||||
n.item :relationships, safe_join([fa_icon('users fw'), t('settings.relationships')]), relationships_path, if: -> { current_user.functional? }
|
||||
n.item :filters, safe_join([fa_icon('filter fw'), t('filters.index.title')]), filters_path, highlights_on: %r{/filters}, if: -> { current_user.functional? }
|
||||
n.item :statuses_cleanup, safe_join([fa_icon('history fw'), t('settings.statuses_cleanup')]), statuses_cleanup_path, if: -> { current_user.functional_or_moved? }
|
||||
|
||||
n.item :security, safe_join([fa_icon('lock fw'), t('settings.account')]), edit_user_registration_path do |s|
|
||||
s.item :password, safe_join([fa_icon('lock fw'), t('settings.account_settings')]), edit_user_registration_path, highlights_on: %r{/auth/edit|/settings/delete|/settings/migration|/settings/aliases|/settings/login_activities|^/disputes}
|
||||
s.item :two_factor_authentication, safe_join([fa_icon('mobile fw'), t('settings.two_factor_authentication')]), settings_two_factor_authentication_methods_path, highlights_on: %r{/settings/two_factor_authentication|/settings/otp_authentication|/settings/security_keys}
|
||||
s.item :authorized_apps, safe_join([fa_icon('list fw'), t('settings.authorized_apps')]), oauth_authorized_applications_path
|
||||
end
|
||||
|
||||
n.item :data, safe_join([fa_icon('cloud-download fw'), t('settings.import_and_export')]), settings_export_path do |s|
|
||||
s.item :import, safe_join([fa_icon('cloud-upload fw'), t('settings.import')]), settings_imports_path, if: -> { current_user.functional? }
|
||||
s.item :export, safe_join([fa_icon('cloud-download fw'), t('settings.export')]), settings_export_path
|
||||
end
|
||||
|
||||
n.item :invites, safe_join([fa_icon('user-plus fw'), t('invites.title')]), invites_path, if: -> { current_user.can?(:invite_users) && current_user.functional? }
|
||||
n.item :development, safe_join([fa_icon('code fw'), t('settings.development')]), settings_applications_path, if: -> { current_user.functional? }
|
||||
|
||||
n.item :trends, safe_join([fa_icon('fire fw'), t('admin.trends.title')]), admin_trends_statuses_path, if: -> { current_user.can?(:manage_taxonomies) } do |s|
|
||||
s.item :statuses, safe_join([fa_icon('comments-o fw'), t('admin.trends.statuses.title')]), admin_trends_statuses_path, highlights_on: %r{/admin/trends/statuses}
|
||||
s.item :tags, safe_join([fa_icon('hashtag fw'), t('admin.trends.tags.title')]), admin_trends_tags_path, highlights_on: %r{/admin/tags|/admin/trends/tags}
|
||||
s.item :links, safe_join([fa_icon('newspaper-o fw'), t('admin.trends.links.title')]), admin_trends_links_path, highlights_on: %r{/admin/trends/links}
|
||||
end
|
||||
|
||||
n.item :moderation, safe_join([fa_icon('gavel fw'), t('moderation.title')]), nil, if: -> { current_user.can?(:manage_reports, :view_audit_log, :manage_users, :manage_invites, :manage_taxonomies, :manage_federation, :manage_blocks) } do |s|
|
||||
s.item :reports, safe_join([fa_icon('flag fw'), t('admin.reports.title')]), admin_reports_path, highlights_on: %r{/admin/reports}, if: -> { current_user.can?(:manage_reports) }
|
||||
s.item :accounts, safe_join([fa_icon('users fw'), t('admin.accounts.title')]), admin_accounts_path(origin: 'local'), highlights_on: %r{/admin/accounts|/admin/pending_accounts|/admin/disputes|/admin/users}, if: -> { current_user.can?(:manage_users) }
|
||||
s.item :invites, safe_join([fa_icon('user-plus fw'), t('admin.invites.title')]), admin_invites_path, if: -> { current_user.can?(:manage_invites) }
|
||||
s.item :follow_recommendations, safe_join([fa_icon('user-plus fw'), t('admin.follow_recommendations.title')]), admin_follow_recommendations_path, highlights_on: %r{/admin/follow_recommendations}, if: -> { current_user.can?(:manage_taxonomies) }
|
||||
s.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_path(limited: limited_federation_mode? ? nil : '1'), highlights_on: %r{/admin/instances|/admin/domain_blocks|/admin/domain_allows}, if: -> { current_user.can?(:manage_federation) }
|
||||
s.item :email_domain_blocks, safe_join([fa_icon('envelope fw'), t('admin.email_domain_blocks.title')]), admin_email_domain_blocks_path, highlights_on: %r{/admin/email_domain_blocks}, if: -> { current_user.can?(:manage_blocks) }
|
||||
s.item :ip_blocks, safe_join([fa_icon('ban fw'), t('admin.ip_blocks.title')]), admin_ip_blocks_path, highlights_on: %r{/admin/ip_blocks}, if: -> { current_user.can?(:manage_blocks) }
|
||||
s.item :action_logs, safe_join([fa_icon('bars fw'), t('admin.action_logs.title')]), admin_action_logs_path, if: -> { current_user.can?(:view_audit_log) }
|
||||
end
|
||||
|
||||
n.item :admin, safe_join([fa_icon('cogs fw'), t('admin.title')]), nil, if: -> { current_user.can?(:view_dashboard, :manage_settings, :manage_rules, :manage_announcements, :manage_custom_emojis, :manage_webhooks, :manage_federation) } do |s|
|
||||
s.item :dashboard, safe_join([fa_icon('tachometer fw'), t('admin.dashboard.title')]), admin_dashboard_path, if: -> { current_user.can?(:view_dashboard) }
|
||||
s.item :settings, safe_join([fa_icon('cogs fw'), t('admin.settings.title')]), admin_settings_path, if: -> { current_user.can?(:manage_settings) }, highlights_on: %r{/admin/settings}
|
||||
s.item :rules, safe_join([fa_icon('gavel fw'), t('admin.rules.title')]), admin_rules_path, highlights_on: %r{/admin/rules}, if: -> { current_user.can?(:manage_rules) }
|
||||
s.item :roles, safe_join([fa_icon('vcard fw'), t('admin.roles.title')]), admin_roles_path, highlights_on: %r{/admin/roles}, if: -> { current_user.can?(:manage_roles) }
|
||||
s.item :announcements, safe_join([fa_icon('bullhorn fw'), t('admin.announcements.title')]), admin_announcements_path, highlights_on: %r{/admin/announcements}, if: -> { current_user.can?(:manage_announcements) }
|
||||
s.item :custom_emojis, safe_join([fa_icon('smile-o fw'), t('admin.custom_emojis.title')]), admin_custom_emojis_path, highlights_on: %r{/admin/custom_emojis}, if: -> { current_user.can?(:manage_custom_emojis) }
|
||||
s.item :webhooks, safe_join([fa_icon('inbox fw'), t('admin.webhooks.title')]), admin_webhooks_path, highlights_on: %r{/admin/webhooks}, if: -> { current_user.can?(:manage_webhooks) }
|
||||
s.item :relays, safe_join([fa_icon('exchange fw'), t('admin.relays.title')]), admin_relays_path, highlights_on: %r{/admin/relays}, if: -> { !limited_federation_mode? && current_user.can?(:manage_federation) }
|
||||
end
|
||||
|
||||
n.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_path, link_html: { target: 'sidekiq' }, if: -> { current_user.can?(:view_devops) }
|
||||
n.item :pghero, safe_join([fa_icon('database fw'), 'PgHero']), pghero_path, link_html: { target: 'pghero' }, if: -> { current_user.can?(:view_devops) }
|
||||
n.item :logout, safe_join([fa_icon('sign-out fw'), t('auth.logout')]), destroy_user_session_path, link_html: { 'data-method' => 'delete' }
|
||||
end
|
||||
end
|
||||
@@ -1,41 +0,0 @@
|
||||
databases:
|
||||
primary:
|
||||
# Database URL (defaults to app database)
|
||||
# url: <%= ENV["DATABASE_URL"] %>
|
||||
|
||||
# Add more databases
|
||||
# other:
|
||||
# url: <%= ENV["OTHER_DATABASE_URL"] %>
|
||||
|
||||
# Minimum time for long running queries
|
||||
# long_running_query_sec: 60
|
||||
|
||||
# Minimum average time for slow queries
|
||||
# slow_query_ms: 20
|
||||
|
||||
# Minimum calls for slow queries
|
||||
# slow_query_calls: 100
|
||||
|
||||
# Minimum connections for high connections warning
|
||||
# total_connections_threshold: 500
|
||||
|
||||
# Statement timeout for explain
|
||||
# explain_timeout_sec: 10
|
||||
|
||||
# Time zone (defaults to app time zone)
|
||||
# time_zone: "Pacific Time (US & Canada)"
|
||||
|
||||
# Basic authentication
|
||||
# username: admin
|
||||
# password: secret
|
||||
|
||||
# Stats database URL (defaults to app database)
|
||||
# stats_database_url: <%= ENV["PGHERO_STATS_DATABASE_URL"] %>
|
||||
|
||||
# AWS configuration (defaults to app AWS config)
|
||||
# also need aws_db_instance_identifier with each database
|
||||
# aws_access_key_id: ...
|
||||
# aws_secret_access_key: ...
|
||||
# aws_region: us-east-1
|
||||
|
||||
override_csp: false
|
||||
@@ -1,28 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
persistent_timeout ENV.fetch('PERSISTENT_TIMEOUT') { 20 }.to_i
|
||||
|
||||
max_threads_count = ENV.fetch('MAX_THREADS') { 5 }.to_i
|
||||
min_threads_count = ENV.fetch('MIN_THREADS') { max_threads_count }.to_i
|
||||
threads min_threads_count, max_threads_count
|
||||
|
||||
if ENV['SOCKET']
|
||||
bind "unix://#{ENV['SOCKET']}"
|
||||
else
|
||||
bind "tcp://#{ENV.fetch('BIND', '127.0.0.1')}:#{ENV.fetch('PORT', 3000)}"
|
||||
end
|
||||
|
||||
environment ENV.fetch('RAILS_ENV') { 'development' }
|
||||
workers ENV.fetch('WEB_CONCURRENCY') { 2 }.to_i
|
||||
|
||||
preload_app!
|
||||
|
||||
on_worker_boot do
|
||||
ActiveSupport.on_load(:active_record) do
|
||||
ActiveRecord::Base.establish_connection
|
||||
end
|
||||
end
|
||||
|
||||
plugin :tmp_restart
|
||||
|
||||
set_remote_address(proxy_protocol: :v1) if ENV['PROXY_PROTO_V1'] == 'true'
|
||||
192
config/routes.rb
192
config/routes.rb
@@ -1,192 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'sidekiq_unique_jobs/web'
|
||||
require 'sidekiq-scheduler/web'
|
||||
|
||||
Rails.application.routes.draw do
|
||||
# Paths of routes on the web app that to not require to be indexed or
|
||||
# have alternative format representations requiring separate controllers
|
||||
web_app_paths = %w(
|
||||
/getting-started
|
||||
/getting-started-misc
|
||||
/keyboard-shortcuts
|
||||
/home
|
||||
/public
|
||||
/public/local
|
||||
/public/remote
|
||||
/conversations
|
||||
/lists/(*any)
|
||||
/notifications
|
||||
/favourites
|
||||
/bookmarks
|
||||
/pinned
|
||||
/start
|
||||
/directory
|
||||
/explore/(*any)
|
||||
/search
|
||||
/publish
|
||||
/follow_requests
|
||||
/blocks
|
||||
/domain_blocks
|
||||
/mutes
|
||||
/followed_tags
|
||||
/statuses/(*any)
|
||||
/deck/(*any)
|
||||
).freeze
|
||||
|
||||
root 'home#index'
|
||||
|
||||
mount LetterOpenerWeb::Engine, at: 'letter_opener' if Rails.env.development?
|
||||
|
||||
get 'health', to: 'health#show'
|
||||
|
||||
authenticate :user, lambda { |u| u.role&.can?(:view_devops) } do
|
||||
mount Sidekiq::Web, at: 'sidekiq', as: :sidekiq
|
||||
mount PgHero::Engine, at: 'pghero', as: :pghero
|
||||
end
|
||||
|
||||
use_doorkeeper do
|
||||
controllers authorizations: 'oauth/authorizations',
|
||||
authorized_applications: 'oauth/authorized_applications',
|
||||
tokens: 'oauth/tokens'
|
||||
end
|
||||
|
||||
get '.well-known/host-meta', to: 'well_known/host_meta#show', as: :host_meta, defaults: { format: 'xml' }
|
||||
get '.well-known/nodeinfo', to: 'well_known/nodeinfo#index', as: :nodeinfo, defaults: { format: 'json' }
|
||||
get '.well-known/webfinger', to: 'well_known/webfinger#show', as: :webfinger
|
||||
get '.well-known/change-password', to: redirect('/auth/edit')
|
||||
get '.well-known/proxy', to: redirect { |_, request| "/authorize_interaction?#{request.params.to_query}" }
|
||||
|
||||
get '/nodeinfo/2.0', to: 'well_known/nodeinfo#show', as: :nodeinfo_schema
|
||||
|
||||
get 'manifest', to: 'manifests#show', defaults: { format: 'json' }
|
||||
get 'intent', to: 'intents#show'
|
||||
get 'custom.css', to: 'custom_css#show', as: :custom_css
|
||||
|
||||
get 'remote_interaction_helper', to: 'remote_interaction_helper#index'
|
||||
|
||||
resource :instance_actor, path: 'actor', only: [:show] do
|
||||
resource :inbox, only: [:create], module: :activitypub
|
||||
resource :outbox, only: [:show], module: :activitypub
|
||||
end
|
||||
|
||||
devise_scope :user do
|
||||
get '/invite/:invite_code', to: 'auth/registrations#new', as: :public_invite
|
||||
|
||||
resource :unsubscribe, only: [:show, :create], controller: :mail_subscriptions
|
||||
|
||||
namespace :auth do
|
||||
resource :setup, only: [:show, :update], controller: :setup
|
||||
resource :challenge, only: [:create], controller: :challenges
|
||||
get 'sessions/security_key_options', to: 'sessions#webauthn_options'
|
||||
post 'captcha_confirmation', to: 'confirmations#confirm_captcha', as: :captcha_confirmation
|
||||
end
|
||||
end
|
||||
|
||||
devise_for :users, path: 'auth', format: false, controllers: {
|
||||
omniauth_callbacks: 'auth/omniauth_callbacks',
|
||||
sessions: 'auth/sessions',
|
||||
registrations: 'auth/registrations',
|
||||
passwords: 'auth/passwords',
|
||||
confirmations: 'auth/confirmations',
|
||||
}
|
||||
|
||||
get '/users/:username', to: redirect('/@%{username}'), constraints: lambda { |req| req.format.nil? || req.format.html? }
|
||||
get '/users/:username/following', to: redirect('/@%{username}/following'), constraints: lambda { |req| req.format.nil? || req.format.html? }
|
||||
get '/users/:username/followers', to: redirect('/@%{username}/followers'), constraints: lambda { |req| req.format.nil? || req.format.html? }
|
||||
get '/users/:username/statuses/:id', to: redirect('/@%{username}/%{id}'), constraints: lambda { |req| req.format.nil? || req.format.html? }
|
||||
get '/authorize_follow', to: redirect { |_, request| "/authorize_interaction?#{request.params.to_query}" }
|
||||
|
||||
resources :accounts, path: 'users', only: [:show], param: :username do
|
||||
resources :statuses, only: [:show] do
|
||||
member do
|
||||
get :activity
|
||||
get :embed
|
||||
end
|
||||
|
||||
resources :replies, only: [:index], module: :activitypub
|
||||
end
|
||||
|
||||
resources :followers, only: [:index], controller: :follower_accounts
|
||||
resources :following, only: [:index], controller: :following_accounts
|
||||
|
||||
resource :outbox, only: [:show], module: :activitypub
|
||||
resource :inbox, only: [:create], module: :activitypub
|
||||
resource :claim, only: [:create], module: :activitypub
|
||||
resources :collections, only: [:show], module: :activitypub
|
||||
resource :followers_synchronization, only: [:show], module: :activitypub
|
||||
end
|
||||
|
||||
resource :inbox, only: [:create], module: :activitypub
|
||||
|
||||
get '/:encoded_at(*path)', to: redirect("/@%{path}"), constraints: { encoded_at: /%40/ }
|
||||
|
||||
constraints(username: %r{[^@/.]+}) do
|
||||
get '/@:username', to: 'accounts#show', as: :short_account
|
||||
get '/@:username/with_replies', to: 'accounts#show', as: :short_account_with_replies
|
||||
get '/@:username/media', to: 'accounts#show', as: :short_account_media
|
||||
get '/@:username/tagged/:tag', to: 'accounts#show', as: :short_account_tag
|
||||
end
|
||||
|
||||
constraints(account_username: %r{[^@/.]+}) do
|
||||
get '/@:account_username/following', to: 'following_accounts#index'
|
||||
get '/@:account_username/followers', to: 'follower_accounts#index'
|
||||
get '/@:account_username/:id', to: 'statuses#show', as: :short_account_status
|
||||
get '/@:account_username/:id/embed', to: 'statuses#embed', as: :embed_short_account_status
|
||||
end
|
||||
|
||||
get '/@:username_with_domain/(*any)', to: 'home#index', constraints: { username_with_domain: %r{([^/])+?} }, format: false
|
||||
get '/settings', to: redirect('/settings/profile')
|
||||
|
||||
draw(:settings)
|
||||
|
||||
namespace :disputes do
|
||||
resources :strikes, only: [:show, :index] do
|
||||
resource :appeal, only: [:create]
|
||||
end
|
||||
end
|
||||
|
||||
resources :media, only: [:show] do
|
||||
get :player
|
||||
end
|
||||
|
||||
resources :tags, only: [:show]
|
||||
resources :emojis, only: [:show]
|
||||
resources :invites, only: [:index, :create, :destroy]
|
||||
resources :filters, except: [:show] do
|
||||
resources :statuses, only: [:index], controller: 'filters/statuses' do
|
||||
collection do
|
||||
post :batch
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
resource :relationships, only: [:show, :update]
|
||||
resource :statuses_cleanup, controller: :statuses_cleanup, only: [:show, :update]
|
||||
|
||||
get '/media_proxy/:id/(*any)', to: 'media_proxy#show', as: :media_proxy, format: false
|
||||
get '/backups/:id/download', to: 'backups#download', as: :download_backup, format: false
|
||||
|
||||
resource :authorize_interaction, only: [:show]
|
||||
resource :share, only: [:show]
|
||||
|
||||
draw(:admin)
|
||||
|
||||
get '/admin', to: redirect('/admin/dashboard', status: 302)
|
||||
|
||||
draw(:api)
|
||||
|
||||
web_app_paths.each do |path|
|
||||
get path, to: 'home#index'
|
||||
end
|
||||
|
||||
get '/web/(*any)', to: redirect('/%{any}', status: 302), as: :web, defaults: { any: '' }, format: false
|
||||
get '/about', to: 'about#show'
|
||||
get '/about/more', to: redirect('/about')
|
||||
|
||||
get '/privacy-policy', to: 'privacy#show', as: :privacy_policy
|
||||
get '/terms', to: redirect('/privacy-policy')
|
||||
|
||||
match '/', via: [:post, :put, :patch, :delete], to: 'application#raise_not_found', format: false
|
||||
match '*unmatched_route', via: :all, to: 'application#raise_not_found', format: false
|
||||
end
|
||||
@@ -1,207 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
namespace :admin do
|
||||
get '/dashboard', to: 'dashboard#index'
|
||||
|
||||
resources :domain_allows, only: [:new, :create, :destroy]
|
||||
resources :domain_blocks, only: [:new, :create, :destroy, :update, :edit] do
|
||||
collection do
|
||||
post :batch
|
||||
end
|
||||
end
|
||||
|
||||
resources :export_domain_allows, only: [:new] do
|
||||
collection do
|
||||
get :export, constraints: { format: :csv }
|
||||
post :import
|
||||
end
|
||||
end
|
||||
|
||||
resources :export_domain_blocks, only: [:new] do
|
||||
collection do
|
||||
get :export, constraints: { format: :csv }
|
||||
post :import
|
||||
end
|
||||
end
|
||||
|
||||
resources :email_domain_blocks, only: [:index, :new, :create] do
|
||||
collection do
|
||||
post :batch
|
||||
end
|
||||
end
|
||||
|
||||
resources :action_logs, only: [:index]
|
||||
resources :warning_presets, except: [:new, :show]
|
||||
|
||||
resources :announcements, except: [:show] do
|
||||
member do
|
||||
post :publish
|
||||
post :unpublish
|
||||
end
|
||||
end
|
||||
|
||||
get '/settings', to: redirect('/admin/settings/branding')
|
||||
get '/settings/edit', to: redirect('/admin/settings/branding')
|
||||
|
||||
namespace :settings do
|
||||
resource :branding, only: [:show, :update], controller: 'branding'
|
||||
resource :registrations, only: [:show, :update], controller: 'registrations'
|
||||
resource :content_retention, only: [:show, :update], controller: 'content_retention'
|
||||
resource :about, only: [:show, :update], controller: 'about'
|
||||
resource :appearance, only: [:show, :update], controller: 'appearance'
|
||||
resource :discovery, only: [:show, :update], controller: 'discovery'
|
||||
resource :other, only: [:show, :update], controller: 'other'
|
||||
end
|
||||
|
||||
resources :site_uploads, only: [:destroy]
|
||||
|
||||
resources :invites, only: [:index, :create, :destroy] do
|
||||
collection do
|
||||
post :deactivate_all
|
||||
end
|
||||
end
|
||||
|
||||
resources :relays, only: [:index, :new, :create, :destroy] do
|
||||
member do
|
||||
post :enable
|
||||
post :disable
|
||||
end
|
||||
end
|
||||
|
||||
resources :instances, only: [:index, :show, :destroy], constraints: { id: %r{[^/]+} }, format: 'html' do
|
||||
member do
|
||||
post :clear_delivery_errors
|
||||
post :restart_delivery
|
||||
post :stop_delivery
|
||||
end
|
||||
end
|
||||
|
||||
resources :rules, only: [:index, :create, :edit, :update, :destroy]
|
||||
|
||||
resources :webhooks do
|
||||
member do
|
||||
post :enable
|
||||
post :disable
|
||||
end
|
||||
|
||||
resource :secret, only: [], controller: 'webhooks/secrets' do
|
||||
post :rotate
|
||||
end
|
||||
end
|
||||
|
||||
resources :reports, only: [:index, :show] do
|
||||
resources :actions, only: [:create], controller: 'reports/actions' do
|
||||
collection do
|
||||
post :preview
|
||||
end
|
||||
end
|
||||
|
||||
member do
|
||||
post :assign_to_self
|
||||
post :unassign
|
||||
post :reopen
|
||||
post :resolve
|
||||
end
|
||||
end
|
||||
|
||||
resources :report_notes, only: [:create, :destroy]
|
||||
|
||||
resources :accounts, only: [:index, :show, :destroy] do
|
||||
member do
|
||||
post :enable
|
||||
post :unsensitive
|
||||
post :unsilence
|
||||
post :unsuspend
|
||||
post :redownload
|
||||
post :remove_avatar
|
||||
post :remove_header
|
||||
post :memorialize
|
||||
post :approve
|
||||
post :reject
|
||||
post :unblock_email
|
||||
end
|
||||
|
||||
collection do
|
||||
post :batch
|
||||
end
|
||||
|
||||
resource :change_email, only: [:show, :update]
|
||||
resource :reset, only: [:create]
|
||||
resource :action, only: [:new, :create], controller: 'account_actions'
|
||||
|
||||
resources :statuses, only: [:index, :show] do
|
||||
collection do
|
||||
post :batch
|
||||
end
|
||||
end
|
||||
|
||||
resources :relationships, only: [:index]
|
||||
|
||||
resource :confirmation, only: [:create] do
|
||||
collection do
|
||||
post :resend
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
resources :users, only: [] do
|
||||
resource :two_factor_authentication, only: [:destroy], controller: 'users/two_factor_authentications'
|
||||
resource :role, only: [:show, :update], controller: 'users/roles'
|
||||
end
|
||||
|
||||
resources :custom_emojis, only: [:index, :new, :create] do
|
||||
collection do
|
||||
post :batch
|
||||
end
|
||||
end
|
||||
|
||||
resources :ip_blocks, only: [:index, :new, :create] do
|
||||
collection do
|
||||
post :batch
|
||||
end
|
||||
end
|
||||
|
||||
resources :roles, except: [:show]
|
||||
resources :account_moderation_notes, only: [:create, :destroy]
|
||||
resource :follow_recommendations, only: [:show, :update]
|
||||
resources :tags, only: [:show, :update]
|
||||
|
||||
namespace :trends do
|
||||
resources :links, only: [:index] do
|
||||
collection do
|
||||
post :batch
|
||||
end
|
||||
end
|
||||
|
||||
resources :tags, only: [:index] do
|
||||
collection do
|
||||
post :batch
|
||||
end
|
||||
end
|
||||
|
||||
resources :statuses, only: [:index] do
|
||||
collection do
|
||||
post :batch
|
||||
end
|
||||
end
|
||||
|
||||
namespace :links do
|
||||
resources :preview_card_providers, only: [:index], path: :publishers do
|
||||
collection do
|
||||
post :batch
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
namespace :disputes do
|
||||
resources :appeals, only: [:index] do
|
||||
member do
|
||||
post :approve
|
||||
post :reject
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
resources :software_updates, only: [:index]
|
||||
end
|
||||
@@ -1,320 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
namespace :api, format: false do
|
||||
# OEmbed
|
||||
get '/oembed', to: 'oembed#show', as: :oembed
|
||||
|
||||
# JSON / REST API
|
||||
namespace :v1 do
|
||||
resources :statuses, only: [:create, :show, :update, :destroy] do
|
||||
scope module: :statuses do
|
||||
resources :reblogged_by, controller: :reblogged_by_accounts, only: :index
|
||||
resources :favourited_by, controller: :favourited_by_accounts, only: :index
|
||||
resource :reblog, only: :create
|
||||
post :unreblog, to: 'reblogs#destroy'
|
||||
|
||||
resource :favourite, only: :create
|
||||
post :unfavourite, to: 'favourites#destroy'
|
||||
|
||||
resource :bookmark, only: :create
|
||||
post :unbookmark, to: 'bookmarks#destroy'
|
||||
|
||||
resource :mute, only: :create
|
||||
post :unmute, to: 'mutes#destroy'
|
||||
|
||||
resource :pin, only: :create
|
||||
post :unpin, to: 'pins#destroy'
|
||||
|
||||
resource :history, only: :show
|
||||
resource :source, only: :show
|
||||
|
||||
post :translate, to: 'translations#create'
|
||||
end
|
||||
|
||||
member do
|
||||
get :context
|
||||
end
|
||||
end
|
||||
|
||||
namespace :timelines do
|
||||
resource :direct, only: :show, controller: :direct
|
||||
resource :home, only: :show, controller: :home
|
||||
resource :public, only: :show, controller: :public
|
||||
resources :tag, only: :show
|
||||
resources :list, only: :show
|
||||
end
|
||||
|
||||
get '/streaming', to: 'streaming#index'
|
||||
get '/streaming/(*any)', to: 'streaming#index'
|
||||
|
||||
resources :custom_emojis, only: [:index]
|
||||
resources :suggestions, only: [:index, :destroy]
|
||||
resources :scheduled_statuses, only: [:index, :show, :update, :destroy]
|
||||
resources :preferences, only: [:index]
|
||||
|
||||
resources :announcements, only: [:index] do
|
||||
scope module: :announcements do
|
||||
resources :reactions, only: [:update, :destroy]
|
||||
end
|
||||
|
||||
member do
|
||||
post :dismiss
|
||||
end
|
||||
end
|
||||
|
||||
# namespace :crypto do
|
||||
# resources :deliveries, only: :create
|
||||
|
||||
# namespace :keys do
|
||||
# resource :upload, only: [:create]
|
||||
# resource :query, only: [:create]
|
||||
# resource :claim, only: [:create]
|
||||
# resource :count, only: [:show]
|
||||
# end
|
||||
|
||||
# resources :encrypted_messages, only: [:index] do
|
||||
# collection do
|
||||
# post :clear
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
|
||||
resources :conversations, only: [:index, :destroy] do
|
||||
member do
|
||||
post :read
|
||||
post :unread
|
||||
end
|
||||
end
|
||||
|
||||
resources :media, only: [:create, :update, :show]
|
||||
resources :blocks, only: [:index]
|
||||
resources :mutes, only: [:index]
|
||||
resources :favourites, only: [:index]
|
||||
resources :bookmarks, only: [:index]
|
||||
resources :reports, only: [:create]
|
||||
resources :trends, only: [:index], controller: 'trends/tags'
|
||||
resources :filters, only: [:index, :create, :show, :update, :destroy]
|
||||
resources :endorsements, only: [:index]
|
||||
resources :markers, only: [:index, :create]
|
||||
|
||||
namespace :profile do
|
||||
resource :avatar, only: :destroy
|
||||
resource :header, only: :destroy
|
||||
end
|
||||
|
||||
namespace :apps do
|
||||
get :verify_credentials, to: 'credentials#show'
|
||||
end
|
||||
|
||||
resources :apps, only: [:create]
|
||||
|
||||
namespace :trends do
|
||||
resources :tags, only: [:index]
|
||||
resources :links, only: [:index]
|
||||
resources :statuses, only: [:index]
|
||||
end
|
||||
|
||||
namespace :emails do
|
||||
resources :confirmations, only: [:create]
|
||||
get :check_confirmation, to: 'confirmations#check'
|
||||
end
|
||||
|
||||
resource :instance, only: [:show] do
|
||||
resources :peers, only: [:index], controller: 'instances/peers'
|
||||
resources :rules, only: [:index], controller: 'instances/rules'
|
||||
resources :domain_blocks, only: [:index], controller: 'instances/domain_blocks'
|
||||
resource :privacy_policy, only: [:show], controller: 'instances/privacy_policies'
|
||||
resource :extended_description, only: [:show], controller: 'instances/extended_descriptions'
|
||||
resource :translation_languages, only: [:show], controller: 'instances/translation_languages'
|
||||
resource :languages, only: [:show], controller: 'instances/languages'
|
||||
resource :activity, only: [:show], controller: 'instances/activity'
|
||||
end
|
||||
|
||||
namespace :peers do
|
||||
get :search, to: 'search#index'
|
||||
end
|
||||
|
||||
resource :domain_blocks, only: [:show, :create, :destroy]
|
||||
|
||||
resource :directory, only: [:show]
|
||||
|
||||
resources :follow_requests, only: [:index] do
|
||||
member do
|
||||
post :authorize
|
||||
post :reject
|
||||
end
|
||||
end
|
||||
|
||||
resources :notifications, only: [:index, :show, :destroy] do
|
||||
collection do
|
||||
post :clear
|
||||
delete :destroy_multiple
|
||||
end
|
||||
|
||||
member do
|
||||
post :dismiss
|
||||
end
|
||||
end
|
||||
|
||||
namespace :accounts do
|
||||
get :verify_credentials, to: 'credentials#show'
|
||||
patch :update_credentials, to: 'credentials#update'
|
||||
resource :search, only: :show, controller: :search
|
||||
resource :lookup, only: :show, controller: :lookup
|
||||
resources :relationships, only: :index
|
||||
resources :familiar_followers, only: :index
|
||||
end
|
||||
|
||||
resources :accounts, only: [:create, :show] do
|
||||
resources :statuses, only: :index, controller: 'accounts/statuses'
|
||||
resources :followers, only: :index, controller: 'accounts/follower_accounts'
|
||||
resources :following, only: :index, controller: 'accounts/following_accounts'
|
||||
resources :lists, only: :index, controller: 'accounts/lists'
|
||||
resources :identity_proofs, only: :index, controller: 'accounts/identity_proofs'
|
||||
resources :featured_tags, only: :index, controller: 'accounts/featured_tags'
|
||||
|
||||
member do
|
||||
post :follow
|
||||
post :unfollow
|
||||
post :remove_from_followers
|
||||
post :block
|
||||
post :unblock
|
||||
post :mute
|
||||
post :unmute
|
||||
end
|
||||
|
||||
resource :pin, only: :create, controller: 'accounts/pins'
|
||||
post :unpin, to: 'accounts/pins#destroy'
|
||||
resource :note, only: :create, controller: 'accounts/notes'
|
||||
end
|
||||
|
||||
resources :tags, only: [:show] do
|
||||
member do
|
||||
post :follow
|
||||
post :unfollow
|
||||
end
|
||||
end
|
||||
|
||||
resources :followed_tags, only: [:index]
|
||||
|
||||
resources :lists, only: [:index, :create, :show, :update, :destroy] do
|
||||
resource :accounts, only: [:show, :create, :destroy], controller: 'lists/accounts'
|
||||
end
|
||||
|
||||
namespace :featured_tags do
|
||||
get :suggestions, to: 'suggestions#index'
|
||||
end
|
||||
|
||||
resources :featured_tags, only: [:index, :create, :destroy]
|
||||
|
||||
resources :polls, only: [:create, :show] do
|
||||
resources :votes, only: :create, controller: 'polls/votes'
|
||||
end
|
||||
|
||||
namespace :push do
|
||||
resource :subscription, only: [:create, :show, :update, :destroy]
|
||||
end
|
||||
|
||||
namespace :admin do
|
||||
resources :accounts, only: [:index, :show, :destroy] do
|
||||
member do
|
||||
post :enable
|
||||
post :unsensitive
|
||||
post :unsilence
|
||||
post :unsuspend
|
||||
post :approve
|
||||
post :reject
|
||||
end
|
||||
|
||||
resource :action, only: [:create], controller: 'account_actions'
|
||||
end
|
||||
|
||||
resources :reports, only: [:index, :update, :show] do
|
||||
member do
|
||||
post :assign_to_self
|
||||
post :unassign
|
||||
post :reopen
|
||||
post :resolve
|
||||
end
|
||||
end
|
||||
|
||||
resources :domain_allows, only: [:index, :show, :create, :destroy]
|
||||
resources :domain_blocks, only: [:index, :show, :update, :create, :destroy]
|
||||
resources :email_domain_blocks, only: [:index, :show, :create, :destroy]
|
||||
resources :ip_blocks, only: [:index, :show, :update, :create, :destroy]
|
||||
|
||||
namespace :trends do
|
||||
resources :tags, only: [:index] do
|
||||
member do
|
||||
post :approve
|
||||
post :reject
|
||||
end
|
||||
end
|
||||
resources :links, only: [:index] do
|
||||
member do
|
||||
post :approve
|
||||
post :reject
|
||||
end
|
||||
end
|
||||
resources :statuses, only: [:index] do
|
||||
member do
|
||||
post :approve
|
||||
post :reject
|
||||
end
|
||||
end
|
||||
|
||||
namespace :links do
|
||||
resources :preview_card_providers, only: [:index], path: :publishers do
|
||||
member do
|
||||
post :approve
|
||||
post :reject
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
post :measures, to: 'measures#create'
|
||||
post :dimensions, to: 'dimensions#create'
|
||||
post :retention, to: 'retention#create'
|
||||
|
||||
resources :canonical_email_blocks, only: [:index, :create, :show, :destroy] do
|
||||
collection do
|
||||
post :test
|
||||
end
|
||||
end
|
||||
|
||||
resources :tags, only: [:index, :show, :update]
|
||||
end
|
||||
end
|
||||
|
||||
namespace :v2 do
|
||||
get '/search', to: 'search#index', as: :search
|
||||
|
||||
resources :media, only: [:create]
|
||||
resources :suggestions, only: [:index]
|
||||
resource :instance, only: [:show]
|
||||
resources :filters, only: [:index, :create, :show, :update, :destroy] do
|
||||
resources :keywords, only: [:index, :create], controller: 'filters/keywords'
|
||||
resources :statuses, only: [:index, :create], controller: 'filters/statuses'
|
||||
end
|
||||
|
||||
namespace :filters do
|
||||
resources :keywords, only: [:show, :update, :destroy]
|
||||
resources :statuses, only: [:show, :destroy]
|
||||
end
|
||||
|
||||
namespace :admin do
|
||||
resources :accounts, only: [:index]
|
||||
end
|
||||
end
|
||||
|
||||
namespace :web do
|
||||
resource :settings, only: [:update]
|
||||
resources :embeds, only: [:show]
|
||||
resources :push_subscriptions, only: [:create] do
|
||||
member do
|
||||
put :update
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,76 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
namespace :settings do
|
||||
resource :profile, only: [:show, :update] do
|
||||
resources :pictures, only: :destroy
|
||||
end
|
||||
|
||||
get :preferences, to: redirect('/settings/preferences/appearance')
|
||||
|
||||
namespace :preferences do
|
||||
resource :appearance, only: [:show, :update], controller: :appearance
|
||||
resource :notifications, only: [:show, :update]
|
||||
resource :other, only: [:show, :update], controller: :other
|
||||
end
|
||||
|
||||
resources :imports, only: [:index, :show, :destroy, :create] do
|
||||
member do
|
||||
post :confirm
|
||||
get :failures
|
||||
end
|
||||
end
|
||||
|
||||
resource :export, only: [:show, :create]
|
||||
|
||||
namespace :exports, constraints: { format: :csv } do
|
||||
resources :follows, only: :index, controller: :following_accounts
|
||||
resources :blocks, only: :index, controller: :blocked_accounts
|
||||
resources :mutes, only: :index, controller: :muted_accounts
|
||||
resources :lists, only: :index, controller: :lists
|
||||
resources :domain_blocks, only: :index, controller: :blocked_domains
|
||||
resources :bookmarks, only: :index, controller: :bookmarks
|
||||
end
|
||||
|
||||
resources :two_factor_authentication_methods, only: [:index] do
|
||||
collection do
|
||||
post :disable
|
||||
end
|
||||
end
|
||||
|
||||
resource :otp_authentication, only: [:show, :create], controller: 'two_factor_authentication/otp_authentication'
|
||||
|
||||
resources :webauthn_credentials, only: [:index, :new, :create, :destroy],
|
||||
path: 'security_keys',
|
||||
controller: 'two_factor_authentication/webauthn_credentials' do
|
||||
collection do
|
||||
get :options
|
||||
end
|
||||
end
|
||||
|
||||
namespace :two_factor_authentication do
|
||||
resources :recovery_codes, only: [:create]
|
||||
resource :confirmation, only: [:new, :create]
|
||||
end
|
||||
|
||||
resources :applications, except: [:edit] do
|
||||
member do
|
||||
post :regenerate
|
||||
end
|
||||
end
|
||||
|
||||
resources :flavours, only: [:index, :show, :update], param: :flavour
|
||||
|
||||
resource :delete, only: [:show, :destroy]
|
||||
resource :migration, only: [:show, :create]
|
||||
resource :verification, only: :show
|
||||
resource :privacy, only: [:show, :update], controller: 'privacy'
|
||||
|
||||
namespace :migration do
|
||||
resource :redirect, only: [:new, :create, :destroy]
|
||||
end
|
||||
|
||||
resources :aliases, only: [:index, :create, :destroy]
|
||||
resources :sessions, only: [:destroy]
|
||||
resources :featured_tags, only: [:index, :create, :destroy]
|
||||
resources :login_activities, only: [:index]
|
||||
end
|
||||
@@ -1,22 +0,0 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Your secret key is used for verifying the integrity of signed cookies.
|
||||
# If you change this key, all old signed cookies will become invalid!
|
||||
|
||||
# Make sure the secret is at least 30 characters and all random,
|
||||
# no regular words or you'll be exposed to dictionary attacks.
|
||||
# You can use `rails secret` to generate a secure secret key.
|
||||
|
||||
# Make sure the secrets in this file are kept private
|
||||
# if you're sharing your code publicly.
|
||||
|
||||
development:
|
||||
secret_key_base: d4398e4af52f1fc5be5c3c8764e9ecce7beac5462826cb8b649373b2aad5a0f133598ed817c4e9931e943041460d6b6eda40a854e825e1bbd510c4594b1538f2
|
||||
|
||||
test:
|
||||
secret_key_base: 5be187ddbd651211a906f9aa399f4a148edf6e06b971c7c0b5429b9483df6e21d262cc846447d0f89b89c32d56a99e151039df5dd874ede7f712afbe041a9269
|
||||
|
||||
# Do not keep production secrets in the repository,
|
||||
# instead read values from the environment.
|
||||
production:
|
||||
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
|
||||
@@ -1,64 +0,0 @@
|
||||
---
|
||||
:concurrency: <%= ENV.fetch('SIDEKIQ_CONCURRENCY', 5) %>
|
||||
:queues:
|
||||
- [default, 8]
|
||||
- [push, 6]
|
||||
- [ingress, 4]
|
||||
- [mailers, 2]
|
||||
- [pull]
|
||||
- [scheduler]
|
||||
:scheduler:
|
||||
:listened_queues_only: true
|
||||
:schedule:
|
||||
scheduled_statuses_scheduler:
|
||||
every: '5m'
|
||||
class: Scheduler::ScheduledStatusesScheduler
|
||||
queue: scheduler
|
||||
trends_refresh_scheduler:
|
||||
every: '5m'
|
||||
class: Scheduler::Trends::RefreshScheduler
|
||||
queue: scheduler
|
||||
trends_review_notifications_scheduler:
|
||||
every: '6h'
|
||||
class: Scheduler::Trends::ReviewNotificationsScheduler
|
||||
queue: scheduler
|
||||
indexing_scheduler:
|
||||
interval: 1 minute
|
||||
class: Scheduler::IndexingScheduler
|
||||
queue: scheduler
|
||||
vacuum_scheduler:
|
||||
cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *'
|
||||
class: Scheduler::VacuumScheduler
|
||||
queue: scheduler
|
||||
follow_recommendations_scheduler:
|
||||
cron: '<%= Random.rand(0..59) %> <%= Random.rand(6..9) %> * * *'
|
||||
class: Scheduler::FollowRecommendationsScheduler
|
||||
queue: scheduler
|
||||
user_cleanup_scheduler:
|
||||
cron: '<%= Random.rand(0..59) %> <%= Random.rand(4..6) %> * * *'
|
||||
class: Scheduler::UserCleanupScheduler
|
||||
queue: scheduler
|
||||
ip_cleanup_scheduler:
|
||||
cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *'
|
||||
class: Scheduler::IpCleanupScheduler
|
||||
queue: scheduler
|
||||
pghero_scheduler:
|
||||
cron: '0 0 * * *'
|
||||
class: Scheduler::PgheroScheduler
|
||||
queue: scheduler
|
||||
instance_refresh_scheduler:
|
||||
cron: '0 * * * *'
|
||||
class: Scheduler::InstanceRefreshScheduler
|
||||
queue: scheduler
|
||||
accounts_statuses_cleanup_scheduler:
|
||||
interval: 1 minute
|
||||
class: Scheduler::AccountsStatusesCleanupScheduler
|
||||
queue: scheduler
|
||||
suspended_user_cleanup_scheduler:
|
||||
interval: 1 minute
|
||||
class: Scheduler::SuspendedUserCleanupScheduler
|
||||
queue: scheduler
|
||||
software_update_check_scheduler:
|
||||
interval: 30 minutes
|
||||
class: Scheduler::SoftwareUpdateCheckScheduler
|
||||
queue: scheduler
|
||||
Reference in New Issue
Block a user