about summary refs log tree commit diff
path: root/config
diff options
context:
space:
mode:
Diffstat (limited to 'config')
-rw-r--r--config/application.rb4
-rw-r--r--config/cable.yml2
-rw-r--r--config/database.yml2
-rw-r--r--config/environments/development.rb5
-rw-r--r--config/environments/production.rb19
-rw-r--r--config/initializers/inflections.rb8
-rw-r--r--config/initializers/paperclip.rb4
-rw-r--r--config/initializers/redis.rb1
-rw-r--r--config/initializers/sidekiq.rb5
-rw-r--r--config/initializers/statsd.rb20
-rw-r--r--config/initializers/trusted_proxies.rb11
-rw-r--r--config/locales/de.yml33
-rw-r--r--config/locales/en.yml19
-rw-r--r--config/locales/simple_form.de.yml5
-rw-r--r--config/navigation.rb1
-rw-r--r--config/puma.rb45
-rw-r--r--config/routes.rb30
-rw-r--r--config/settings.yml23
18 files changed, 178 insertions, 59 deletions
diff --git a/config/application.rb b/config/application.rb
index 79ace8521..d0b06bf95 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -3,6 +3,7 @@ require_relative 'boot'
 require 'rails/all'
 
 require_relative '../app/lib/exceptions'
+require_relative '../lib/statsd_monitor'
 
 # Require the gems listed in Gemfile, including any gems
 # you've limited to :test, :development, or :production.
@@ -30,6 +31,8 @@ module Mastodon
 
     config.active_job.queue_adapter = :sidekiq
 
+    config.middleware.insert(0, ::StatsDMonitor)
+
     config.middleware.insert_before 0, Rack::Cors do
       allow do
         origins  '*'
@@ -46,6 +49,7 @@ module Mastodon
 
     config.to_prepare do
       Doorkeeper::AuthorizationsController.layout 'public'
