diff --git a/app/mailers/concerns/bulk_mail_settings_concern.rb b/app/mailers/concerns/bulk_mail_settings_concern.rb new file mode 100644 index 000000000..601cc6a0f --- /dev/null +++ b/app/mailers/concerns/bulk_mail_settings_concern.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module BulkMailSettingsConcern + include ActiveSupport::Concern + include Mastodon::EmailConfigurationHelper + + private + + def use_bulk_mail_delivery_settings + return if bulk_mail_configuration&.dig(:smtp_settings, :address).blank? + + mail.delivery_method.settings = convert_smtp_settings(bulk_mail_configuration[:smtp_settings]) + end + + def bulk_mail_configuration + Rails.configuration.x.email&.bulk_mail + end +end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 0eef9b90d..fffc80a8e 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class UserMailer < Devise::Mailer + include BulkMailSettingsConcern + layout 'mailer' helper :accounts @@ -12,6 +14,8 @@ class UserMailer < Devise::Mailer before_action :set_instance + after_action :use_bulk_mail_delivery_settings, only: [:announcement_published, :terms_of_service_changed] + default to: -> { @resource.email } def confirmation_instructions(user, token, *, **) diff --git a/app/workers/admin/distribute_announcement_notification_worker.rb b/app/workers/admin/distribute_announcement_notification_worker.rb index 636852ea1..9a3ce0f2f 100644 --- a/app/workers/admin/distribute_announcement_notification_worker.rb +++ b/app/workers/admin/distribute_announcement_notification_worker.rb @@ -2,7 +2,7 @@ class Admin::DistributeAnnouncementNotificationWorker include Sidekiq::IterableJob - include BulkMailer + include BulkMailingConcern def build_enumerator(announcement_id, cursor:) @announcement = Announcement.find(announcement_id) diff --git a/app/workers/admin/distribute_terms_of_service_notification_worker.rb b/app/workers/admin/distribute_terms_of_service_notification_worker.rb index 5920f1594..4afabc813 100644 --- a/app/workers/admin/distribute_terms_of_service_notification_worker.rb +++ b/app/workers/admin/distribute_terms_of_service_notification_worker.rb @@ -2,7 +2,7 @@ class Admin::DistributeTermsOfServiceNotificationWorker include Sidekiq::IterableJob - include BulkMailer + include BulkMailingConcern def build_enumerator(terms_of_service_id, cursor:) @terms_of_service = TermsOfService.find(terms_of_service_id) diff --git a/app/workers/concerns/bulk_mailer.rb b/app/workers/concerns/bulk_mailing_concern.rb similarity index 96% rename from app/workers/concerns/bulk_mailer.rb rename to app/workers/concerns/bulk_mailing_concern.rb index 78cb3d82b..5f8154d7f 100644 --- a/app/workers/concerns/bulk_mailer.rb +++ b/app/workers/concerns/bulk_mailing_concern.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module BulkMailer +module BulkMailingConcern def push_bulk_mailer(mailer_class, mailer_method, args_array) raise ArgumentError, "No method #{mailer_method} on class #{mailer_class.name}" unless mailer_class.respond_to?(mailer_method) diff --git a/config/email.yml b/config/email.yml index 0480520c3..a6d34c300 100644 --- a/config/email.yml +++ b/config/email.yml @@ -19,3 +19,18 @@ production: tls: <%= ENV.fetch('SMTP_TLS', false) == 'true' ? true : nil %> ssl: <%= ENV.fetch('SMTP_SSL', false) == 'true' ? true : nil %> read_timeout: 20 + bulk_mail: + smtp_settings: + port: <%= ENV.fetch('BULK_SMTP_PORT', nil) %> + address: <%= ENV.fetch('BULK_SMTP_SERVER', nil) %> + user_name: <%= ENV.fetch('BULK_SMTP_LOGIN', nil) %> + password: <%= ENV.fetch('BULK_SMTP_PASSWORD', nil) %> + domain: <%= ENV.fetch('BULK_SMTP_DOMAIN', ENV.fetch('LOCAL_DOMAIN', nil)) %> + authentication: <%= ENV.fetch('BULK_SMTP_AUTH_METHOD', 'plain') %> + ca_file: <%= ENV.fetch('BULK_SMTP_CA_FILE', '/etc/ssl/certs/ca-certificates.crt') %> + openssl_verify_mode: <%= ENV.fetch('BULK_SMTP_OPENSSL_VERIFY_MODE', nil) %> + enable_starttls: <%= ENV.fetch('BULK_SMTP_ENABLE_STARTTLS', nil) %> + enable_starttls_auto: <%= ENV.fetch('BULK_SMTP_ENABLE_STARTTLS_AUTO', true) != 'false' %> + tls: <%= ENV.fetch('BULK_SMTP_TLS', false) == 'true' ? true : nil %> + ssl: <%= ENV.fetch('BULK_SMTP_SSL', false) == 'true' ? true : nil %> + read_timeout: 20 diff --git a/config/environments/production.rb b/config/environments/production.rb index af57eec56..b5ec31635 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -110,7 +110,7 @@ Rails.application.configure do config.action_mailer.default_options[:reply_to] = config.x.email.reply_to if config.x.email.reply_to.present? config.action_mailer.default_options[:return_path] = config.x.email.return_path if config.x.email.return_path.present? - config.action_mailer.smtp_settings = Mastodon::EmailConfigurationHelper.smtp_settings(config.x.email.smtp_settings) + config.action_mailer.smtp_settings = Mastodon::EmailConfigurationHelper.convert_smtp_settings(config.x.email.smtp_settings) config.action_mailer.delivery_method = config.x.email.delivery_method.to_sym diff --git a/lib/mastodon/email_configuration_helper.rb b/lib/mastodon/email_configuration_helper.rb index f5014ad68..af8647278 100644 --- a/lib/mastodon/email_configuration_helper.rb +++ b/lib/mastodon/email_configuration_helper.rb @@ -6,7 +6,7 @@ module Mastodon # Convert smtp settings from environment variables (or defaults in # `config/email.yml`) into the format that `ActionMailer` understands - def smtp_settings(config) + def convert_smtp_settings(config) enable_starttls = nil enable_starttls_auto = nil diff --git a/spec/lib/mastodon/email_configuration_helper_spec.rb b/spec/lib/mastodon/email_configuration_helper_spec.rb index c08f87d16..db513672f 100644 --- a/spec/lib/mastodon/email_configuration_helper_spec.rb +++ b/spec/lib/mastodon/email_configuration_helper_spec.rb @@ -3,10 +3,10 @@ require 'rails_helper' RSpec.describe Mastodon::EmailConfigurationHelper do - describe '#smtp_settings' do + describe '#convert_smtp_settings' do subject { described_class } - let(:converted_settings) { subject.smtp_settings(configuration) } + let(:converted_settings) { subject.convert_smtp_settings(configuration) } let(:base_configuration) do { address: 'localhost', diff --git a/spec/mailers/previews/user_mailer_preview.rb b/spec/mailers/previews/user_mailer_preview.rb index e677a24df..3dc3f66c7 100644 --- a/spec/mailers/previews/user_mailer_preview.rb +++ b/spec/mailers/previews/user_mailer_preview.rb @@ -103,4 +103,9 @@ class UserMailerPreview < ActionMailer::Preview def terms_of_service_changed UserMailer.terms_of_service_changed(User.first, TermsOfService.live.first) end + + # Preview this email at http://localhost:3000/rails/mailers/user_mailer/announcement_published + def announcement_published + UserMailer.announcement_published(User.first, Announcement.last) + end end diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index 2385ede50..88f9d12ca 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -14,6 +14,43 @@ RSpec.describe UserMailer do end end + shared_examples 'optional bulk mailer settings' do + context 'when no optional bulk mailer settings are present' do + it 'does not include delivery method options' do + expect(mail.message.delivery_method.settings).to be_empty + end + end + + context 'when optional bulk mailer settings are present' do + let(:smtp_settings) do + { + address: 'localhost', + port: 25, + authentication: 'none', + } + end + + before do + Rails.configuration.x.email ||= ActiveSupport::OrderedOptions.new + Rails.configuration.x.email.update({ bulk_mail: { smtp_settings: } }) + end + + after do + Rails.configuration.x.email = nil + end + + it 'uses the bulk mailer settings' do + expect(mail.message.delivery_method.settings).to eq({ + address: 'localhost', + port: 25, + authentication: nil, + enable_starttls: nil, + enable_starttls_auto: true, + }) + end + end + end + let(:receiver) { Fabricate(:user) } describe '#confirmation_instructions' do @@ -316,6 +353,8 @@ RSpec.describe UserMailer do .and(have_subject(I18n.t('user_mailer.terms_of_service_changed.subject'))) .and(have_body_text(I18n.t('user_mailer.terms_of_service_changed.changelog'))) end + + it_behaves_like 'optional bulk mailer settings' end describe '#announcement_published' do @@ -328,5 +367,7 @@ RSpec.describe UserMailer do .and(have_subject(I18n.t('user_mailer.announcement_published.subject'))) .and(have_body_text(I18n.t('user_mailer.announcement_published.description', domain: local_domain_uri.host))) end + + it_behaves_like 'optional bulk mailer settings' end end