Fix: IMAP/SMTP mit älteren TLS-Versionen zulassen

Der Fehler 'Client network socket disconnected before secure TLS connection
was established' tritt auf, wenn der Mailserver nur alte TLS-Versionen (1.0/1.1)
oder legacy Cipher-Suites anbietet - Node.js 20+ schließt dann den Socket, noch
bevor überhaupt ein Zertifikat gesehen wird. Das Häkchen 'Selbstsignierte
Zertifikate erlauben' greift zu spät, weil der Handshake gar nicht startet.

Fix: Wenn 'Selbstsignierte Zertifikate erlauben' aktiv ist, setzen wir gleich
auch minVersion='TLSv1' und ciphers='DEFAULT:@SECLEVEL=0'. Damit akzeptiert
Node.js auch alte Cipher-Suites und TLS-Versionen des Mailservers.

Bei aktivem 'allowSelfSignedCerts' heißt das zusammen:
- rejectUnauthorized: false (Zertifikate akzeptieren auch wenn selbstsigniert)
- minVersion: 'TLSv1' (auch alte TLS-Versionen zulassen)
- ciphers: 'DEFAULT:@SECLEVEL=0' (auch schwache Ciphers zulassen)

Refactor:
- imapService: neuer Helper buildTlsOptions() – ersetzt 8 identische
  Inline-Setups, damit die Fix-Logik zentral gepflegt wird
- smtpService: tls-Type erweitert (minVersion/ciphers), gleiche Logik

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-23 15:05:04 +02:00
parent fd55f3129f
commit 1de8fb9847
2 changed files with 38 additions and 12 deletions
+7 -2
View File
@@ -69,7 +69,7 @@ export async function sendEmail(
port: number;
secure: boolean;
auth: { user: string; pass: string };
tls?: { rejectUnauthorized: boolean };
tls?: { rejectUnauthorized: boolean; minVersion?: string; ciphers?: string };
ignoreTLS?: boolean;
requireTLS?: boolean;
connectionTimeout: number;
@@ -91,6 +91,11 @@ export async function sendEmail(
// TLS-Optionen nur wenn nicht NONE
if (encryption !== 'NONE') {
transportOptions.tls = { rejectUnauthorized };
if (credentials.allowSelfSignedCerts) {
// Auch ältere TLS-Versionen + legacy Cipher-Suites für alte Server zulassen
transportOptions.tls.minVersion = 'TLSv1';
transportOptions.tls.ciphers = 'DEFAULT:@SECLEVEL=0';
}
} else {
// Keine Verschlüsselung: STARTTLS ignorieren
transportOptions.ignoreTLS = true;
@@ -273,7 +278,7 @@ export async function testSmtpConnection(credentials: SmtpCredentials): Promise<
port: number;
secure: boolean;
auth: { user: string; pass: string };
tls?: { rejectUnauthorized: boolean };
tls?: { rejectUnauthorized: boolean; minVersion?: string; ciphers?: string };
ignoreTLS?: boolean;
connectionTimeout: number;
greetingTimeout: number;