Improve email deliverability headers and SMTP identity

This commit is contained in:
2026-03-04 17:37:51 +13:00
parent 4e64f79e64
commit d30a2473ce
5 changed files with 55 additions and 11 deletions

View File

@@ -1 +1 @@
0403261321
0403261736

File diff suppressed because one or more lines are too long

View File

@@ -14,6 +14,7 @@ from email.policy import SMTP as SMTP_POLICY
from email.utils import formataddr, formatdate, make_msgid
from io import BytesIO
from typing import Any, Dict, Optional
from urllib.parse import urlparse
from ..build_info import BUILD_NUMBER
from ..config import settings as env_settings
@@ -512,6 +513,40 @@ def _build_default_base_url() -> str:
return f"http://localhost:{port}"
def _derive_mail_hostname(*, from_address: str) -> str:
runtime = get_runtime_settings()
candidates = (
runtime.magent_application_url,
runtime.magent_proxy_base_url,
env_settings.cors_allow_origin,
)
for candidate in candidates:
normalized = _normalize_display_text(candidate)
if not normalized:
continue
parsed = urlparse(normalized if "://" in normalized else f"https://{normalized}")
hostname = _normalize_display_text(parsed.hostname)
if hostname and "." in hostname:
return hostname
domain = _normalize_display_text(from_address.split("@", 1)[1] if "@" in from_address else None)
if domain and "." in domain:
return domain
return "localhost"
def _add_transactional_headers(
message: EmailMessage,
*,
from_name: str,
from_address: str,
) -> None:
message["Reply-To"] = formataddr((from_name, from_address))
message["Organization"] = env_settings.app_name
message["X-Mailer"] = f"{env_settings.app_name}/{BUILD_NUMBER}"
message["Auto-Submitted"] = "auto-generated"
message["X-Auto-Response-Suppress"] = "All"
def _looks_like_full_html_document(value: str) -> bool:
probe = value.lstrip().lower()
return probe.startswith("<!doctype") or probe.startswith("<html") or "<body" in probe[:300]
@@ -918,8 +953,10 @@ def smtp_email_delivery_warning() -> Optional[str]:
if host.endswith(".mail.protection.outlook.com") and not (username and password):
return (
"Unauthenticated Microsoft 365 relay mode is configured. SMTP acceptance does not "
"confirm mailbox delivery. For reliable delivery, use smtp.office365.com:587 with "
"SMTP credentials or configure a verified Exchange relay connector."
"confirm mailbox delivery, and suspicious messages can still be filtered. For reliable "
"delivery, use smtp.office365.com:587 with SMTP credentials or configure a verified "
"Exchange relay connector and make sure SPF, DKIM, and DMARC are healthy for the "
"sender domain."
)
return None
@@ -986,8 +1023,9 @@ def _send_email_sync(*, recipient_email: str, subject: str, body_text: str, body
delivery_warning = smtp_email_delivery_warning()
if not host or not from_address:
raise RuntimeError("SMTP email settings are incomplete.")
local_hostname = _derive_mail_hostname(from_address=from_address)
logger.info(
"smtp send started recipient=%s from=%s host=%s port=%s tls=%s ssl=%s auth=%s subject=%s",
"smtp send started recipient=%s from=%s host=%s port=%s tls=%s ssl=%s auth=%s subject=%s ehlo=%s",
recipient_email,
from_address,
host,
@@ -996,6 +1034,7 @@ def _send_email_sync(*, recipient_email: str, subject: str, body_text: str, body
use_ssl,
bool(username and password),
subject,
local_hostname,
)
if delivery_warning:
logger.warning("smtp delivery warning host=%s detail=%s", host, delivery_warning)
@@ -1009,6 +1048,11 @@ def _send_email_sync(*, recipient_email: str, subject: str, body_text: str, body
message["Message-ID"] = make_msgid(domain=from_address.split("@", 1)[1])
else:
message["Message-ID"] = make_msgid()
_add_transactional_headers(
message,
from_name=from_name,
from_address=from_address,
)
message.set_content(body_text or _strip_html_for_text(body_html))
if body_html.strip():
message.add_alternative(body_html, subtype="html")
@@ -1027,7 +1071,7 @@ def _send_email_sync(*, recipient_email: str, subject: str, body_text: str, body
)
if use_ssl:
with smtplib.SMTP_SSL(host, port, timeout=20) as smtp:
with smtplib.SMTP_SSL(host, port, timeout=20, local_hostname=local_hostname) as smtp:
logger.debug("smtp ssl connection opened host=%s port=%s", host, port)
if username and password:
smtp.login(username, password)
@@ -1047,7 +1091,7 @@ def _send_email_sync(*, recipient_email: str, subject: str, body_text: str, body
)
return receipt
with smtplib.SMTP(host, port, timeout=20) as smtp:
with smtplib.SMTP(host, port, timeout=20, local_hostname=local_hostname) as smtp:
logger.debug("smtp connection opened host=%s port=%s", host, port)
smtp.ehlo()
if use_tls:

View File

@@ -1,12 +1,12 @@
{
"name": "magent-frontend",
"version": "0403261321",
"version": "0403261736",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "magent-frontend",
"version": "0403261321",
"version": "0403261736",
"dependencies": {
"next": "16.1.6",
"react": "19.2.4",

View File

@@ -1,7 +1,7 @@
{
"name": "magent-frontend",
"private": true,
"version": "0403261321",
"version": "0403261736",
"scripts": {
"dev": "next dev",
"build": "next build",