class MailIdentity < ApplicationRecord include Auditable encrypts :smtp_password require "openssl" has_many :mailings, dependent: :restrict_with_exception ENCRYPTIONS = Catalog::MAIL_ENCRYPTIONS.keys.freeze # Mapping host SMTP → IMAP tipici dei provider usati in produzione. IMAP_HOST_HINTS = { "aruba.it" => "imaps.aruba.it", "smtps.aruba.it" => "imaps.aruba.it", "smtp.aruba.it" => "imaps.aruba.it", "gmail.com" => "imap.gmail.com", "smtp.gmail.com" => "imap.gmail.com", "outlook.com" => "outlook.office365.com", "smtp.office365.com" => "outlook.office365.com" }.freeze validates :name, :from_name, :from_email, :smtp_host, :smtp_port, presence: true validates :from_email, format: { with: URI::MailTo::EMAIL_REGEXP } validates :reply_to, format: { with: URI::MailTo::EMAIL_REGEXP }, allow_blank: true validates :smtp_port, numericality: { in: 1..65535 } validates :imap_port, numericality: { in: 1..65535 }, allow_nil: true validates :encryption, inclusion: { in: ENCRYPTIONS } validates :smtp_authentication, inclusion: { in: Catalog::MAIL_AUTH_METHODS.keys } validate :encryption_matches_port before_validation :apply_imap_defaults scope :active, -> { where(active: true) } scope :imap_enabled, -> { where(imap_enabled: true) } scope :ordered, -> { order(:name) } def from_header %(#{from_name} <#{from_email}>) end def smtp_settings settings = { address: smtp_host, port: smtp_port, enable_starttls_auto: encryption == "starttls", ssl: encryption == "tls", openssl_verify_mode: verify_ssl? ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE, open_timeout: 15, read_timeout: 60 } if smtp_username.present? settings[:user_name] = smtp_username settings[:password] = smtp_password settings[:authentication] = smtp_authentication.to_sym end settings end def imap_username smtp_username.presence || from_email end def effective_imap_host imap_host.presence || inferred_imap_host end def effective_imap_port (imap_port.presence || 993).to_i end def imap_ready? imap_enabled? && effective_imap_host.present? && effective_imap_port.positive? end def imap_settings { address: effective_imap_host, port: effective_imap_port, ssl: true, user_name: imap_username, password: smtp_password } end def inferred_imap_host host = smtp_host.to_s.downcase.strip return if host.blank? IMAP_HOST_HINTS.each do |needle, imap| return imap if host == needle || host.end_with?(".#{needle}") || host.include?(needle) end # Fallback generico: smtp.X → imap.X, smtps.X → imaps.X if host.start_with?("smtps.") host.sub(/\Asmtps\./, "imaps.") elsif host.start_with?("smtp.") host.sub(/\Asmtp\./, "imap.") end end private def apply_imap_defaults self.imap_port = 993 if imap_port.blank? self.imap_enabled = true if imap_enabled.nil? self.imap_host = inferred_imap_host if imap_host.blank? && inferred_imap_host.present? end def encryption_matches_port return if smtp_port.blank? || encryption.blank? if encryption == "tls" && smtp_port == 587 errors.add(:smtp_port, "con SSL/TLS va usata la porta 465 (es. smtps.aruba.it)") elsif encryption == "starttls" && smtp_port == 465 errors.add(:smtp_port, "con STARTTLS va usata la porta 587 (es. smtp.aruba.it)") end end end