diff --git a/.env.example b/.env.example index a153d08e..2ef17b07 100644 --- a/.env.example +++ b/.env.example @@ -72,8 +72,11 @@ SMTP_PASSWORD= # Email отправителя (если не указан, используется SMTP_USER) SMTP_FROM_EMAIL= SMTP_FROM_NAME=VPN Service -# Использовать TLS шифрование +# Использовать STARTTLS (порт 587 / 25). Не путать с SMTP_USE_SSL. SMTP_USE_TLS=true +# Использовать implicit TLS (SMTPS). Автоматически включается при SMTP_PORT=465. +# Для портов 25/587 оставить false. +SMTP_USE_SSL=false # Уведомления администраторов ADMIN_NOTIFICATIONS_ENABLED=true diff --git a/app/cabinet/services/email_service.py b/app/cabinet/services/email_service.py index 00964f83..1d9fae90 100644 --- a/app/cabinet/services/email_service.py +++ b/app/cabinet/services/email_service.py @@ -45,18 +45,26 @@ class EmailService: def use_tls(self) -> bool: return settings.SMTP_USE_TLS + @property + def use_ssl(self) -> bool: + # Port 465 always implies implicit TLS (SMTPS, RFC 8314). + return settings.SMTP_USE_SSL or self.port == 465 + def is_configured(self) -> bool: """Check if SMTP is properly configured.""" return settings.is_smtp_configured() def _get_smtp_connection(self) -> smtplib.SMTP: """Create and return SMTP connection.""" - smtp = smtplib.SMTP(self.host, self.port, timeout=30) - smtp.ehlo() - - if self.use_tls: - smtp.starttls() + if self.use_ssl: + smtp: smtplib.SMTP = smtplib.SMTP_SSL(self.host, self.port, timeout=30) smtp.ehlo() + else: + smtp = smtplib.SMTP(self.host, self.port, timeout=30) + smtp.ehlo() + if self.use_tls: + smtp.starttls() + smtp.ehlo() # Only attempt login if credentials are provided AND server supports AUTH if self.user and self.password: diff --git a/app/config.py b/app/config.py index 8b6d28d7..9af450c5 100644 --- a/app/config.py +++ b/app/config.py @@ -1014,6 +1014,8 @@ class Settings(BaseSettings): SMTP_FROM_EMAIL: str | None = None SMTP_FROM_NAME: str = 'VPN Service' SMTP_USE_TLS: bool = True + # Implicit TLS (SMTPS) — required for port 465. Auto-enabled when SMTP_PORT == 465. + SMTP_USE_SSL: bool = False # Ban System Integration (BedolagaBan monitoring) BAN_SYSTEM_ENABLED: bool = False