Skip to content

Commit 0abedd7

Browse files
committed
EHLO SMTP setting
1 parent 841d55a commit 0abedd7

File tree

33 files changed

+2615
-2123
lines changed

33 files changed

+2615
-2123
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
77
- **Templates**: Added option to choose between visual email builder or MJML code editor when creating templates
88
- **Templates**: Added ability to translate email templates to languages configured in workspace settings
99
- **Contacts**: Fixed invalid "Blacklisted" status option in change status dropdown, replaced with valid "Bounced" and "Complained" statuses (#285)
10+
- **SMTP**: Added configurable EHLO hostname for SMTP connections. Some SMTP servers reject `EHLO localhost`; users can now set a custom hostname (e.g., their domain) via the `SMTP_EHLO_HOSTNAME` env var, setup wizard, or workspace integration settings. Defaults to the SMTP host value when empty.
1011

1112
## [27.4] - 2026-03-01
1213

config/config.go

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ type EnvValues struct {
5252
SMTPFromEmail string
5353
SMTPFromName string
5454
SMTPUseTLS string // "true", "false", or "" (empty = not set, defaults to true)
55+
SMTPEHLOHostname string
5556
SMTPRelayEnabled string // "true", "false", or "" (empty = not set, allows setup wizard to configure)
5657
SMTPRelayDomain string
5758
SMTPRelayPort int
@@ -136,13 +137,14 @@ type TracingConfig struct {
136137
}
137138

138139
type SMTPConfig struct {
139-
Host string
140-
Port int
141-
Username string
142-
Password string
143-
FromEmail string
144-
FromName string
145-
UseTLS bool
140+
Host string
141+
Port int
142+
Username string
143+
Password string
144+
FromEmail string
145+
FromName string
146+
UseTLS bool
147+
EHLOHostname string
146148
}
147149

148150
type SMTPRelayConfig struct {
@@ -187,6 +189,7 @@ type SystemSettings struct {
187189
SMTPFromEmail string
188190
SMTPFromName string
189191
SMTPUseTLS bool
192+
SMTPEHLOHostname string
190193
TelemetryEnabled bool
191194
CheckForUpdates bool
192195
SMTPRelayEnabled bool
@@ -284,6 +287,8 @@ func loadSystemSettings(db *sql.DB, secretKey string) (*SystemSettings, error) {
284287
settings.SMTPUseTLS = smtpUseTLS != "false"
285288
}
286289

290+
settings.SMTPEHLOHostname = settingsMap["smtp_ehlo_hostname"]
291+
287292
// Decrypt SMTP username if present
288293
if encryptedUsername, ok := settingsMap["encrypted_smtp_username"]; ok && encryptedUsername != "" {
289294
if decrypted, err := crypto.DecryptFromHexString(encryptedUsername, secretKey); err == nil {
@@ -517,6 +522,7 @@ func LoadWithOptions(opts LoadOptions) (*Config, error) {
517522
SMTPFromEmail: v.GetString("SMTP_FROM_EMAIL"),
518523
SMTPFromName: v.GetString("SMTP_FROM_NAME"),
519524
SMTPUseTLS: smtpUseTLSStr, // "true", "false", or "" (empty = not set, defaults to true)
525+
SMTPEHLOHostname: v.GetString("SMTP_EHLO_HOSTNAME"),
520526
SMTPRelayEnabled: smtpRelayEnabledStr, // "true", "false", or "" (empty = not set)
521527
SMTPRelayDomain: v.GetString("SMTP_RELAY_DOMAIN"),
522528
SMTPRelayPort: v.GetInt("SMTP_RELAY_PORT"),
@@ -561,13 +567,14 @@ func LoadWithOptions(opts LoadOptions) (*Config, error) {
561567

562568
// SMTP settings - env vars override database
563569
smtpConfig = SMTPConfig{
564-
Host: envVals.SMTPHost,
565-
Port: envVals.SMTPPort,
566-
Username: envVals.SMTPUsername,
567-
Password: envVals.SMTPPassword,
568-
FromEmail: envVals.SMTPFromEmail,
569-
FromName: envVals.SMTPFromName,
570-
UseTLS: envVals.SMTPUseTLS != "false", // Default to true unless explicitly set to false
570+
Host: envVals.SMTPHost,
571+
Port: envVals.SMTPPort,
572+
Username: envVals.SMTPUsername,
573+
Password: envVals.SMTPPassword,
574+
FromEmail: envVals.SMTPFromEmail,
575+
FromName: envVals.SMTPFromName,
576+
UseTLS: envVals.SMTPUseTLS != "false", // Default to true unless explicitly set to false
577+
EHLOHostname: envVals.SMTPEHLOHostname,
571578
}
572579

573580
// Use database values as fallback
@@ -599,6 +606,9 @@ func LoadWithOptions(opts LoadOptions) (*Config, error) {
599606
if envVals.SMTPUseTLS == "" {
600607
smtpConfig.UseTLS = systemSettings.SMTPUseTLS
601608
}
609+
if smtpConfig.EHLOHostname == "" {
610+
smtpConfig.EHLOHostname = systemSettings.SMTPEHLOHostname
611+
}
602612

603613
// SMTP Relay settings - env vars override database
604614
smtpRelayConfig = SMTPRelayConfig{
@@ -635,13 +645,14 @@ func LoadWithOptions(opts LoadOptions) (*Config, error) {
635645
rootEmail = envVals.RootEmail
636646
apiEndpoint = envVals.APIEndpoint
637647
smtpConfig = SMTPConfig{
638-
Host: envVals.SMTPHost,
639-
Port: envVals.SMTPPort,
640-
Username: envVals.SMTPUsername,
641-
Password: envVals.SMTPPassword,
642-
FromEmail: envVals.SMTPFromEmail,
643-
FromName: envVals.SMTPFromName,
644-
UseTLS: envVals.SMTPUseTLS != "false", // Default to true unless explicitly set to false
648+
Host: envVals.SMTPHost,
649+
Port: envVals.SMTPPort,
650+
Username: envVals.SMTPUsername,
651+
Password: envVals.SMTPPassword,
652+
FromEmail: envVals.SMTPFromEmail,
653+
FromName: envVals.SMTPFromName,
654+
UseTLS: envVals.SMTPUseTLS != "false", // Default to true unless explicitly set to false
655+
EHLOHostname: envVals.SMTPEHLOHostname,
645656
}
646657
// Apply defaults for first-run
647658
if smtpConfig.Port == 0 {

console/src/components/settings/Integrations.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,6 +1701,13 @@ export function Integrations({ workspace, onSave, loading, isOwner }: Integratio
17011701
)
17021702
}}
17031703
</Form.Item>
1704+
<Form.Item
1705+
name={['smtp', 'ehlo_hostname']}
1706+
label={t`EHLO Hostname`}
1707+
tooltip={t`The hostname your server identifies itself as when connecting to the SMTP server. Defaults to the SMTP host value if empty.`}
1708+
>
1709+
<Input placeholder={t`Defaults to SMTP host`} disabled={!isOwner} />
1710+
</Form.Item>
17041711
</>
17051712
)}
17061713

@@ -1937,6 +1944,13 @@ export function Integrations({ workspace, onSave, loading, isOwner }: Integratio
19371944
)}
19381945
</Descriptions.Item>
19391946
)
1947+
if (provider.smtp.ehlo_hostname) {
1948+
items.push(
1949+
<Descriptions.Item key="ehlo" label={t`EHLO Hostname`}>
1950+
{provider.smtp.ehlo_hostname}
1951+
</Descriptions.Item>
1952+
)
1953+
}
19401954
} else if (provider.kind === 'ses' && provider.ses) {
19411955
items.push(
19421956
<Descriptions.Item key="region" label={t`AWS Region`}>

console/src/i18n/locales/ca.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)