This commit is contained in:
2025-05-21 10:38:22 +00:00
parent ecb913843c
commit b0a0078ad0
6 changed files with 227 additions and 261 deletions

View File

@ -21,7 +21,8 @@ import { SmtpState } from './interfaces.js';
export class SMTPServer {
public emailServerRef: UnifiedEmailServer;
private smtpServerOptions: ISmtpServerOptions;
private server: plugins.net.Server;
// Making server protected so tests can access it
protected server: plugins.net.Server;
private sessions: Map<plugins.net.Socket | plugins.tls.TLSSocket, ISmtpSession>;
private sessionTimeouts: Map<string, NodeJS.Timeout>;
private hostname: string;
@ -55,6 +56,51 @@ export class SMTPServer {
});
}
/**
* Start the SMTP server and listen on the specified port
* @returns A promise that resolves when the server is listening
*/
public listen(): Promise<void> {
return new Promise<void>((resolve, reject) => {
if (!this.smtpServerOptions.port) {
return reject(new Error('SMTP server port not specified'));
}
const port = this.smtpServerOptions.port;
this.server.listen(port, () => {
logger.log('info', `SMTP server listening on port ${port}`);
console.log(`SMTP server started on port ${port}`);
resolve();
});
this.server.on('error', (err) => {
logger.log('error', `SMTP server error: ${err.message}`);
console.error(`Failed to start SMTP server: ${err.message}`);
reject(err);
});
});
}
/**
* Stop the SMTP server
* @returns A promise that resolves when the server has stopped
*/
public close(): Promise<void> {
return new Promise<void>((resolve, reject) => {
this.server.close((err) => {
if (err) {
logger.log('error', `Error closing SMTP server: ${err.message}`);
reject(err);
return;
}
logger.log('info', 'SMTP server stopped');
resolve();
});
});
}
/**
* Clean up idle sessions
* @private

View File

@ -205,6 +205,16 @@ export interface ISmtpServerOptions {
*/
methods: ('PLAIN' | 'LOGIN' | 'OAUTH2')[];
};
/**
* Socket timeout in milliseconds (default: 5 minutes)
*/
socketTimeout?: number;
/**
* Initial connection timeout in milliseconds (default: 30 seconds)
*/
connectionTimeout?: number;
}
/**