diff --git a/client/src/Pages/Settings/index.tsx b/client/src/Pages/Settings/index.tsx index 70a8e1bb6..5fda73382 100644 --- a/client/src/Pages/Settings/index.tsx +++ b/client/src/Pages/Settings/index.tsx @@ -186,8 +186,7 @@ export const SettingsPage = () => { if ( !formValues.systemEmailHost || !formValues.systemEmailPort || - !formValues.systemEmailAddress || - !formValues.systemEmailPassword + !formValues.systemEmailAddress ) { alert("Please fill in all required email fields before testing."); return; @@ -198,12 +197,14 @@ export const SettingsPage = () => { systemEmailHost: formValues.systemEmailHost, systemEmailPort: formValues.systemEmailPort, systemEmailAddress: formValues.systemEmailAddress, - systemEmailPassword: formValues.systemEmailPassword, systemEmailSecure: formValues.systemEmailSecure, systemEmailPool: formValues.systemEmailPool, systemEmailIgnoreTLS: formValues.systemEmailIgnoreTLS, systemEmailRequireTLS: formValues.systemEmailRequireTLS, systemEmailRejectUnauthorized: formValues.systemEmailRejectUnauthorized, + ...(formValues.systemEmailPassword && { + systemEmailPassword: formValues.systemEmailPassword, + }), ...(formValues.systemEmailUser && { systemEmailUser: formValues.systemEmailUser }), ...(formValues.systemEmailDisplayName && { systemEmailDisplayName: formValues.systemEmailDisplayName, @@ -749,8 +750,7 @@ export const SettingsPage = () => { disabled={ !form.watch("systemEmailHost") || !form.watch("systemEmailPort") || - !form.watch("systemEmailAddress") || - !form.watch("systemEmailPassword") + !form.watch("systemEmailAddress") } > {t("common.buttons.sendTestEmail")} diff --git a/server/src/service/emailService.ts b/server/src/service/emailService.ts index 3aca5362c..488196983 100755 --- a/server/src/service/emailService.ts +++ b/server/src/service/emailService.ts @@ -127,10 +127,12 @@ export class EmailService implements IEmailService { host: systemEmailHost, port: Number(systemEmailPort), secure: systemEmailSecure, - auth: { - user: systemEmailUser || systemEmailAddress, - pass: systemEmailPassword, - }, + ...(systemEmailPassword && { + auth: { + user: systemEmailUser || systemEmailAddress, + pass: systemEmailPassword, + }, + }), name: systemEmailConnectionHost || "localhost", connectionTimeout: 5000, pool: systemEmailPool, diff --git a/server/test/unit/services/emailService.test.ts b/server/test/unit/services/emailService.test.ts index d18b83917..6721dc3c9 100644 --- a/server/test/unit/services/emailService.test.ts +++ b/server/test/unit/services/emailService.test.ts @@ -315,6 +315,33 @@ describe("EmailService", () => { ); }); + it("omits auth from the transport config when no password is configured", async () => { + const transporter = createMockTransporter(); + const nodemailer = createMockNodemailer(transporter); + const { service } = createService({ nodemailer }); + const config = makeTransportConfig({ systemEmailPassword: undefined }); + + await service.sendEmail("to@example.com", "Subject", "
body
", config); + + const transportArg = (nodemailer.createTransport as jest.Mock).mock.calls[0]?.[0] as Recordbody
", config); + + expect(nodemailer.createTransport).toHaveBeenCalledWith( + expect.objectContaining({ + auth: { user: "user@example.com", pass: "password123" }, + }) + ); + }); + it("uses 'localhost' as name when systemEmailConnectionHost is falsy", async () => { const transporter = createMockTransporter(); const nodemailer = createMockNodemailer(transporter);