feat(server/emails): support require TLS configuration option EMAIL_REQUIRE_TLS (#5425)

This commit is contained in:
Iain Sproat
2025-09-12 12:06:25 +01:00
committed by GitHub
parent f6fb76562b
commit 18265b6278
7 changed files with 42 additions and 9 deletions
+2 -1
View File
@@ -94,7 +94,8 @@ services:
S3_REGION: '' # optional, defaults to 'us-east-1'
FILE_SIZE_LIMIT_MB: 1000
EMAIL_FROM: 'no-reply@example.org'
EMAIL_SECURE: 'false' # If connecting to maildev server, do not use TLS
EMAIL_SECURE: 'false' # Force the use of SSL. If connecting to maildev server, do not use SSL.
EMAIL_REQUIRE_TLS: 'false' # Force the use of TLS. If your email server supports STARTTLS, you probably want this enabled instead of EMAIL_SECURE. If connecting to maildev server, do not use TLS.
FRONTEND_ORIGIN: 'http://127.0.0.1'
ONBOARDING_STREAM_URL: 'https://latest.speckle.systems/projects/843d07eb10'
+3
View File
@@ -75,7 +75,10 @@ EMAIL=true
EMAIL_HOST="127.0.0.1"
EMAIL_FROM="no-reply@example.org"
EMAIL_PORT="1025"
# Email secure enables SSL. If your server supports STARTTLS,
# you probably want to set EMAIL_REQUIRE_TLS instead.
EMAIL_SECURE="false"
EMAIL_REQUIRE_TLS="false"
# EMAIL_HOST="-> FILL IN <-"
# EMAIL_PORT="-> FILL IN <-"
@@ -6,8 +6,9 @@ import {
getEmailPort,
getEmailUsername,
isEmailEnabled,
isSecureEmailEnabled,
isTestEnv
isSSLEmailEnabled,
isTestEnv,
isTLSEmailRequired
} from '@/modules/shared/helpers/envHelper'
import type { Transporter } from 'nodemailer'
import { createTransport } from 'nodemailer'
@@ -21,7 +22,8 @@ const initSmtpTransporter = async () => {
const smtpTransporter = createTransport({
host: getEmailHost(),
port: getEmailPort(),
secure: isSecureEmailEnabled(),
requireTLS: isTLSEmailRequired(),
secure: isSSLEmailEnabled(),
auth: {
user: getEmailUsername(),
pass: getEmailPassword()
@@ -3,6 +3,7 @@ import { has, trimEnd } from 'lodash-es'
import * as Environment from '@speckle/shared/environment'
import type { Nullable } from '@speckle/shared'
import { ensureError } from '@speckle/shared'
import { logger } from '@/observability/logging'
export function getStringFromEnv(
envVarKey: string,
@@ -383,8 +384,24 @@ export function getEmailPort() {
return getIntFromEnv('EMAIL_PORT', '587')
}
export function isSecureEmailEnabled() {
return getBooleanFromEnv('EMAIL_SECURE', true) // default to secure
export function isSSLEmailEnabled() {
const sslRequired = getBooleanFromEnv('EMAIL_SECURE', false) // see EMAIL_REQUIRE_TLS
if (sslRequired && isTLSEmailRequired()) {
throw new MisconfiguredEnvironmentError(
'EMAIL_SECURE and EMAIL_REQUIRE_TLS cannot both be true. TLS would typically be preferred over SSL.'
)
}
return sslRequired
}
export function isTLSEmailRequired() {
const tlsRequired = getBooleanFromEnv('EMAIL_REQUIRE_TLS', true) // default to true
if (!tlsRequired && !isSSLEmailEnabled()) {
logger.warn(
'Neither EMAIL_SECURE and EMAIL_REQUIRE_TLS are true. Client will attempt to upgrade to TLS on connect, but will default to whatever the server supports which may be insecure.'
)
}
return tlsRequired
}
export function getEmailUsername() {
@@ -985,6 +985,8 @@ Generate the environment variables for Speckle server and Speckle objects deploy
value: {{ .Values.server.email.from | quote }}
- name: EMAIL_SECURE
value: {{ .Values.server.email.secure | quote }}
- name: EMAIL_REQUIRE_TLS
value: {{ .Values.server.email.requireTLS | quote }}
- name: EMAIL_VERIFICATION_TIMEOUT_MINUTES
value: {{ .Values.server.email.verificationTimeoutMinutes | quote }}
{{- end }}
+6 -1
View File
@@ -1309,7 +1309,12 @@
},
"secure": {
"type": "boolean",
"description": "If true, will use TLS when connecting to the email server",
"description": "If true, will use SSL when connecting to the email server. requireTLS would be preferable if the server supports it. Both 'secure' and 'requireTLS' can be false if the email server does not support encryption, but this is not recommended. Both 'secure' and 'requireTLS' cannot be true at the same time.",
"default": false
},
"requireTLS": {
"type": "boolean",
"description": "If true, will require TLS when connecting to the email server. This is preferable to 'secure' if the email server supports TLS. Both 'secure' and 'requireTLS' can be false if the email server does not support encryption, but this is not recommended. Both 'secure' and 'requireTLS' cannot be true at the same time.",
"default": true
},
"networkPolicy": {
+5 -2
View File
@@ -800,9 +800,12 @@ server:
## @param server.email.password.secretKey The key within the Kubernetes Secret holding the email password as its value.
##
secretKey: ''
## @param server.email.secure If true, will use TLS when connecting to the email server
## @param server.email.secure If true, will use SSL when connecting to the email server. requireTLS would be preferable if the server supports it. Both 'secure' and 'requireTLS' can be false if the email server does not support encryption, but this is not recommended. Both 'secure' and 'requireTLS' cannot be true at the same time.
##
secure: true
secure: false
## @param server.email.requireTLS If true, will require TLS when connecting to the email server. This is preferable to 'secure' if the email server supports TLS. Both 'secure' and 'requireTLS' can be false if the email server does not support encryption, but this is not recommended. Both 'secure' and 'requireTLS' cannot be true at the same time.
##
requireTLS: true
## @extra server.email.networkPolicy If networkPolicy is enabled for Speckle server, this provides the Network Policy with the necessary details to allow egress connections to the email server
##
networkPolicy: