update
This commit is contained in:
@ -1,61 +1,61 @@
|
||||
/**
|
||||
* SMTP Server Module Interfaces
|
||||
* This file contains all interfaces for the refactored SMTP server implementation
|
||||
* 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';
|
||||
import { SmtpState } from '../interfaces.js';
|
||||
|
||||
// Define all needed types/interfaces directly in this file
|
||||
export { SmtpState };
|
||||
|
||||
// Define EmailProcessingMode directly in this file
|
||||
export type EmailProcessingMode = 'forward' | 'mta' | 'process';
|
||||
import type { SmtpState, SmtpCommand } from './constants.js';
|
||||
|
||||
/**
|
||||
* Envelope recipient information
|
||||
* Interface for components that need cleanup
|
||||
*/
|
||||
export interface IEnvelopeRecipient {
|
||||
export interface IDestroyable {
|
||||
/**
|
||||
* Email address of the recipient
|
||||
* Clean up all resources (timers, listeners, etc)
|
||||
*/
|
||||
address: string;
|
||||
|
||||
/**
|
||||
* Additional SMTP command arguments
|
||||
*/
|
||||
args: Record<string, string>;
|
||||
destroy(): void | Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* SMTP session envelope information
|
||||
* SMTP authentication credentials
|
||||
*/
|
||||
export interface ISmtpAuth {
|
||||
/**
|
||||
* Username for authentication
|
||||
*/
|
||||
username: string;
|
||||
|
||||
/**
|
||||
* Password for authentication
|
||||
*/
|
||||
password: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* SMTP envelope (sender and recipients)
|
||||
*/
|
||||
export interface ISmtpEnvelope {
|
||||
/**
|
||||
* Envelope sender (MAIL FROM) information
|
||||
* Mail from address
|
||||
*/
|
||||
mailFrom: {
|
||||
/**
|
||||
* Email address of the sender
|
||||
*/
|
||||
address: string;
|
||||
|
||||
/**
|
||||
* Additional SMTP command arguments
|
||||
*/
|
||||
args: Record<string, string>;
|
||||
args?: Record<string, string>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Envelope recipients (RCPT TO) information
|
||||
* Recipients list
|
||||
*/
|
||||
rcptTo: IEnvelopeRecipient[];
|
||||
rcptTo: Array<{
|
||||
address: string;
|
||||
args?: Record<string, string>;
|
||||
}>;
|
||||
}
|
||||
|
||||
/**
|
||||
* SMTP Session interface - represents an active SMTP connection
|
||||
* SMTP session representing a client connection
|
||||
*/
|
||||
export interface ISmtpSession {
|
||||
/**
|
||||
@ -64,104 +64,264 @@ export interface ISmtpSession {
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* Current session state in the SMTP conversation
|
||||
* Current state of the SMTP session
|
||||
*/
|
||||
state: SmtpState;
|
||||
|
||||
/**
|
||||
* Hostname provided by the client in EHLO/HELO command
|
||||
* Client's hostname from EHLO/HELO
|
||||
*/
|
||||
clientHostname: string;
|
||||
clientHostname: string | null;
|
||||
|
||||
/**
|
||||
* MAIL FROM email address (legacy format)
|
||||
*/
|
||||
mailFrom: string;
|
||||
|
||||
/**
|
||||
* RCPT TO email addresses (legacy format)
|
||||
*/
|
||||
rcptTo: string[];
|
||||
|
||||
/**
|
||||
* Raw email data being received
|
||||
*/
|
||||
emailData: string;
|
||||
|
||||
/**
|
||||
* Chunks of email data for more efficient buffer management
|
||||
*/
|
||||
emailDataChunks?: string[];
|
||||
|
||||
/**
|
||||
* Total size of email data chunks (tracked incrementally for performance)
|
||||
*/
|
||||
emailDataSize?: number;
|
||||
|
||||
/**
|
||||
* Whether the connection is using TLS
|
||||
*/
|
||||
useTLS: boolean;
|
||||
|
||||
/**
|
||||
* Whether the connection has ended
|
||||
*/
|
||||
connectionEnded: boolean;
|
||||
|
||||
/**
|
||||
* Remote IP address of the client
|
||||
*/
|
||||
remoteAddress: string;
|
||||
|
||||
/**
|
||||
* Whether the connection is secure (TLS)
|
||||
* Whether TLS is active for this session
|
||||
*/
|
||||
secure: boolean;
|
||||
|
||||
/**
|
||||
* Whether the client has been authenticated
|
||||
* Authentication status
|
||||
*/
|
||||
authenticated: boolean;
|
||||
|
||||
/**
|
||||
* SMTP envelope information (structured format)
|
||||
* Authentication username if authenticated
|
||||
*/
|
||||
username?: string;
|
||||
|
||||
/**
|
||||
* Transaction envelope
|
||||
*/
|
||||
envelope: ISmtpEnvelope;
|
||||
|
||||
/**
|
||||
* Email processing mode to use for this session
|
||||
* When the session was created
|
||||
*/
|
||||
processingMode?: EmailProcessingMode;
|
||||
createdAt: Date;
|
||||
|
||||
/**
|
||||
* Timestamp of last activity for session timeout tracking
|
||||
* Last activity timestamp
|
||||
*/
|
||||
lastActivity?: number;
|
||||
lastActivity: Date;
|
||||
|
||||
/**
|
||||
* Timeout ID for DATA command timeout
|
||||
* Client's IP address
|
||||
*/
|
||||
dataTimeoutId?: NodeJS.Timeout;
|
||||
remoteAddress: string;
|
||||
|
||||
/**
|
||||
* Client's port
|
||||
*/
|
||||
remotePort: number;
|
||||
|
||||
/**
|
||||
* Additional session data
|
||||
*/
|
||||
data?: Record<string, any>;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* SMTP authentication data
|
||||
* Session manager interface
|
||||
*/
|
||||
export interface ISmtpAuth {
|
||||
export interface ISessionManager extends IDestroyable {
|
||||
/**
|
||||
* Authentication method used
|
||||
* Create a new session for a socket
|
||||
*/
|
||||
method: 'PLAIN' | 'LOGIN' | 'OAUTH2' | string;
|
||||
createSession(socket: plugins.net.Socket | plugins.tls.TLSSocket): ISmtpSession;
|
||||
|
||||
/**
|
||||
* Username for authentication
|
||||
* Get session by socket
|
||||
*/
|
||||
username: string;
|
||||
getSession(socket: plugins.net.Socket | plugins.tls.TLSSocket): ISmtpSession | undefined;
|
||||
|
||||
/**
|
||||
* Password or token for authentication
|
||||
* Update session state
|
||||
*/
|
||||
password: string;
|
||||
updateSessionState(socket: plugins.net.Socket | plugins.tls.TLSSocket, 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[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection manager interface
|
||||
*/
|
||||
export interface IConnectionManager extends IDestroyable {
|
||||
/**
|
||||
* Handle a new connection
|
||||
*/
|
||||
handleConnection(socket: plugins.net.Socket | plugins.tls.TLSSocket, secure: boolean): Promise<void>;
|
||||
|
||||
/**
|
||||
* Close all active connections
|
||||
*/
|
||||
closeAllConnections(): void;
|
||||
|
||||
/**
|
||||
* Get active connection count
|
||||
*/
|
||||
getConnectionCount(): number;
|
||||
|
||||
/**
|
||||
* Check if accepting new connections
|
||||
*/
|
||||
canAcceptConnection(): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<void>;
|
||||
|
||||
/**
|
||||
* Get supported commands for current session state
|
||||
*/
|
||||
getSupportedCommands(session: ISmtpSession): SmtpCommand[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Data handler interface
|
||||
*/
|
||||
export interface IDataHandler extends IDestroyable {
|
||||
/**
|
||||
* Handle email data
|
||||
*/
|
||||
handleData(
|
||||
socket: plugins.net.Socket | plugins.tls.TLSSocket,
|
||||
data: string,
|
||||
session: ISmtpSession
|
||||
): Promise<void>;
|
||||
|
||||
/**
|
||||
* Process a complete email
|
||||
*/
|
||||
processEmail(
|
||||
rawData: string,
|
||||
session: ISmtpSession
|
||||
): Promise<Email>;
|
||||
}
|
||||
|
||||
/**
|
||||
* TLS handler interface
|
||||
*/
|
||||
export interface ITlsHandler extends IDestroyable {
|
||||
/**
|
||||
* Handle STARTTLS command
|
||||
*/
|
||||
handleStartTls(
|
||||
socket: plugins.net.Socket,
|
||||
session: ISmtpSession
|
||||
): Promise<plugins.tls.TLSSocket | null>;
|
||||
|
||||
/**
|
||||
* Check if TLS is available
|
||||
*/
|
||||
isTlsAvailable(): boolean;
|
||||
|
||||
/**
|
||||
* Get TLS options
|
||||
*/
|
||||
getTlsOptions(): plugins.tls.TlsOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Security handler interface
|
||||
*/
|
||||
export interface ISecurityHandler extends IDestroyable {
|
||||
/**
|
||||
* Check IP reputation
|
||||
*/
|
||||
checkIpReputation(socket: plugins.net.Socket | plugins.tls.TLSSocket): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Validate email address
|
||||
*/
|
||||
isValidEmail(email: string): boolean;
|
||||
|
||||
/**
|
||||
* Authenticate user
|
||||
*/
|
||||
authenticate(auth: ISmtpAuth): Promise<boolean>;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -174,29 +334,19 @@ export interface ISmtpServerOptions {
|
||||
port: number;
|
||||
|
||||
/**
|
||||
* TLS private key (PEM format)
|
||||
* Hostname of the server
|
||||
*/
|
||||
key: string;
|
||||
hostname: string;
|
||||
|
||||
/**
|
||||
* TLS certificate (PEM format)
|
||||
* TLS/SSL private key (PEM format)
|
||||
*/
|
||||
cert: string;
|
||||
key?: string;
|
||||
|
||||
/**
|
||||
* Server hostname for SMTP banner
|
||||
* TLS/SSL certificate (PEM format)
|
||||
*/
|
||||
hostname?: string;
|
||||
|
||||
/**
|
||||
* Host address to bind to (defaults to all interfaces)
|
||||
*/
|
||||
host?: string;
|
||||
|
||||
/**
|
||||
* Secure port for dedicated TLS connections
|
||||
*/
|
||||
securePort?: number;
|
||||
cert?: string;
|
||||
|
||||
/**
|
||||
* CA certificates for TLS (PEM format)
|
||||
@ -300,229 +450,9 @@ export interface ISessionEvents {
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for the session manager component
|
||||
* SMTP Server interface
|
||||
*/
|
||||
export interface ISessionManager {
|
||||
/**
|
||||
* Creates a new session for a socket connection
|
||||
*/
|
||||
createSession(socket: plugins.net.Socket | plugins.tls.TLSSocket, secure: boolean): ISmtpSession;
|
||||
|
||||
/**
|
||||
* Updates the session state
|
||||
*/
|
||||
updateSessionState(session: ISmtpSession, newState: SmtpState): void;
|
||||
|
||||
/**
|
||||
* Updates the session's last activity timestamp
|
||||
*/
|
||||
updateSessionActivity(session: ISmtpSession): void;
|
||||
|
||||
/**
|
||||
* Removes a session
|
||||
*/
|
||||
removeSession(socket: plugins.net.Socket | plugins.tls.TLSSocket): void;
|
||||
|
||||
/**
|
||||
* Gets a session for a socket
|
||||
*/
|
||||
getSession(socket: plugins.net.Socket | plugins.tls.TLSSocket): ISmtpSession | undefined;
|
||||
|
||||
/**
|
||||
* Cleans up idle sessions
|
||||
*/
|
||||
cleanupIdleSessions(): void;
|
||||
|
||||
/**
|
||||
* Gets the current number of active sessions
|
||||
*/
|
||||
getSessionCount(): number;
|
||||
|
||||
/**
|
||||
* Clears all sessions (used when shutting down)
|
||||
*/
|
||||
clearAllSessions(): void;
|
||||
|
||||
/**
|
||||
* Register an event listener
|
||||
*/
|
||||
on<K extends keyof ISessionEvents>(event: K, listener: ISessionEvents[K]): void;
|
||||
|
||||
/**
|
||||
* Remove an event listener
|
||||
*/
|
||||
off<K extends keyof ISessionEvents>(event: K, listener: ISessionEvents[K]): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for the connection manager component
|
||||
*/
|
||||
export interface IConnectionManager {
|
||||
/**
|
||||
* Handle a new connection
|
||||
*/
|
||||
handleNewConnection(socket: plugins.net.Socket): void;
|
||||
|
||||
/**
|
||||
* Handle a new secure TLS connection
|
||||
*/
|
||||
handleNewSecureConnection(socket: plugins.tls.TLSSocket): void;
|
||||
|
||||
/**
|
||||
* Set up event handlers for a socket
|
||||
*/
|
||||
setupSocketEventHandlers(socket: plugins.net.Socket | plugins.tls.TLSSocket): void;
|
||||
|
||||
/**
|
||||
* Get the current connection count
|
||||
*/
|
||||
getConnectionCount(): number;
|
||||
|
||||
/**
|
||||
* Check if the server has reached the maximum number of connections
|
||||
*/
|
||||
hasReachedMaxConnections(): boolean;
|
||||
|
||||
/**
|
||||
* Close all active connections
|
||||
*/
|
||||
closeAllConnections(): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for the command handler component
|
||||
*/
|
||||
export interface ICommandHandler {
|
||||
/**
|
||||
* Process a command from the client
|
||||
*/
|
||||
processCommand(socket: plugins.net.Socket | plugins.tls.TLSSocket, commandLine: string): void;
|
||||
|
||||
/**
|
||||
* Send a response to the client
|
||||
*/
|
||||
sendResponse(socket: plugins.net.Socket | plugins.tls.TLSSocket, response: string): void;
|
||||
|
||||
/**
|
||||
* Handle EHLO command
|
||||
*/
|
||||
handleEhlo(socket: plugins.net.Socket | plugins.tls.TLSSocket, clientHostname: string): void;
|
||||
|
||||
/**
|
||||
* Handle MAIL FROM command
|
||||
*/
|
||||
handleMailFrom(socket: plugins.net.Socket | plugins.tls.TLSSocket, args: string): void;
|
||||
|
||||
/**
|
||||
* Handle RCPT TO command
|
||||
*/
|
||||
handleRcptTo(socket: plugins.net.Socket | plugins.tls.TLSSocket, args: string): void;
|
||||
|
||||
/**
|
||||
* Handle DATA command
|
||||
*/
|
||||
handleData(socket: plugins.net.Socket | plugins.tls.TLSSocket): void;
|
||||
|
||||
/**
|
||||
* Handle RSET command
|
||||
*/
|
||||
handleRset(socket: plugins.net.Socket | plugins.tls.TLSSocket): void;
|
||||
|
||||
/**
|
||||
* Handle NOOP command
|
||||
*/
|
||||
handleNoop(socket: plugins.net.Socket | plugins.tls.TLSSocket): void;
|
||||
|
||||
/**
|
||||
* Handle QUIT command
|
||||
*/
|
||||
handleQuit(socket: plugins.net.Socket | plugins.tls.TLSSocket): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for the data handler component
|
||||
*/
|
||||
export interface IDataHandler {
|
||||
/**
|
||||
* Process incoming email data (legacy line-based)
|
||||
*/
|
||||
processEmailData(socket: plugins.net.Socket | plugins.tls.TLSSocket, data: string): Promise<void>;
|
||||
|
||||
/**
|
||||
* Handle raw data chunks during DATA mode (optimized for large messages)
|
||||
*/
|
||||
handleDataReceived(socket: plugins.net.Socket | plugins.tls.TLSSocket, data: string): Promise<void>;
|
||||
|
||||
/**
|
||||
* Process a complete email
|
||||
*/
|
||||
processEmail(session: ISmtpSession): Promise<ISmtpTransactionResult>;
|
||||
|
||||
/**
|
||||
* Save an email to disk
|
||||
*/
|
||||
saveEmail(session: ISmtpSession): void;
|
||||
|
||||
/**
|
||||
* Parse an email into an Email object
|
||||
*/
|
||||
parseEmail(session: ISmtpSession): Promise<Email>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for the TLS handler component
|
||||
*/
|
||||
export interface ITlsHandler {
|
||||
/**
|
||||
* Handle STARTTLS command
|
||||
*/
|
||||
handleStartTls(socket: plugins.net.Socket | plugins.tls.TLSSocket): void;
|
||||
|
||||
/**
|
||||
* Upgrade a connection to TLS
|
||||
*/
|
||||
startTLS(socket: plugins.net.Socket): void;
|
||||
|
||||
/**
|
||||
* Create a secure server
|
||||
*/
|
||||
createSecureServer(): plugins.tls.Server | undefined;
|
||||
|
||||
/**
|
||||
* Check if TLS is enabled
|
||||
*/
|
||||
isTlsEnabled(): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for the security handler component
|
||||
*/
|
||||
export interface ISecurityHandler {
|
||||
/**
|
||||
* Check IP reputation for a connection
|
||||
*/
|
||||
checkIpReputation(socket: plugins.net.Socket | plugins.tls.TLSSocket): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Validate an email address
|
||||
*/
|
||||
isValidEmail(email: string): boolean;
|
||||
|
||||
/**
|
||||
* Validate authentication credentials
|
||||
*/
|
||||
authenticate(session: ISmtpSession, username: string, password: string, method: string): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Log a security event
|
||||
*/
|
||||
logSecurityEvent(event: string, level: string, message: string, details: Record<string, any>): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for the SMTP server component
|
||||
*/
|
||||
export interface ISmtpServer {
|
||||
export interface ISmtpServer extends IDestroyable {
|
||||
/**
|
||||
* Start the SMTP server
|
||||
*/
|
||||
@ -575,46 +505,46 @@ export interface ISmtpServer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration for creating an SMTP server
|
||||
* Configuration for creating SMTP server
|
||||
*/
|
||||
export interface ISmtpServerConfig {
|
||||
/**
|
||||
* Email server reference
|
||||
* Email server instance
|
||||
*/
|
||||
emailServer: UnifiedEmailServer;
|
||||
|
||||
/**
|
||||
* SMTP server options
|
||||
* Server options
|
||||
*/
|
||||
options: ISmtpServerOptions;
|
||||
|
||||
/**
|
||||
* Optional session manager
|
||||
* Optional custom session manager
|
||||
*/
|
||||
sessionManager?: ISessionManager;
|
||||
|
||||
/**
|
||||
* Optional connection manager
|
||||
* Optional custom connection manager
|
||||
*/
|
||||
connectionManager?: IConnectionManager;
|
||||
|
||||
/**
|
||||
* Optional command handler
|
||||
* Optional custom command handler
|
||||
*/
|
||||
commandHandler?: ICommandHandler;
|
||||
|
||||
/**
|
||||
* Optional data handler
|
||||
* Optional custom data handler
|
||||
*/
|
||||
dataHandler?: IDataHandler;
|
||||
|
||||
/**
|
||||
* Optional TLS handler
|
||||
* Optional custom TLS handler
|
||||
*/
|
||||
tlsHandler?: ITlsHandler;
|
||||
|
||||
/**
|
||||
* Optional security handler
|
||||
* Optional custom security handler
|
||||
*/
|
||||
securityHandler?: ISecurityHandler;
|
||||
}
|
Reference in New Issue
Block a user