fix(server/email): emails configuration is secure by default but can be overridden (#5417)
This commit is contained in:
@@ -94,6 +94,7 @@ 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
|
||||
|
||||
FRONTEND_ORIGIN: 'http://127.0.0.1'
|
||||
ONBOARDING_STREAM_URL: 'https://latest.speckle.systems/projects/843d07eb10'
|
||||
|
||||
@@ -75,6 +75,7 @@ EMAIL=true
|
||||
EMAIL_HOST="127.0.0.1"
|
||||
EMAIL_FROM="no-reply@example.org"
|
||||
EMAIL_PORT="1025"
|
||||
EMAIL_SECURE="false"
|
||||
|
||||
# EMAIL_HOST="-> FILL IN <-"
|
||||
# EMAIL_PORT="-> FILL IN <-"
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
import { emailLogger as logger } from '@/observability/logging'
|
||||
import { MisconfiguredEnvironmentError } from '@/modules/shared/errors'
|
||||
import { isEmailEnabled, isTestEnv } from '@/modules/shared/helpers/envHelper'
|
||||
import {
|
||||
getEmailHost,
|
||||
getEmailPassword,
|
||||
getEmailPort,
|
||||
getEmailUsername,
|
||||
isEmailEnabled,
|
||||
isSecureEmailEnabled,
|
||||
isTestEnv
|
||||
} from '@/modules/shared/helpers/envHelper'
|
||||
import type { Transporter } from 'nodemailer'
|
||||
import { createTransport } from 'nodemailer'
|
||||
|
||||
@@ -11,18 +19,23 @@ const createJsonEchoTransporter = () => createTransport({ jsonTransport: true })
|
||||
const initSmtpTransporter = async () => {
|
||||
try {
|
||||
const smtpTransporter = createTransport({
|
||||
host: process.env.EMAIL_HOST || '127.0.0.1',
|
||||
port: parseInt(process.env.EMAIL_PORT || '587'),
|
||||
secure: process.env.EMAIL_SECURE === 'true',
|
||||
host: getEmailHost(),
|
||||
port: getEmailPort(),
|
||||
secure: isSecureEmailEnabled(),
|
||||
auth: {
|
||||
user: process.env.EMAIL_USERNAME,
|
||||
pass: process.env.EMAIL_PASSWORD
|
||||
user: getEmailUsername(),
|
||||
pass: getEmailPassword()
|
||||
},
|
||||
pool: true,
|
||||
maxConnections: 20,
|
||||
maxMessages: Infinity
|
||||
})
|
||||
await smtpTransporter.verify()
|
||||
const transporterVerified = await smtpTransporter.verify()
|
||||
if (!transporterVerified) {
|
||||
logger.error(
|
||||
'📧 Email provider is likely misconfigured as validation failed, check config variables'
|
||||
)
|
||||
}
|
||||
return smtpTransporter
|
||||
} catch (e) {
|
||||
logger.error(e, '📧 Email provider is misconfigured, check config variables.')
|
||||
|
||||
@@ -7,14 +7,16 @@ import { ensureError } from '@speckle/shared'
|
||||
export function getStringFromEnv(
|
||||
envVarKey: string,
|
||||
options?: Partial<{
|
||||
default?: string
|
||||
/**
|
||||
* If set to true, wont throw if the env var is not set
|
||||
*/
|
||||
unsafe: boolean
|
||||
unsafe?: boolean
|
||||
}>
|
||||
): string {
|
||||
const envVar = process.env[envVarKey]
|
||||
if (!envVar) {
|
||||
if (options?.default !== undefined) return options.default
|
||||
if (options?.unsafe) return ''
|
||||
throw new MisconfiguredEnvironmentError(`${envVarKey} env var not configured`)
|
||||
}
|
||||
@@ -334,10 +336,6 @@ export function getOnboardingStreamCacheBustNumber() {
|
||||
return parseInt(val) || 1
|
||||
}
|
||||
|
||||
export function getEmailFromAddress() {
|
||||
return getStringFromEnv('EMAIL_FROM')
|
||||
}
|
||||
|
||||
export function getMaximumProjectModelsPerPage() {
|
||||
return getIntFromEnv('MAX_PROJECT_MODELS_PER_PAGE', '500')
|
||||
}
|
||||
@@ -373,6 +371,30 @@ export function isEmailEnabled() {
|
||||
return getBooleanFromEnv('EMAIL')
|
||||
}
|
||||
|
||||
export function getEmailFromAddress() {
|
||||
return getStringFromEnv('EMAIL_FROM')
|
||||
}
|
||||
|
||||
export function getEmailHost() {
|
||||
return getStringFromEnv('EMAIL_HOST', { default: '127.0.0.1' })
|
||||
}
|
||||
|
||||
export function getEmailPort() {
|
||||
return getIntFromEnv('EMAIL_PORT', '587')
|
||||
}
|
||||
|
||||
export function isSecureEmailEnabled() {
|
||||
return getBooleanFromEnv('EMAIL_SECURE', true) // default to secure
|
||||
}
|
||||
|
||||
export function getEmailUsername() {
|
||||
return getStringFromEnv('EMAIL_USERNAME', { unsafe: true }) // can be empty
|
||||
}
|
||||
|
||||
export function getEmailPassword() {
|
||||
return getStringFromEnv('EMAIL_PASSWORD', { unsafe: true }) // can be empty
|
||||
}
|
||||
|
||||
export const getFileImporterQueuePostgresUrl = () =>
|
||||
process.env['FILEIMPORT_QUEUE_POSTGRES_URL'] ?? null
|
||||
|
||||
|
||||
@@ -971,18 +971,20 @@ Generate the environment variables for Speckle server and Speckle objects deploy
|
||||
- name: EMAIL
|
||||
value: "true"
|
||||
- name: EMAIL_HOST
|
||||
value: "{{ .Values.server.email.host }}"
|
||||
value: {{ .Values.server.email.host | quote }}
|
||||
- name: EMAIL_PORT
|
||||
value: "{{ .Values.server.email.port }}"
|
||||
value: {{ .Values.server.email.port | quote }}
|
||||
- name: EMAIL_USERNAME
|
||||
value: "{{ .Values.server.email.username }}"
|
||||
value: {{ .Values.server.email.username | quote }}
|
||||
- name: EMAIL_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ default .Values.secretName .Values.server.email.password.secretName }}
|
||||
key: {{ default "email_password" .Values.server.email.password.secretKey }}
|
||||
- name: EMAIL_FROM
|
||||
value: "{{ .Values.server.email.from }}"
|
||||
value: {{ .Values.server.email.from | quote }}
|
||||
- name: EMAIL_SECURE
|
||||
value: {{ .Values.server.email.secure | quote }}
|
||||
- name: EMAIL_VERIFICATION_TIMEOUT_MINUTES
|
||||
value: {{ .Values.server.email.verificationTimeoutMinutes | quote }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1307,6 +1307,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"secure": {
|
||||
"type": "boolean",
|
||||
"description": "If true, will use TLS when connecting to the email server",
|
||||
"default": true
|
||||
},
|
||||
"networkPolicy": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -800,6 +800,9 @@ 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
|
||||
##
|
||||
secure: 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:
|
||||
|
||||
Reference in New Issue
Block a user