+      Doorkeeper::Application.send :include, ApplicationExtension
     end
 
     config.action_dispatch.default_headers = {
diff --git a/config/cable.yml b/config/cable.yml
index 978f721af..34759a772 100644
--- a/config/cable.yml
+++ b/config/cable.yml
@@ -7,4 +7,4 @@ test:
 
 production:
   adapter: redis
-  url: redis://<%= ENV['REDIS_HOST'] || 'localhost' %>:<%= ENV['REDIS_PORT'] || 6379 %>/1
+  url: redis://<%= ENV['REDIS_PASSWORD'] ? ':' + ENV['REDIS_PASSWORD'] + '@' : '' %><%= ENV['REDIS_HOST'] || 'localhost' %>:<%= ENV['REDIS_PORT'] || 6379 %>/1
diff --git a/config/database.yml b/config/database.yml
index 52c26f599..5ec342f93 100644
--- a/config/database.yml
+++ b/config/database.yml
@@ -1,6 +1,6 @@
 default: &default
   adapter: postgresql
-  pool: <%= ENV["DB_POOL"] || ENV['RAILS_MAX_THREADS'] || 5 %>
+  pool: <%= ENV["DB_POOL"] || ENV['MAX_THREADS'] || 5 %>
   timeout: 5000
   encoding: unicode
 
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 829edcf04..3f44d861e 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -62,7 +62,10 @@ Rails.application.configure do
   # routes, locales, etc. This feature depends on the listen gem.
   # config.file_watcher = ActiveSupport::EventedFileUpdateChecker
 
-  config.action_mailer.delivery_method = :letter_opener
+  # If using a Heroku, Vagrant or generic remote development environment,
+  # use letter_opener_web, accessible at  /letter_opener.
+  # Otherwise, use letter_opener, which launches a browser window to view sent mail.
+  config.action_mailer.delivery_method = (ENV['HEROKU'] || ENV['VAGRANT'] || ENV['REMOTE_DEV']) ? :letter_opener_web : :letter_opener
 
   config.after_initialize do
     Bullet.enable        = true
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 9254d494c..d2dfa4274 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -32,6 +32,9 @@ Rails.application.configure do
   # 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 = [IPAddr.new(ENV['TRUSTED_PROXY_IP'])] unless ENV['TRUSTED_PROXY_IP'].blank?
+
   # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
   config.force_ssl = false
 
@@ -45,10 +48,20 @@ Rails.application.configure do
   # Use a different logger for distributed setups.
   # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
 
+  # Parse and split the REDIS_URL if passed (used with hosting platforms such as Heroku).
+  # Set ENV variables because they are used elsewhere.
+  if ENV['REDIS_URL']
+    redis_url = URI.parse(ENV['REDIS_URL'])
+    ENV['REDIS_HOST'] = redis_url.host
+    ENV['REDIS_PORT'] = redis_url.port.to_s
+    ENV['REDIS_PASSWORD'] = redis_url.password
+  end
+
   # Use a different cache store in production.
   config.cache_store = :redis_store, {
     host: ENV.fetch('REDIS_HOST') { 'localhost' },
     port: ENV.fetch('REDIS_PORT') { 6379 },
+    password: ENV.fetch('REDIS_PASSWORD') { false },
     db: 0,
     namespace: 'cache',
     expires_in: 20.minutes
@@ -85,7 +98,7 @@ Rails.application.configure do
     :address        => ENV['SMTP_SERVER'],
     :user_name      => ENV['SMTP_LOGIN'],
     :password       => ENV['SMTP_PASSWORD'],
-    :domain         => config.x.local_domain,
+    :domain         => ENV['SMTP_DOMAIN'] || config.x.local_domain,
     :authentication => :plain,
   }
 
@@ -94,4 +107,8 @@ Rails.application.configure do
   config.react.variant = :production
 
   config.active_record.logger = nil
+
+  config.to_prepare do
+    StatsD.backend = StatsD::Instrument::Backends::NullBackend.new if ENV['STATSD_ADDR'].blank?
+  end
 end
diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb
index ac033bf9d..b5e43e705 100644
--- a/config/initializers/inflections.rb
+++ b/config/initializers/inflections.rb
@@ -10,7 +10,7 @@
 #   inflect.uncountable %w( fish sheep )
 # end
 
-# These inflection rules are supported but not enabled by default:
-# ActiveSupport::Inflector.inflections(:en) do |inflect|
-#   inflect.acronym 'RESTful'
-# end
+ActiveSupport::Inflector.inflections(:en) do |inflect|
+  inflect.acronym 'StatsD'
+  inflect.acronym 'OEmbed'
+end
diff --git a/config/initializers/paperclip.rb b/config/initializers/paperclip.rb
index cb7ed4487..71a7b514e 100644
--- a/config/initializers/paperclip.rb
+++ b/config/initializers/paperclip.rb
@@ -1,5 +1,7 @@
 # frozen_string_literal: true
 
+Paperclip.options[:read_timeout] = 60
+
 if ENV['S3_ENABLED'] == 'true'
   Aws.eager_autoload!(services: %w(S3))
 
@@ -9,7 +11,7 @@ if ENV['S3_ENABLED'] == 'true'
   Paperclip::Attachment.default_options[:s3_host_name]   = ENV.fetch('S3_HOSTNAME') { "s3-#{ENV.fetch('S3_REGION')}.amazonaws.com" }
   Paperclip::Attachment.default_options[:path]           = '/:class/:attachment/:id_partition/:style/:filename'
   Paperclip::Attachment.default_options[:s3_headers]     = { 'Cache-Control' => 'max-age=315576000', 'Expires' => 10.years.from_now.httpdate }
-  Paperclip::Attachment.default_options[:s3_permissions] = 'public'
+  Paperclip::Attachment.default_options[:s3_permissions] = 'public-read'
   Paperclip::Attachment.default_options[:s3_region]      = ENV.fetch('S3_REGION') { 'us-east-1' }
 
   Paperclip::Attachment.default_options[:s3_credentials] = {
diff --git a/config/initializers/redis.rb b/config/initializers/redis.rb
index 3825710b8..3660c4a9b 100644
--- a/config/initializers/redis.rb
+++ b/config/initializers/redis.rb
@@ -3,5 +3,6 @@
 Redis.current = Redis.new(
   host: ENV.fetch('REDIS_HOST') { 'localhost' },
   port: ENV.fetch('REDIS_PORT') { 6379 },
+  password: ENV.fetch('REDIS_PASSWORD') { false },
   driver: :hiredis
 )
diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb
index 63fdb3f16..ecdd07b08 100644
--- a/config/initializers/sidekiq.rb
+++ b/config/initializers/sidekiq.rb
@@ -1,10 +1,11 @@
 host = ENV.fetch('REDIS_HOST') { 'localhost' }
 port = ENV.fetch('REDIS_PORT') { 6379 }
+password = ENV.fetch('REDIS_PASSWORD') { false }
 
 Sidekiq.configure_server do |config|
-  config.redis = { host: host, port: port }
+  config.redis = { host: host, port: port, password: password}
 end
 
 Sidekiq.configure_client do |config|
-  config.redis = { host: host, port: port }
+  config.redis = { host: host, port: port, password: password }
 end
diff --git a/config/initializers/statsd.rb b/config/initializers/statsd.rb
new file mode 100644
index 000000000..c9c754e7f
--- /dev/null
+++ b/config/initializers/statsd.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+StatsD.prefix              = 'mastodon'
+StatsD.default_sample_rate = 1
+
+StatsDMonitor.extend(StatsD::Instrument)
+StatsDMonitor.statsd_measure(:call, 'request.duration')
+
+STATSD_REQUEST_METRICS = {
+  'request.status.success'               => 200,
+  'request.status.not_found'             => 404,
+  'request.status.too_many_requests'     => 429,
+  'request.status.internal_server_error' => 500,
+}.freeze
+
+STATSD_REQUEST_METRICS.each do |name, code|
+  StatsDMonitor.statsd_count_if(:call, name) do |status, _env, _body|
+    status.to_i == code
+  end
+end
diff --git a/config/initializers/trusted_proxies.rb b/config/initializers/trusted_proxies.rb
new file mode 100644
index 000000000..3c2afd8cd
--- /dev/null
+++ b/config/initializers/trusted_proxies.rb
@@ -0,0 +1,11 @@
+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
diff --git a/config/locales/de.yml b/config/locales/de.yml
index ead3ae514..f36cc64c8 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -14,6 +14,7 @@ de:
     people_followed_by: Nutzer, denen %{name} folgt
     people_who_follow: Nutzer, die %{name} folgen
     posts: Beiträge
+    remote_follow: Folgen
     unfollow: Entfolgen
   application_mailer:
     signature: Mastodon-Benachrichtigungen von %{instance}
@@ -26,6 +27,25 @@ de:
     resend_confirmation: Bestätigung nochmal versenden
     reset_password: Passwort zurücksetzen
     set_new_password: Neues Passwort setzen
+  authorize_follow:
+    error: Das entfernte Profil konnte nicht geladen werden
+    follow: Folgen
+    prompt_html: 'Du (<strong>%{self}</strong>) möchtest dieser Person folgen:'
+    title: "%{acct} folgen"
+  datetime:
+    distance_in_words:
+      about_x_hours: "%{count}h"
+      about_x_months: "%{count}mo"
+      about_x_years: "%{count}y"
+      almost_x_years: "%{count}y"
+      half_a_minute: Gerade eben
+      less_than_x_minutes: "%{count}m"
+      less_than_x_seconds: Gerade eben
+      over_x_years: "%{count}y"
+      x_days: "%{count}d"
+      x_minutes: "%{count}m"
+      x_months: "%{count}mo"
+      x_seconds: "%{count}s"
   generic:
     changes_saved_msg: Änderungen gespeichert!
     powered_by: angetrieben von %{link}
@@ -40,6 +60,9 @@ de:
     follow:
       body: "%{name} folgt dir jetzt!"
       subject: "%{name} folgt dir nun"
+    follow_request:
+      body: "%{name} möchte dir folgen:"
+      subject: "%{name} möchte dir folgen"
     mention:
       body: "%{name} hat dich erwähnt:"
       subject: "%{name} hat dich erwähnt"
@@ -49,13 +72,23 @@ de:
   pagination:
     next: Vorwärts
     prev: Zurück
+  remote_follow:
+    acct: Dein Nutzername@Domain, von dem du dieser Person folgen möchtest
+    missing_resource: Die erforderliche Weiterleitungs-URL konnte leider in deinem Profil nicht gefunden werden
+    proceed: Weiter
+    prompt: 'Du wirst dieser Person folgen:'
   settings:
     edit_profile: Profil bearbeiten
     preferences: Einstellungen
   stream_entries:
+    click_to_show: Klicken um zu zeigen
     favourited: favorisierte einen Beitrag von
     is_now_following: folgt nun
     reblogged: teilte
+    sensitive_content: Sensible Inhalte
+  time:
+    formats:
+      default: "%d.%m.%Y %H:%M"
   users:
     invalid_email: Inkorrekte E-mail-Addresse
   will_paginate:
diff --git a/config/locales/en.yml b/config/locales/en.yml
index e166fc717..831fdbc7a 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -3,9 +3,19 @@ en:
   about:
     about_instance: "<em>%{instance}</em> is a Mastodon instance."
     about_mastodon: Mastodon is a <em>free, open-source</em> social network server. A <em>decentralized</em> alternative to commercial platforms, it avoids the risks of a single company monopolizing your communication. Anyone can run Mastodon and participate in the <em>social network</em> seamlessly.
+    business_email: 'Business e-mail:'
+    contact: Contact
+    domain_count_after: other instances
+    domain_count_before: Connected to
     get_started: Get started
+    learn_more: Learn more
+    links: Links
     source_code: Source code
+    status_count_after: statuses
+    status_count_before: Who authored
     terms: Terms
+    user_count_after: users
+    user_count_before: Home to
   accounts:
     follow: Follow
     followers: Followers
@@ -18,6 +28,8 @@ en:
     unfollow: Unfollow
   application_mailer:
     signature: Mastodon notifications from %{instance}
+  applications:
+    invalid_url: The provided URL is invalid
   auth:
     change_password: Change password
     didnt_get_confirmation: Didn't receive confirmation instructions?
@@ -67,8 +79,8 @@ en:
       body: 'You were mentioned by %{name} in:'
       subject: You were mentioned by %{name}
     reblog:
-      body: 'Your status was reblogged by %{name}:'
-      subject: "%{name} reblogged your status"
+      body: 'Your status was boosted by %{name}:'
+      subject: "%{name} boosted your status"
   pagination:
     next: Next
     prev: Prev
@@ -78,8 +90,11 @@ en:
     proceed: Proceed to follow
     prompt: 'You are going to follow:'
   settings:
+    back: Back to Mastodon
     edit_profile: Edit profile
     preferences: Preferences
+  statuses:
+    over_character_limit: character limit of %{max} exceeded
   stream_entries:
     click_to_show: Click to show
     favourited: favourited a post by
diff --git a/config/locales/simple_form.de.yml b/config/locales/simple_form.de.yml
index d0aed9d0e..614cd4911 100644
--- a/config/locales/simple_form.de.yml
+++ b/config/locales/simple_form.de.yml
@@ -1,6 +1,9 @@
 ---
 de:
   simple_form:
+    hints:
+      defaults:
+        locked: Erlaubt dir, Folger zu überprüfen, bevor sie dir folgen können
     labels:
       defaults:
         avatar: Avatar
@@ -11,6 +14,7 @@ de:
         email: E-mail-Addresse
         header: Kopfbild
         locale: Sprache
+        locked: Gesperrter Profil
         new_password: Neues Passwort
         note: Über mich
         password: Passwort
@@ -21,6 +25,7 @@ de:
       notification_emails:
         favourite: E-mail senden, wenn jemand meinen Beitrag favorisiert
         follow: E-mail senden, wenn mir jemand folgt
+        follow_request: E-mail senden, wenn mir jemand folgen möchte
         mention: E-mail senden, wenn mich jemand erwähnt
         reblog: E-mail senden, wenn jemand meinen Beitrag teilt
     'no': Nein
diff --git a/config/navigation.rb b/config/navigation.rb
index 1b6615ed0..9aaa12b0b 100644
--- a/config/navigation.rb
+++ b/config/navigation.rb
@@ -7,5 +7,6 @@ SimpleNavigation::Configuration.run do |navigation|
     primary.item :domain_blocks, safe_join([fa_icon('lock fw'), 'Domain Blocks']), admin_domain_blocks_url
     primary.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_url
     primary.item :pghero, safe_join([fa_icon('database fw'), 'PgHero']), pghero_url
+    primary.item :settings, safe_join([fa_icon('cogs fw'), 'Site Settings']), admin_settings_url
   end
 end
diff --git a/config/puma.rb b/config/puma.rb
index ad2dbfffd..550129bdc 100644
--- a/config/puma.rb
+++ b/config/puma.rb
@@ -1,47 +1,18 @@
-# Puma can serve each request in a thread from an internal thread pool.
-# The `threads` method setting takes two numbers a minimum and maximum.
-# Any libraries that use thread pools should be configured to match
-# the maximum value specified for Puma. Default is set to 5 threads for minimum
-# and maximum, this matches the default thread size of Active Record.
-#
-threads_count = ENV.fetch("MAX_THREADS") { 5 }.to_i
+threads_count = ENV.fetch('MAX_THREADS') { 5 }.to_i
 threads threads_count, threads_count
 
-# Specifies the `port` that Puma will listen on to receive requests, default is 3000.
-#
-port        ENV.fetch("PORT") { 3000 }
+port        ENV.fetch('PORT') { 3000 }
+environment ENV.fetch('RAILS_ENV') { 'development' }
+workers     ENV.fetch('WEB_CONCURRENCY') { 2 }
 
-# Specifies the `environment` that Puma will run in.
-#
-environment ENV.fetch("RAILS_ENV") { "development" }
-
-# Specifies the number of `workers` to boot in clustered mode.
-# Workers are forked webserver processes. If using threads and workers together
-# the concurrency of the application would be max `threads` * `workers`.
-# Workers do not work on JRuby or Windows (both of which do not support
-# processes).
-#
-workers ENV.fetch("WEB_CONCURRENCY") { 2 }
-
-# Use the `preload_app!` method when specifying a `workers` number.
-# This directive tells Puma to first boot the application and load code
-# before forking the application. This takes advantage of Copy On Write
-# process behavior so workers use less memory. If you use this option
-# you need to make sure to reconnect any threads in the `on_worker_boot`
-# block.
-#
 preload_app!
 
-# The code in the `on_worker_boot` will be called if you are using
-# clustered mode by specifying a number of `workers`. After each worker
-# process is booted this block will be run, if you are using `preload_app!`
-# option you will want to use this block to reconnect to any threads
-# or connections that may have been created at application boot, Ruby
-# cannot share connections between processes.
-#
 on_worker_boot do
+  if ENV['HEROKU'] # Spawn the workers from Puma, to only use one dyno
+    @sidekiq_pid ||= spawn('bundle exec sidekiq -q default -q mailers -q push')
+  end
+
   ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
 end
 
-# Allow puma to be restarted by `rails restart` command.
 plugin :tmp_restart
diff --git a/config/routes.rb b/config/routes.rb
index 18c239c48..15fb924f1 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -3,6 +3,7 @@
 require 'sidekiq/web'
 
 Rails.application.routes.draw do
+  mount LetterOpenerWeb::Engine, at: 'letter_opener' if Rails.env.development?
   mount ActionCable.server, at: 'cable'
 
   authenticate :user, lambda { |u| u.admin? } do
@@ -58,6 +59,7 @@ Rails.application.routes.draw do
   namespace :admin do
     resources :pubsubhubbub, only: [:index]
     resources :domain_blocks, only: [:index, :create]
+    resources :settings, only: [:index, :update]
 
     resources :accounts, only: [:index, :show, :update] do
       member do
@@ -85,6 +87,7 @@ Rails.application.routes.draw do
       resources :statuses, only: [:create, :show, :destroy] do
         member do
           get :context
+          get :card
           get :reblogged_by
           get :favourited_by
 
@@ -100,10 +103,11 @@ Rails.application.routes.draw do
       get '/timelines/public',   to: 'timelines#public', as: :public_timeline
       get '/timelines/tag/:id',  to: 'timelines#tag', as: :hashtag_timeline
 
-      resources :follows,  only: [:create]
-      resources :media,    only: [:create]
-      resources :apps,     only: [:create]
-      resources :blocks,   only: [:index]
+      resources :follows,    only: [:create]
+      resources :media,      only: [:create]
+      resources :apps,       only: [:create]
+      resources :blocks,     only: [:index]
+      resources :favourites, only: [:index]
 
       resources :follow_requests, only: [:index] do
         member do
@@ -112,8 +116,11 @@ Rails.application.routes.draw do
         end
       end
 
-      resources :notifications, only: [:index]
-      resources :favourites,    only: [:index]
+      resources :notifications, only: [:index, :show] do
+        collection do
+          post :clear
+        end
+      end
 
       resources :accounts, only: [:show] do
         collection do
@@ -134,12 +141,17 @@ Rails.application.routes.draw do
         end
       end
     end
+
+    namespace :web do
+      resource :settings, only: [:update]
+    end
   end
 
-  get '/web/*any', to: 'home#index', as: :web
+  get '/web/(*any)', to: 'home#index', as: :web
 
-  get :about, to: 'about#index'
-  get :terms, to: 'about#terms'
+  get '/about',      to: 'about#index'
+  get '/about/more', to: 'about#more'
+  get '/terms',      to: 'about#terms'
 
   root 'home#index'
 
diff --git a/config/settings.yml b/config/settings.yml
new file mode 100644
index 000000000..a78bd067d
--- /dev/null
+++ b/config/settings.yml
@@ -0,0 +1,23 @@
+# config/app.yml for rails-settings-cached
+defaults: &defaults
+  site_description: ''
+  site_extended_description: ''
+  site_contact_username: ''
+  site_contact_email: ''
+  notification_emails:
+    follow: false
+    reblog: false
+    favourite: false
+    mention: false
+    follow_request: true
+  interactions:
+    must_be_follower: false
+    must_be_following: false
+development:
+  <<: *defaults
+
+test:
+  <<: *defaults
+
+production:
+  <<: *defaults