/** * SMTP Server Interfaces * Defines all the interfaces used by the SMTP server implementation */ import * as plugins from '../../../plugins.js'; import type { Email } from '../../core/classes.email.js'; import type { UnifiedEmailServer } from '../../routing/classes.unified.email.server.js'; // Re-export types from other modules import { SmtpState } from '../interfaces.js'; import { SmtpCommand } from './constants.js'; export { SmtpState, SmtpCommand }; export type { IEnvelopeRecipient } from '../interfaces.js'; /** * Interface for components that need cleanup */ export interface IDestroyable { /** * Clean up all resources (timers, listeners, etc) */ destroy(): void | Promise; } /** * SMTP authentication credentials */ export interface ISmtpAuth { /** * Username for authentication */ username: string; /** * Password for authentication */ password: string; } /** * SMTP envelope (sender and recipients) */ export interface ISmtpEnvelope { /** * Mail from address */ mailFrom: { address: string; args?: Record; }; /** * Recipients list */ rcptTo: Array<{ address: string; args?: Record; }>; } /** * SMTP session representing a client connection */ export interface ISmtpSession { /** * Unique session identifier */ id: string; /** * Current state of the SMTP session */ state: SmtpState; /** * Client's hostname from EHLO/HELO */ clientHostname: string | null; /** * Whether TLS is active for this session */ secure: boolean; /** * Authentication status */ authenticated: boolean; /** * Authentication username if authenticated */ username?: string; /** * Transaction envelope */ envelope: ISmtpEnvelope; /** * When the session was created */ createdAt: Date; /** * Last activity timestamp */ lastActivity: number; /** * Client's IP address */ remoteAddress: string; /** * Client's port */ remotePort: number; /** * Additional session data */ data?: Record; /** * Message size if SIZE extension is used */ messageSize?: number; /** * Server capabilities advertised to client */ capabilities?: string[]; /** * Buffer for incomplete data */ dataBuffer?: string; /** * Flag to track if we're currently receiving DATA */ receivingData?: boolean; /** * The raw email data being received */ rawData?: string; /** * Greeting sent to client */ greeting?: string; /** * Whether EHLO has been sent */ ehloSent?: boolean; /** * Whether HELO has been sent */ heloSent?: boolean; /** * TLS options for this session */ tlsOptions?: any; /** * Whether TLS is being used */ useTLS?: boolean; /** * Mail from address for this transaction */ mailFrom?: string; /** * Recipients for this transaction */ rcptTo?: string[]; /** * Email data being received */ emailData?: string; /** * Chunks of email data */ emailDataChunks?: string[]; /** * Timeout ID for data reception */ dataTimeoutId?: NodeJS.Timeout; /** * Whether connection has ended */ connectionEnded?: boolean; /** * Size of email data being received */ emailDataSize?: number; /** * Processing mode for this session */ processingMode?: string; } /** * Session manager interface */ export interface ISessionManager extends IDestroyable { /** * Create a new session for a socket */ createSession(socket: plugins.net.Socket | plugins.tls.TLSSocket, secure?: boolean): ISmtpSession; /** * Get session by socket */ getSession(socket: plugins.net.Socket | plugins.tls.TLSSocket): ISmtpSession | undefined; /** * Update session state */ updateSessionState(session: ISmtpSession, newState: SmtpState): void; /** * Remove a session */ removeSession(socket: plugins.net.Socket | plugins.tls.TLSSocket): void; /** * Clear all sessions */ clearAllSessions(): void; /** * Get all active sessions */ getAllSessions(): ISmtpSession[]; /** * Get session count */ getSessionCount(): number; /** * Update last activity for a session */ updateLastActivity(socket: plugins.net.Socket | plugins.tls.TLSSocket): void; /** * Check for timed out sessions */ checkTimeouts(timeoutMs: number): ISmtpSession[]; /** * Update session activity timestamp */ updateSessionActivity(session: ISmtpSession): void; /** * Replace socket in session (for TLS upgrade) */ replaceSocket(oldSocket: plugins.net.Socket | plugins.tls.TLSSocket, newSocket: plugins.net.Socket | plugins.tls.TLSSocket): boolean; } /** * Connection manager interface */ export interface IConnectionManager extends IDestroyable { /** * Handle a new connection */ handleConnection(socket: plugins.net.Socket | plugins.tls.TLSSocket, secure: boolean): Promise; /** * Close all active connections */ closeAllConnections(): void; /** * Get active connection count */ getConnectionCount(): number; /** * Check if accepting new connections */ canAcceptConnection(): boolean; /** * Handle new connection (legacy method name) */ handleNewConnection(socket: plugins.net.Socket): Promise; /** * Handle new secure connection (legacy method name) */ handleNewSecureConnection(socket: plugins.tls.TLSSocket): Promise; /** * Setup socket event handlers */ setupSocketEventHandlers(socket: plugins.net.Socket | plugins.tls.TLSSocket): void; } /** * Command handler interface */ export interface ICommandHandler extends IDestroyable { /** * Handle an SMTP command */ handleCommand( socket: plugins.net.Socket | plugins.tls.TLSSocket, command: SmtpCommand, args: string, session: ISmtpSession ): Promise; /** * Get supported commands for current session state */ getSupportedCommands(session: ISmtpSession): SmtpCommand[]; /** * Process command (legacy method name) */ processCommand(socket: plugins.net.Socket | plugins.tls.TLSSocket, command: string): Promise; } /** * Data handler interface */ export interface IDataHandler extends IDestroyable { /** * Handle email data */ handleData( socket: plugins.net.Socket | plugins.tls.TLSSocket, data: string, session: ISmtpSession ): Promise; /** * Process a complete email */ processEmail( rawData: string, session: ISmtpSession ): Promise; /** * Handle data received (legacy method name) */ handleDataReceived(socket: plugins.net.Socket | plugins.tls.TLSSocket, data: string): Promise; /** * Process email data (legacy method name) */ processEmailData(socket: plugins.net.Socket | plugins.tls.TLSSocket, data: string): Promise; } /** * TLS handler interface */ export interface ITlsHandler extends IDestroyable { /** * Handle STARTTLS command */ handleStartTls( socket: plugins.net.Socket, session: ISmtpSession ): Promise; /** * Check if TLS is available */ isTlsAvailable(): boolean; /** * Get TLS options */ getTlsOptions(): plugins.tls.TlsOptions; /** * Check if TLS is enabled */ isTlsEnabled(): boolean; } /** * Security handler interface */ export interface ISecurityHandler extends IDestroyable { /** * Check IP reputation */ checkIpReputation(socket: plugins.net.Socket | plugins.tls.TLSSocket): Promise; /** * Validate email address */ isValidEmail(email: string): boolean; /** * Authenticate user */ authenticate(auth: ISmtpAuth): Promise; } /** * SMTP server options */ export interface ISmtpServerOptions { /** * Port to listen on */ port: number; /** * Hostname of the server */ hostname: string; /** * Host to bind to (optional, defaults to 0.0.0.0) */ host?: string; /** * Secure port for TLS connections */ securePort?: number; /** * TLS/SSL private key (PEM format) */ key?: string; /** * TLS/SSL certificate (PEM format) */ cert?: string; /** * CA certificates for TLS (PEM format) */ ca?: string; /** * Maximum size of messages in bytes */ maxSize?: number; /** * Maximum number of concurrent connections */ maxConnections?: number; /** * Authentication options */ auth?: { /** * Whether authentication is required */ required: boolean; /** * Allowed authentication methods */ methods: ('PLAIN' | 'LOGIN' | 'OAUTH2')[]; }; /** * Socket timeout in milliseconds (default: 5 minutes / 300000ms) */ socketTimeout?: number; /** * Initial connection timeout in milliseconds (default: 30 seconds / 30000ms) */ connectionTimeout?: number; /** * Interval for checking idle sessions in milliseconds (default: 5 seconds / 5000ms) * For testing, can be set lower (e.g. 1000ms) to detect timeouts more quickly */ cleanupInterval?: number; /** * Maximum number of recipients allowed per message (default: 100) */ maxRecipients?: number; /** * Maximum message size in bytes (default: 10MB / 10485760 bytes) * This is advertised in the EHLO SIZE extension */ size?: number; /** * Timeout for the DATA command in milliseconds (default: 60000ms / 1 minute) * This controls how long to wait for the complete email data */ dataTimeout?: number; } /** * Result of SMTP transaction */ export interface ISmtpTransactionResult { /** * Whether the transaction was successful */ success: boolean; /** * Error message if failed */ error?: string; /** * Message ID if successful */ messageId?: string; /** * Resulting email if successful */ email?: Email; } /** * Interface for SMTP session events * These events are emitted by the session manager */ export interface ISessionEvents { created: (session: ISmtpSession, socket: plugins.net.Socket | plugins.tls.TLSSocket) => void; stateChanged: (session: ISmtpSession, previousState: SmtpState, newState: SmtpState) => void; timeout: (session: ISmtpSession, socket: plugins.net.Socket | plugins.tls.TLSSocket) => void; completed: (session: ISmtpSession, socket: plugins.net.Socket | plugins.tls.TLSSocket) => void; error: (session: ISmtpSession, error: Error) => void; } /** * SMTP Server interface */ export interface ISmtpServer extends IDestroyable { /** * Start the SMTP server */ listen(): Promise; /** * Stop the SMTP server */ close(): Promise; /** * Get the session manager */ getSessionManager(): ISessionManager; /** * Get the connection manager */ getConnectionManager(): IConnectionManager; /** * Get the command handler */ getCommandHandler(): ICommandHandler; /** * Get the data handler */ getDataHandler(): IDataHandler; /** * Get the TLS handler */ getTlsHandler(): ITlsHandler; /** * Get the security handler */ getSecurityHandler(): ISecurityHandler; /** * Get the server options */ getOptions(): ISmtpServerOptions; /** * Get the email server reference */ getEmailServer(): UnifiedEmailServer; } /** * Configuration for creating SMTP server */ export interface ISmtpServerConfig { /** * Email server instance */ emailServer: UnifiedEmailServer; /** * Server options */ options: ISmtpServerOptions; /** * Optional custom session manager */ sessionManager?: ISessionManager; /** * Optional custom connection manager */ connectionManager?: IConnectionManager; /** * Optional custom command handler */ commandHandler?: ICommandHandler; /** * Optional custom data handler */ dataHandler?: IDataHandler; /** * Optional custom TLS handler */ tlsHandler?: ITlsHandler; /** * Optional custom security handler */ securityHandler?: ISecurityHandler; }