feat: Implement Deno-native STARTTLS handler and connection wrapper

- Refactored STARTTLS implementation to use Deno's native TLS via Deno.startTls().
- Introduced ConnectionWrapper to provide a Node.js net.Socket-compatible interface for Deno.Conn and Deno.TlsConn.
- Updated TlsHandler to utilize the new STARTTLS implementation.
- Added comprehensive SMTP authentication tests for PLAIN and LOGIN mechanisms.
- Implemented rate limiting tests for SMTP server connections and commands.
- Enhanced error handling and logging throughout the STARTTLS and connection upgrade processes.
This commit is contained in:
2025-10-28 18:51:33 +00:00
parent 9cd15342e0
commit 6523c55516
14 changed files with 1328 additions and 429 deletions

View File

@@ -359,3 +359,36 @@ export async function retryOperation<T>(
throw lastError!;
}
/**
* Upgrade SMTP connection to TLS using STARTTLS command
* @param conn - Active SMTP connection
* @param hostname - Server hostname for TLS verification
* @returns Upgraded TLS connection
*/
export async function upgradeToTls(conn: Deno.Conn, hostname: string = 'localhost'): Promise<Deno.TlsConn> {
const encoder = new TextEncoder();
// Send STARTTLS command
await conn.write(encoder.encode('STARTTLS\r\n'));
// Read response
const response = await readSmtpResponse(conn);
// Check for 220 Ready to start TLS
if (!response.startsWith('220')) {
throw new Error(`STARTTLS failed: ${response}`);
}
// Read test certificate for self-signed cert validation
const certPath = new URL('../../test/fixtures/test-cert.pem', import.meta.url).pathname;
const certPem = await Deno.readTextFile(certPath);
// Upgrade connection to TLS with certificate options
const tlsConn = await Deno.startTls(conn, {
hostname,
caCerts: [certPem], // Accept self-signed test certificate
});
return tlsConn;
}