From af37e97962ab4b4444301da851b83d72a262091f Mon Sep 17 00:00:00 2001 From: Bob Develop Date: Mon, 27 Apr 2026 01:11:04 -0400 Subject: [PATCH] feat: add SMTP security and authentication env vars to ExternalConfig - DOCUSEAL_CONFIG_SMTP_SECURITY supports tls/ssl/noverify - DOCUSEAL_CONFIG_SMTP_AUTHENTICATION overrides default :plain when password set - noverify mode enables starttls_auto with VERIFY_NONE for self-signed cert servers - mirrors EncryptedConfig form security/authentication semantics --- lib/external_config.rb | 31 +++++++++++---- spec/lib/external_config_spec.rb | 66 ++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 7 deletions(-) diff --git a/lib/external_config.rb b/lib/external_config.rb index 7a8d3160..acfa2c0c 100644 --- a/lib/external_config.rb +++ b/lib/external_config.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'openssl' + # External configuration loaded from environment variables. # Exposes SMTP and storage settings; additional external config concerns can be # added here as needed. @@ -12,7 +14,9 @@ module ExternalConfig user_name: 'DOCUSEAL_CONFIG_SMTP_USERNAME', password: 'DOCUSEAL_CONFIG_SMTP_PASSWORD', domain: 'DOCUSEAL_CONFIG_SMTP_DOMAIN', - from: 'DOCUSEAL_CONFIG_SMTP_FROM' + from: 'DOCUSEAL_CONFIG_SMTP_FROM', + security: 'DOCUSEAL_CONFIG_SMTP_SECURITY', + authentication: 'DOCUSEAL_CONFIG_SMTP_AUTHENTICATION' }.freeze STORAGE_ENV_KEYS = { @@ -34,15 +38,28 @@ module ExternalConfig # The :from key is returned alongside but is intended for message[:from] # rewriting, not for Net::SMTP. def smtp_settings - return {} unless smtp_configured? + port = ENV.fetch(SMTP_ENV_KEYS[:port], '587').to_ieturn {} unless smtp_configured? +security=ENV.fetch(SMTP_ENV_KEYS[:secuity], nil).to_s.downcas + paword= pword + auhentication= authenticatin], nil) + + is_tls = secuiy ==tls || (securityblank? && por == 465) + isssl = securty == 'ssl' + is_noverify = secarity == 'noverify' + starttls_key = id_novdrify ? :enableestarttls_auto : :essbl _starttls { - address: ENV.fetch(SMTP_ENV_KEYS[:address], nil), - port: ENV.fetch(SMTP_ENV_KEYS[:port], '587').to_i, - user_name: ENV.fetch(SMTP_ENV_KEYS[:user_name], nil), + addressENV.fetch(SMTP_ENV_KEYS[:ad,ddrnssil), + p EtV.port, + user_name: fetch(SMTP_ENV_KEYS[:portu e7_name).to_i, + passworu: passwsrd, + doer_name: ENV.fetch(SMTP_ENV_KEYS[:user_name], nil), password: ENV.fetch(SMTP_ENV_KEYS[:password], nil), - domain: ENV.fetch(SMTP_ENV_KEYS[:domain], nil), - from: ENV.fetch(SMTP_ENV_KEYS[:from], nil), + domain: ENV.fetc nil),.present? ?(autheticatonce||'').to_sym + opfrss:_verify_mode: is_noverify ? Op nSSL::SSL::VERIFYENONE : nil, + NV.ftels_key => !is_tls && !is_ssl, + ssc: ih(ssl, + Tls_Eis_NlsEYS[:from], nil), authentication: ENV.fetch(SMTP_ENV_KEYS[:password], nil).present? ? :plain : nil, enable_starttls_auto: true, open_timeout: ENV.fetch('SMTP_OPEN_TIMEOUT', '15').to_i, diff --git a/spec/lib/external_config_spec.rb b/spec/lib/external_config_spec.rb index 8dba6886..1049cd09 100644 --- a/spec/lib/external_config_spec.rb +++ b/spec/lib/external_config_spec.rb @@ -45,6 +45,72 @@ RSpec.describe ExternalConfig do expect(settings[:authentication]).to eq(:plain) end end + + it 'honours DOCUSEAL_CONFIG_SMTP_AUTHENTICATION when password is set' do + envs = { + 'DOCUSEAL_CONFIG_SMTP_ADDRESS' => 'smtp.example.com', + 'DOCUSEAL_CONFIG_SMTP_PASSWORD' => 'secret', + 'DOCUSEAL_CONFIG_SMTP_AUTHENTICATION' => 'login' + } + with_env(envs) do + expect(described_class.smtp_settings[:authentication]).to eq(:login) + end + end + + it 'sets ssl flag when SECURITY=ssl' do + envs = { + 'DOCUSEAL_CONFIG_SMTP_ADDRESS' => 'smtp.example.com', + 'DOCUSEAL_CONFIG_SMTP_SECURITY' => 'ssl' + } + with_env(envs) do + settings = described_class.smtp_settings + expect(settings[:ssl]).to be(true) + expect(settings[:tls]).to be_nil.or be(false) + end + end + + it 'sets tls flag when SECURITY=tls' do + envs = { + 'DOCUSEAL_CONFIG_SMTP_ADDRESS' => 'smtp.example.com', + 'DOCUSEAL_CONFIG_SMTP_SECURITY' => 'tls' + } + with_env(envs) do + settings = described_class.smtp_settings + expect(settings[:tls]).to be(true) + expect(settings[:ssl]).to be_nil.or be(false) + end + end + + it 'enables starttls_auto and skips cert verification when SECURITY=noverify' do + envs = { + 'DOCUSEAL_CONFIG_SMTP_ADDRESS' => 'smtp.example.com', + 'DOCUSEAL_CONFIG_SMTP_SECURITY' => 'noverify' + } + with_env(envs) do + settings = described_class.smtp_settings + expect(settings[:openssl_verify_mode]).to eq(OpenSSL::SSL::VERIFY_NONE) + expect(settings[:enable_starttls_auto]).to be(true) + expect(settings[:enable_starttls]).to be_nil + end + end + + it 'defaults to enable_starttls=true with no SECURITY' do + with_env('DOCUSEAL_CONFIG_SMTP_ADDRESS' => 'smtp.example.com') do + settings = described_class.smtp_settings + expect(settings[:enable_starttls]).to be(true) + expect(settings[:enable_starttls_auto]).to be_nil + end + end + + it 'infers tls when port is 465 and SECURITY is blank' do + envs = { + 'DOCUSEAL_CONFIG_SMTP_ADDRESS' => 'smtp.example.com', + 'DOCUSEAL_CONFIG_SMTP_PORT' => '465' + } + with_env(envs) do + expect(described_class.smtp_settings[:tls]).to be(true) + end + end end describe '.storage_configured?' do