smtp.rb 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. class Channel::Driver::Smtp < Channel::Driver::BaseEmailOutbound
  3. # We're using the same timeouts like in Net::SMTP gem
  4. # but we would like to have the possibility to mock them for tests
  5. DEFAULT_OPEN_TIMEOUT = 30.seconds
  6. DEFAULT_READ_TIMEOUT = 60.seconds
  7. # Sends a message via SMTP
  8. #
  9. # @example
  10. # instance = Channel::Driver::Smtp.new
  11. # instance.deliver(
  12. # {
  13. # host: 'some.host',
  14. # port: 25,
  15. # enable_starttls_auto: true, # optional
  16. # openssl_verify_mode: 'none', # optional
  17. # user: 'someuser',
  18. # password: 'somepass'
  19. # authentication: nil, # nil, autodetection - to use certain schema use 'plain', 'login', 'xoauth2' or 'cram_md5'
  20. # },
  21. # mail_attributes,
  22. # notification
  23. # )
  24. def deliver(options, attr, notification = false) # rubocop:disable Style/OptionalBooleanParameter
  25. # return if we run import mode
  26. return if Setting.get('import_mode')
  27. options = prepare_options(options, attr)
  28. attr = prepare_message_attrs(attr)
  29. smtp_params = build_smtp_params(options)
  30. Certificate::ApplySSLCertificates.ensure_fresh_ssl_context if options[:ssl] || options[:enable_starttls_auto]
  31. deliver_mail(attr, notification, :smtp, smtp_params)
  32. end
  33. def prepare_options(options, attr)
  34. # set smtp defaults
  35. if !options.key?(:port) || options[:port].blank?
  36. options[:port] = 25
  37. end
  38. if !options.key?(:ssl) && options[:port].to_i == 465
  39. options[:ssl] = true
  40. end
  41. if !options.key?(:domain)
  42. # set fqdn, if local fqdn - use domain of sender
  43. fqdn = Setting.get('fqdn')
  44. if fqdn =~ %r{(localhost|\.local^|\.loc^)}i && (attr['from'] || attr[:from])
  45. domain = Mail::Address.new(attr['from'] || attr[:from]).domain
  46. if domain
  47. fqdn = domain
  48. end
  49. end
  50. options[:domain] = fqdn
  51. end
  52. if !options.key?(:enable_starttls_auto)
  53. options[:enable_starttls_auto] = true
  54. end
  55. options
  56. end
  57. def build_smtp_params(options)
  58. ssl_verify_mode = if options[:openssl_verify_mode].present?
  59. options[:openssl_verify_mode]
  60. else
  61. options.fetch(:ssl_verify, true) ? 'peer' : 'none'
  62. end
  63. smtp_params = {
  64. openssl_verify_mode: ssl_verify_mode,
  65. address: options[:host],
  66. port: options[:port],
  67. domain: options[:domain],
  68. enable_starttls_auto: options[:enable_starttls_auto],
  69. open_timeout: DEFAULT_OPEN_TIMEOUT,
  70. read_timeout: DEFAULT_READ_TIMEOUT,
  71. }
  72. # set ssl if needed
  73. if options[:ssl].present?
  74. smtp_params[:ssl] = options[:ssl]
  75. end
  76. # add authentication only if needed
  77. if options[:user].present?
  78. smtp_params[:user_name] = options[:user]
  79. smtp_params[:password] = options[:password]
  80. smtp_params[:authentication] = options[:authentication]
  81. end
  82. smtp_params
  83. end
  84. end