mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 21:15:32 +09:00
fix(email): test saved SMTP config and add TLS modes (#3388)
This commit is contained in:
1 parent
45b78a13c2
commit
cca8227ca6
66 files changed
+2464
-319
No files matched your search
@@ -12,6 +12,7 @@
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fluxer/constants": "workspace:*",
|
||||
"@fluxer/i18n": "workspace:*",
|
||||
"@fluxer/logger": "workspace:*",
|
||||
"itty-time": "catalog:",
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {SmtpEmailProvider} from '@pkgs/email/src/SmtpEmailProvider';
|
||||
import {beforeEach, describe, expect, it, vi} from 'vitest';
|
||||
|
||||
const {createTransport} = vi.hoisted(() => ({createTransport: vi.fn()}));
|
||||
|
||||
vi.mock('nodemailer', () => ({default: {createTransport}}));
|
||||
|
||||
describe('SmtpEmailProvider', () => {
|
||||
beforeEach(() => {
|
||||
createTransport.mockReset();
|
||||
createTransport.mockReturnValue({sendMail: vi.fn(), verify: vi.fn()});
|
||||
});
|
||||
|
||||
it.each([
|
||||
{port: 465, tlsMode: undefined, secure: true, requireTLS: false, ignoreTLS: false},
|
||||
{port: 587, tlsMode: undefined, secure: false, requireTLS: true, ignoreTLS: false},
|
||||
{port: 587, tlsMode: null, secure: false, requireTLS: true, ignoreTLS: false},
|
||||
{port: 587, tlsMode: 'implicit', secure: true, requireTLS: false, ignoreTLS: false},
|
||||
{port: 465, tlsMode: 'starttls', secure: false, requireTLS: true, ignoreTLS: false},
|
||||
{port: 25, tlsMode: 'opportunistic', secure: false, requireTLS: false, ignoreTLS: false},
|
||||
{port: 587, tlsMode: 'none', secure: false, requireTLS: false, ignoreTLS: true},
|
||||
] as const)('maps TLS mode $tlsMode on port $port to nodemailer options', ({port, tlsMode, ...expected}) => {
|
||||
new SmtpEmailProvider({host: 'smtp.example.com', port, username: 'user', password: 'pass', tlsMode});
|
||||
expect(createTransport).toHaveBeenCalledWith(expect.objectContaining(expected));
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {resolveSmtpTlsMode, type SmtpTlsMode, SmtpTlsModes} from '@fluxer/constants/src/SmtpConstants';
|
||||
import {createLogger} from '@fluxer/logger/src/Logger';
|
||||
import type {EmailMessage, IEmailProvider} from '@pkgs/email/src/EmailProviderTypes';
|
||||
import nodemailer, {type Transporter} from 'nodemailer';
|
||||
@@ -11,7 +12,7 @@ interface SmtpEmailConfig {
|
||||
port: number;
|
||||
username: string;
|
||||
password: string;
|
||||
secure?: boolean;
|
||||
tlsMode?: SmtpTlsMode | null;
|
||||
connectionTimeoutMs?: number;
|
||||
greetingTimeoutMs?: number;
|
||||
socketTimeoutMs?: number;
|
||||
@@ -19,12 +20,20 @@ interface SmtpEmailConfig {
|
||||
|
||||
export class SmtpEmailProvider implements IEmailProvider {
|
||||
private readonly transporter: Transporter;
|
||||
private readonly host: string;
|
||||
private readonly port: number;
|
||||
private readonly tlsMode: SmtpTlsMode;
|
||||
|
||||
constructor(config: SmtpEmailConfig) {
|
||||
this.host = config.host;
|
||||
this.port = config.port;
|
||||
this.tlsMode = resolveSmtpTlsMode(config.tlsMode, config.port);
|
||||
this.transporter = nodemailer.createTransport({
|
||||
host: config.host,
|
||||
port: config.port,
|
||||
secure: config.secure ?? true,
|
||||
secure: this.tlsMode === SmtpTlsModes.IMPLICIT,
|
||||
requireTLS: this.tlsMode === SmtpTlsModes.STARTTLS,
|
||||
ignoreTLS: this.tlsMode === SmtpTlsModes.NONE,
|
||||
auth: {
|
||||
user: config.username,
|
||||
pass: config.password,
|
||||
@@ -52,7 +61,7 @@ export class SmtpEmailProvider implements IEmailProvider {
|
||||
logger.debug({to: message.to}, 'Email sent via SMTP');
|
||||
return true;
|
||||
} catch (error) {
|
||||
logger.error({error}, 'SMTP send failed');
|
||||
logger.error({error, host: this.host, port: this.port, tlsMode: this.tlsMode}, 'SMTP send failed');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user