From 38a1d5e7a1660b0cf4cb3d8b51bb1cb92017fcad Mon Sep 17 00:00:00 2001 From: Br0wnHammer Date: Fri, 13 Jun 2025 12:22:28 +0530 Subject: [PATCH] Implement PR Comments --- client/src/Pages/Settings/SettingsEmail.jsx | 76 +++++++++++++-------- client/src/Utils/NetworkService.js | 4 -- client/src/Validation/validation.js | 8 +-- client/src/locales/en.json | 10 +-- server/db/models/AppSettings.js | 23 +++++++ server/service/emailService.js | 12 ++-- server/validation/joi.js | 12 +++- 7 files changed, 96 insertions(+), 49 deletions(-) diff --git a/client/src/Pages/Settings/SettingsEmail.jsx b/client/src/Pages/Settings/SettingsEmail.jsx index 113d5bf44..50f90c38f 100644 --- a/client/src/Pages/Settings/SettingsEmail.jsx +++ b/client/src/Pages/Settings/SettingsEmail.jsx @@ -26,6 +26,21 @@ const SettingsEmail = ({ const { t } = useTranslation(); const theme = useTheme(); + // Destructure settings with default values + const { + systemEmailHost = "", + systemEmailPort = "", + systemEmailSecure = false, + systemEmailPool = false, + systemEmailUser = "", + systemEmailAddress = "", + systemEmailPassword = "", + systemEmailTLSServername = "", + systemEmailConnectionHost = "localhost", + systemEmailIgnoreTLS = false, + systemEmailRequireTLS = false, + systemEmailRejectUnauthorized = true, + } = settingsData?.settings || {}; // Local state const [password, setPassword] = useState(""); const [hasBeenReset, setHasBeenReset] = useState(false); @@ -48,25 +63,31 @@ const SettingsEmail = ({ const handleSendTestEmail = () => { // Collect current form values const emailConfig = { - systemEmailHost: settingsData?.settings?.systemEmailHost, - systemEmailPort: settingsData?.settings?.systemEmailPort, - systemEmailSecure: settingsData?.settings?.systemEmailSecure, - systemEmailPool: settingsData?.settings?.systemEmailPool, - systemEmailUser: settingsData?.settings?.systemEmailUser, - systemEmailAddress: settingsData?.settings?.systemEmailAddress, - systemEmailPassword: password || settingsData?.settings?.systemEmailPassword, - systemEmailConnectionHost: settingsData?.settings?.systemEmailConnectionHost, - systemEmailTLSServername: settingsData?.settings?.systemEmailTLSServername, - systemEmailIgnoreTLS: settingsData?.settings?.systemEmailIgnoreTLS, - systemEmailRequireTLS: settingsData?.settings?.systemEmailRequireTLS, - systemEmailRejectUnauthorized: - settingsData?.settings?.systemEmailRejectUnauthorized, + systemEmailHost, + systemEmailPort, + systemEmailSecure, + systemEmailPool, + systemEmailUser, + systemEmailAddress, + systemEmailPassword: password || systemEmailPassword, + systemEmailTLSServername, + systemEmailConnectionHost, + systemEmailIgnoreTLS, + systemEmailRequireTLS, + systemEmailRejectUnauthorized, }; // Basic validation - if (!emailConfig.systemEmailHost || !emailConfig.systemEmailPort) { + if ( + !emailConfig.systemEmailHost || + !emailConfig.systemEmailPort || + !emailConfig.systemEmailAddress + ) { createToast({ - body: t("settingsEmailRequiredFields", "Email host and port are required"), + body: t( + "settingsEmailRequiredFields", + "Email address, host and port are required" + ), variant: "error", }); return; @@ -98,7 +119,7 @@ const SettingsEmail = ({ @@ -108,7 +129,7 @@ const SettingsEmail = ({ name="systemEmailPort" placeholder="425" type="number" - value={settingsData?.settings?.systemEmailPort ?? ""} + value={systemEmailPort} onChange={handleChange} /> @@ -123,13 +144,13 @@ const SettingsEmail = ({ {t("settingsEmailSecure")} {t("settingsEmailPool")} @@ -138,7 +159,7 @@ const SettingsEmail = ({ @@ -147,7 +168,7 @@ const SettingsEmail = ({ @@ -189,34 +210,33 @@ const SettingsEmail = ({ {t("settingsEmailIgnoreTLS")} {t("settingsEmailRequireTLS")} {t("settingsEmailRejectUnauthorized")} @@ -225,7 +245,7 @@ const SettingsEmail = ({ diff --git a/client/src/Utils/NetworkService.js b/client/src/Utils/NetworkService.js index dcb21df92..3e0ac6103 100644 --- a/client/src/Utils/NetworkService.js +++ b/client/src/Utils/NetworkService.js @@ -1020,10 +1020,6 @@ class NetworkService { systemEmailRequireTLS: emailConfig.systemEmailRequireTLS, systemEmailRejectUnauthorized: emailConfig.systemEmailRejectUnauthorized, systemEmailTLSServername: emailConfig.systemEmailTLSServername, - // Only include these if they are present - ...(emailConfig.systemEmailConnectionHost && { - systemEmailConnectionHost: emailConfig.systemEmailConnectionHost, - }), ...(emailConfig.systemEmailUser && { systemEmailUser: emailConfig.systemEmailUser, }), diff --git a/client/src/Validation/validation.js b/client/src/Validation/validation.js index 089722a8d..f1811a124 100644 --- a/client/src/Validation/validation.js +++ b/client/src/Validation/validation.js @@ -295,11 +295,11 @@ const settingsValidation = joi.object({ systemEmailAddress: joi.string().allow(""), systemEmailPassword: joi.string().allow(""), systemEmailUser: joi.string().allow(""), - systemEmailConnectionHost: joi.string().allow(""), + systemEmailConnectionHost: joi.string().allow("").optional(), systemEmailTLSServername: joi.string().allow(""), - systemEmailIgnoreTLS: joi.boolean().optional(), - systemEmailRequireTLS: joi.boolean().optional(), - systemEmailRejectUnauthorized: joi.boolean().optional(), + systemEmailIgnoreTLS: joi.boolean(), + systemEmailRequireTLS: joi.boolean(), + systemEmailRejectUnauthorized: joi.boolean(), }); const dayjsValidator = (value, helpers) => { diff --git a/client/src/locales/en.json b/client/src/locales/en.json index 610c56d0e..ca3f9dcd6 100644 --- a/client/src/locales/en.json +++ b/client/src/locales/en.json @@ -673,17 +673,17 @@ }, "settingsEmail": "Email", "settingsEmailDescription": "Configure the email settings for your system. This is used to send notifications and alerts.", - "settingsEmailHost": "Email host - Hostname or IP address of the SMTP server", + "settingsEmailHost": "Email host - Hostname or IP address to connect to", "settingsEmailPort": "Email port - Port to connect to", "settingsEmailAddress": "Email address - Used for authentication", "settingsEmailPassword": "Email password - Password for authentication", "settingsEmailUser": "Email user - Username for authentication, overrides email address if specified", "settingsEmailFieldResetLabel": "Password is set. Click Reset to change it.", "settingsEmailTLSServername": "TLS Servername - Optional Hostname for TLS Validation when host is an IP", - "settingsEmailIgnoreTLS": "Ignore TLS", - "settingsEmailRequireTLS": "Require TLS", + "settingsEmailIgnoreTLS": "Ignore TLS - Disable STARTTLS", + "settingsEmailRequireTLS": "Require TLS - Force STARTTLS", "settingsEmailRejectUnauthorized": "Reject Unauthorized", - "settingsEmailSecure": "Secure", + "settingsEmailSecure": "Secure - Use SSL", "settingsEmailPool": "Pool", "state": "State", "statusBreadCrumbsStatusPages": "Status Pages", @@ -714,7 +714,7 @@ "settingsTestEmailFailed": "Failed to send test email", "settingsTestEmailFailedWithReason": "Failed to send test email: {{reason}}", "settingsTestEmailUnknownError": "Unknown error", - "settingsEmailRequiredFields": "Email host and port are required", + "settingsEmailRequiredFields": "Email address, host and port are required", "statusMsg": { "paused": "Monitoring is paused.", "up": "Your site is up.", diff --git a/server/db/models/AppSettings.js b/server/db/models/AppSettings.js index c47de06fa..cd63118e9 100755 --- a/server/db/models/AppSettings.js +++ b/server/db/models/AppSettings.js @@ -32,6 +32,29 @@ const AppSettingsSchema = mongoose.Schema( type: String, default: "localhost", }, + systemEmailTLSServername: { + type: String, + }, + systemEmailSecure: { + type: Boolean, + default: false, + }, + systemEmailPool: { + type: Boolean, + default: false, + }, + systemEmailIgnoreTLS: { + type: Boolean, + default: false, + }, + systemEmailRequireTLS: { + type: Boolean, + default: false, + }, + systemEmailRejectUnauthorized: { + type: Boolean, + default: true, + }, singleton: { type: Boolean, required: true, diff --git a/server/service/emailService.js b/server/service/emailService.js index 325871fac..09123ef93 100755 --- a/server/service/emailService.js +++ b/server/service/emailService.js @@ -121,13 +121,15 @@ class EmailService { user: systemEmailUser || systemEmailAddress, pass: systemEmailPassword, }, + name: systemEmailConnectionHost || "localhost", connectionTimeout: 5000, pool: systemEmailPool, - tls: { rejectUnauthorized: systemEmailRejectUnauthorized }, - ignoreTLS: systemEmailIgnoreTLS, - requireTLS: systemEmailRequireTLS, - servername: systemEmailTLSServername, - name: systemEmailConnectionHost || "localhost", + tls: { + rejectUnauthorized: systemEmailRejectUnauthorized, + ignoreTLS: systemEmailIgnoreTLS, + requireTLS: systemEmailRequireTLS, + servername: systemEmailTLSServername, + }, }; this.transporter = this.nodemailer.createTransport(emailConfig); diff --git a/server/validation/joi.js b/server/validation/joi.js index b7858f92d..f9a7d7322 100755 --- a/server/validation/joi.js +++ b/server/validation/joi.js @@ -413,7 +413,13 @@ const updateAppSettingsBodyValidation = joi.object({ systemEmailAddress: joi.string().allow(""), systemEmailPassword: joi.string().allow(""), systemEmailUser: joi.string().allow(""), - systemEmailConnectionHost: joi.string().allow(""), + systemEmailConnectionHost: joi.string().allow("").optional(), + systemEmailTLSServername: joi.string().allow("").optional(), + systemEmailSecure: joi.boolean(), + systemEmailPool: joi.boolean(), + systemEmailIgnoreTLS: joi.boolean(), + systemEmailRequireTLS: joi.boolean(), + systemEmailRejectUnauthorized: joi.boolean(), }); //**************************************** @@ -622,11 +628,11 @@ const sendTestEmailBodyValidation = joi.object({ systemEmailAddress: joi.string(), systemEmailPassword: joi.string(), systemEmailUser: joi.string(), - systemEmailConnectionHost: joi.string(), + systemEmailConnectionHost: joi.string().allow("").optional(), systemEmailIgnoreTLS: joi.boolean(), systemEmailRequireTLS: joi.boolean(), systemEmailRejectUnauthorized: joi.boolean(), - systemEmailTLSServername: joi.string(), + systemEmailTLSServername: joi.string().allow("").optional(), }); export {