162 lines
11 KiB
JavaScript
162 lines
11 KiB
JavaScript
|
|
/**
|
||
|
|
* SMTP Server Constants
|
||
|
|
* This file contains all constants and enums used by the SMTP server
|
||
|
|
*/
|
||
|
|
import { SmtpState } from '../interfaces.js';
|
||
|
|
// Re-export SmtpState enum from the main interfaces file
|
||
|
|
export { SmtpState };
|
||
|
|
/**
|
||
|
|
* SMTP Response Codes
|
||
|
|
* Based on RFC 5321 and common SMTP practice
|
||
|
|
*/
|
||
|
|
export var SmtpResponseCode;
|
||
|
|
(function (SmtpResponseCode) {
|
||
|
|
// Success codes (2xx)
|
||
|
|
SmtpResponseCode[SmtpResponseCode["SUCCESS"] = 250] = "SUCCESS";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["SYSTEM_STATUS"] = 211] = "SYSTEM_STATUS";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["HELP_MESSAGE"] = 214] = "HELP_MESSAGE";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["SERVICE_READY"] = 220] = "SERVICE_READY";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["SERVICE_CLOSING"] = 221] = "SERVICE_CLOSING";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["AUTHENTICATION_SUCCESSFUL"] = 235] = "AUTHENTICATION_SUCCESSFUL";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["OK"] = 250] = "OK";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["FORWARD"] = 251] = "FORWARD";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["CANNOT_VRFY"] = 252] = "CANNOT_VRFY";
|
||
|
|
// Intermediate codes (3xx)
|
||
|
|
SmtpResponseCode[SmtpResponseCode["MORE_INFO_NEEDED"] = 334] = "MORE_INFO_NEEDED";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["START_MAIL_INPUT"] = 354] = "START_MAIL_INPUT";
|
||
|
|
// Temporary error codes (4xx)
|
||
|
|
SmtpResponseCode[SmtpResponseCode["SERVICE_NOT_AVAILABLE"] = 421] = "SERVICE_NOT_AVAILABLE";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["MAILBOX_TEMPORARILY_UNAVAILABLE"] = 450] = "MAILBOX_TEMPORARILY_UNAVAILABLE";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["LOCAL_ERROR"] = 451] = "LOCAL_ERROR";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["INSUFFICIENT_STORAGE"] = 452] = "INSUFFICIENT_STORAGE";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["TLS_UNAVAILABLE_TEMP"] = 454] = "TLS_UNAVAILABLE_TEMP";
|
||
|
|
// Permanent error codes (5xx)
|
||
|
|
SmtpResponseCode[SmtpResponseCode["SYNTAX_ERROR"] = 500] = "SYNTAX_ERROR";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["SYNTAX_ERROR_PARAMETERS"] = 501] = "SYNTAX_ERROR_PARAMETERS";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["COMMAND_NOT_IMPLEMENTED"] = 502] = "COMMAND_NOT_IMPLEMENTED";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["BAD_SEQUENCE"] = 503] = "BAD_SEQUENCE";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["COMMAND_PARAMETER_NOT_IMPLEMENTED"] = 504] = "COMMAND_PARAMETER_NOT_IMPLEMENTED";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["AUTH_REQUIRED"] = 530] = "AUTH_REQUIRED";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["AUTH_FAILED"] = 535] = "AUTH_FAILED";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["MAILBOX_UNAVAILABLE"] = 550] = "MAILBOX_UNAVAILABLE";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["USER_NOT_LOCAL"] = 551] = "USER_NOT_LOCAL";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["EXCEEDED_STORAGE"] = 552] = "EXCEEDED_STORAGE";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["MAILBOX_NAME_INVALID"] = 553] = "MAILBOX_NAME_INVALID";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["TRANSACTION_FAILED"] = 554] = "TRANSACTION_FAILED";
|
||
|
|
SmtpResponseCode[SmtpResponseCode["MAIL_RCPT_PARAMETERS_INVALID"] = 555] = "MAIL_RCPT_PARAMETERS_INVALID";
|
||
|
|
})(SmtpResponseCode || (SmtpResponseCode = {}));
|
||
|
|
/**
|
||
|
|
* SMTP Command Types
|
||
|
|
*/
|
||
|
|
export var SmtpCommand;
|
||
|
|
(function (SmtpCommand) {
|
||
|
|
SmtpCommand["HELO"] = "HELO";
|
||
|
|
SmtpCommand["EHLO"] = "EHLO";
|
||
|
|
SmtpCommand["MAIL_FROM"] = "MAIL";
|
||
|
|
SmtpCommand["RCPT_TO"] = "RCPT";
|
||
|
|
SmtpCommand["DATA"] = "DATA";
|
||
|
|
SmtpCommand["RSET"] = "RSET";
|
||
|
|
SmtpCommand["NOOP"] = "NOOP";
|
||
|
|
SmtpCommand["QUIT"] = "QUIT";
|
||
|
|
SmtpCommand["STARTTLS"] = "STARTTLS";
|
||
|
|
SmtpCommand["AUTH"] = "AUTH";
|
||
|
|
SmtpCommand["HELP"] = "HELP";
|
||
|
|
SmtpCommand["VRFY"] = "VRFY";
|
||
|
|
SmtpCommand["EXPN"] = "EXPN";
|
||
|
|
})(SmtpCommand || (SmtpCommand = {}));
|
||
|
|
/**
|
||
|
|
* Security log event types
|
||
|
|
*/
|
||
|
|
export var SecurityEventType;
|
||
|
|
(function (SecurityEventType) {
|
||
|
|
SecurityEventType["CONNECTION"] = "connection";
|
||
|
|
SecurityEventType["AUTHENTICATION"] = "authentication";
|
||
|
|
SecurityEventType["COMMAND"] = "command";
|
||
|
|
SecurityEventType["DATA"] = "data";
|
||
|
|
SecurityEventType["IP_REPUTATION"] = "ip_reputation";
|
||
|
|
SecurityEventType["TLS_NEGOTIATION"] = "tls_negotiation";
|
||
|
|
SecurityEventType["DKIM"] = "dkim";
|
||
|
|
SecurityEventType["SPF"] = "spf";
|
||
|
|
SecurityEventType["DMARC"] = "dmarc";
|
||
|
|
SecurityEventType["EMAIL_VALIDATION"] = "email_validation";
|
||
|
|
SecurityEventType["SPAM"] = "spam";
|
||
|
|
SecurityEventType["ACCESS_CONTROL"] = "access_control";
|
||
|
|
})(SecurityEventType || (SecurityEventType = {}));
|
||
|
|
/**
|
||
|
|
* Security log levels
|
||
|
|
*/
|
||
|
|
export var SecurityLogLevel;
|
||
|
|
(function (SecurityLogLevel) {
|
||
|
|
SecurityLogLevel["DEBUG"] = "debug";
|
||
|
|
SecurityLogLevel["INFO"] = "info";
|
||
|
|
SecurityLogLevel["WARN"] = "warn";
|
||
|
|
SecurityLogLevel["ERROR"] = "error";
|
||
|
|
})(SecurityLogLevel || (SecurityLogLevel = {}));
|
||
|
|
/**
|
||
|
|
* SMTP Server Defaults
|
||
|
|
*/
|
||
|
|
export const SMTP_DEFAULTS = {
|
||
|
|
// Default timeouts in milliseconds
|
||
|
|
CONNECTION_TIMEOUT: 30000, // 30 seconds
|
||
|
|
SOCKET_TIMEOUT: 300000, // 5 minutes
|
||
|
|
DATA_TIMEOUT: 60000, // 1 minute
|
||
|
|
CLEANUP_INTERVAL: 5000, // 5 seconds
|
||
|
|
// Default limits
|
||
|
|
MAX_CONNECTIONS: 100,
|
||
|
|
MAX_RECIPIENTS: 100,
|
||
|
|
MAX_MESSAGE_SIZE: 10485760, // 10MB
|
||
|
|
// Default ports
|
||
|
|
SMTP_PORT: 25,
|
||
|
|
SUBMISSION_PORT: 587,
|
||
|
|
SECURE_PORT: 465,
|
||
|
|
// Default hostname
|
||
|
|
HOSTNAME: 'mail.lossless.one',
|
||
|
|
// CRLF line ending required by SMTP protocol
|
||
|
|
CRLF: '\r\n',
|
||
|
|
};
|
||
|
|
/**
|
||
|
|
* SMTP Command Patterns
|
||
|
|
* Regular expressions for parsing SMTP commands
|
||
|
|
*/
|
||
|
|
export const SMTP_PATTERNS = {
|
||
|
|
// Match EHLO/HELO command: "EHLO example.com"
|
||
|
|
// Made very permissive to handle various client implementations
|
||
|
|
EHLO: /^(?:EHLO|HELO)\s+(.+)$/i,
|
||
|
|
// Match MAIL FROM command: "MAIL FROM:<user@example.com> [PARAM=VALUE]"
|
||
|
|
// Made more permissive with whitespace and parameter formats
|
||
|
|
MAIL_FROM: /^MAIL\s+FROM\s*:\s*<([^>]*)>((?:\s+[a-zA-Z0-9][a-zA-Z0-9\-]*(?:=[^\s]+)?)*)$/i,
|
||
|
|
// Match RCPT TO command: "RCPT TO:<user@example.com> [PARAM=VALUE]"
|
||
|
|
// Made more permissive with whitespace and parameter formats
|
||
|
|
RCPT_TO: /^RCPT\s+TO\s*:\s*<([^>]*)>((?:\s+[a-zA-Z0-9][a-zA-Z0-9\-]*(?:=[^\s]+)?)*)$/i,
|
||
|
|
// Match parameter format: "PARAM=VALUE"
|
||
|
|
PARAM: /\s+([A-Za-z0-9][A-Za-z0-9\-]*)(?:=([^\s]+))?/g,
|
||
|
|
// Match email address format - basic validation
|
||
|
|
// This pattern rejects common invalid formats while being permissive for edge cases
|
||
|
|
// Checks: no spaces, has @, has domain with dot, no double dots, proper domain format
|
||
|
|
EMAIL: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
|
||
|
|
// Match end of DATA marker: \r\n.\r\n or just .\r\n at the start of a line (to handle various client implementations)
|
||
|
|
END_DATA: /(\r\n\.\r\n$)|(\n\.\r\n$)|(\r\n\.\n$)|(\n\.\n$)|^\.(\r\n|\n)$/,
|
||
|
|
};
|
||
|
|
/**
|
||
|
|
* SMTP Extension List
|
||
|
|
* These extensions are advertised in the EHLO response
|
||
|
|
*/
|
||
|
|
export const SMTP_EXTENSIONS = {
|
||
|
|
// Basic extensions (RFC 1869)
|
||
|
|
PIPELINING: 'PIPELINING',
|
||
|
|
SIZE: 'SIZE',
|
||
|
|
EIGHTBITMIME: '8BITMIME',
|
||
|
|
// Security extensions
|
||
|
|
STARTTLS: 'STARTTLS',
|
||
|
|
AUTH: 'AUTH',
|
||
|
|
// Additional extensions
|
||
|
|
ENHANCEDSTATUSCODES: 'ENHANCEDSTATUSCODES',
|
||
|
|
HELP: 'HELP',
|
||
|
|
CHUNKING: 'CHUNKING',
|
||
|
|
DSN: 'DSN',
|
||
|
|
// Format an extension with a parameter
|
||
|
|
formatExtension(name, parameter) {
|
||
|
|
return parameter !== undefined ? `${name} ${parameter}` : name;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdHMvbWFpbC9kZWxpdmVyeS9zbXRwc2VydmVyL2NvbnN0YW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFN0MseURBQXlEO0FBQ3pELE9BQU8sRUFBRSxTQUFTLEVBQUUsQ0FBQztBQUVyQjs7O0dBR0c7QUFDSCxNQUFNLENBQU4sSUFBWSxnQkFxQ1g7QUFyQ0QsV0FBWSxnQkFBZ0I7SUFDMUIsc0JBQXNCO0lBQ3RCLCtEQUFhLENBQUE7SUFDYiwyRUFBbUIsQ0FBQTtJQUNuQix5RUFBa0IsQ0FBQTtJQUNsQiwyRUFBbUIsQ0FBQTtJQUNuQiwrRUFBcUIsQ0FBQTtJQUNyQixtR0FBK0IsQ0FBQTtJQUMvQixxREFBUSxDQUFBO0lBQ1IsK0RBQWEsQ0FBQTtJQUNiLHVFQUFpQixDQUFBO0lBRWpCLDJCQUEyQjtJQUMzQixpRkFBc0IsQ0FBQTtJQUN0QixpRkFBc0IsQ0FBQTtJQUV0Qiw4QkFBOEI7SUFDOUIsMkZBQTJCLENBQUE7SUFDM0IsK0dBQXFDLENBQUE7SUFDckMsdUVBQWlCLENBQUE7SUFDakIseUZBQTBCLENBQUE7SUFDMUIseUZBQTBCLENBQUE7SUFFMUIsOEJBQThCO0lBQzlCLHlFQUFrQixDQUFBO0lBQ2xCLCtGQUE2QixDQUFBO0lBQzdCLCtGQUE2QixDQUFBO0lBQzdCLHlFQUFrQixDQUFBO0lBQ2xCLG1IQUF1QyxDQUFBO0lBQ3ZDLDJFQUFtQixDQUFBO0lBQ25CLHVFQUFpQixDQUFBO0lBQ2pCLHVGQUF5QixDQUFBO0lBQ3pCLDZFQUFvQixDQUFBO0lBQ3BCLGlGQUFzQixDQUFBO0lBQ3RCLHlGQUEwQixDQUFBO0lBQzFCLHFGQUF3QixDQUFBO0lBQ3hCLHlHQUFrQyxDQUFBO0FBQ3BDLENBQUMsRUFyQ1csZ0JBQWdCLEtBQWhCLGdCQUFnQixRQXFDM0I7QUFFRDs7R0FFRztBQUNILE1BQU0sQ0FBTixJQUFZLFdBY1g7QUFkRCxXQUFZLFdBQVc7SUFDckIsNEJBQWEsQ0FBQTtJQUNiLDRCQUFhLENBQUE7SUFDYixpQ0FBa0IsQ0FBQTtJQUNsQiwrQkFBZ0IsQ0FBQTtJQUNoQiw0QkFBYSxDQUFBO0lBQ2IsNEJBQWEsQ0FBQTtJQUNiLDRCQUFhLENBQUE7SUFDYiw0QkFBYSxDQUFBO0lBQ2Isb0NBQXFCLENBQUE7SUFDckIsNEJBQWEsQ0FBQTtJQUNiLDRCQUFhLENBQUE7SUFDYiw0QkFBYSxDQUFBO0lBQ2IsNEJBQWEsQ0FBQTtBQUNmLENBQUMsRUFkVyxXQUFXLEtBQVgsV0FBVyxRQWN0QjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxDQUFOLElBQVksaUJBYVg7QUFiRCxXQUFZLGlCQUFpQjtJQUMzQiw4Q0FBeUIsQ0FBQTtJQUN6QixzREFBaUMsQ0FBQTtJQUNqQyx3Q0FBbUIsQ0FBQTtJQUNuQixrQ0FBYSxDQUFBO0lBQ2Isb0RBQStCLENBQUE7SUFDL0Isd0RBQW1DLENBQUE7SUFDbkMsa0NBQWEsQ0FBQTtJQUNiLGdDQUFXLENBQUE7SUFDWCxvQ0FBZSxDQUFBO0lBQ2YsMERBQXFDLENBQUE7SUFDckMsa0NBQWEsQ0FBQTtJQUNiLHNEQUFpQyxDQUFBO0FBQ25DLENBQUMsRUFiVyxpQkFBaUIsS0FBakIsaUJBQWlCLFFBYTVCO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLENBQU4sSUFBWSxnQkFLWDtBQUxELFdBQVksZ0JBQWdCO0lBQzFCLG1DQUFlLENBQUE7SUFDZixpQ0FBYSxDQUFBO0lBQ2IsaUNBQWEsQ0FBQTtJQUNiLG1DQUFlLENBQUE7QUFDakIsQ0FBQyxFQUxXLGdCQUFnQixLQUFoQixnQkFBZ0IsUUFLM0I7QUFFRDs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRztJQUMzQixtQ0FBbUM7SUFDbkMsa0JBQWtCLEVBQUUsS0FBSyxFQUFRLGFBQWE7SUFDOUMsY0FBYyxFQUFFLE1BQU0sRUFBVyxZQUFZO0lBQzdDLFlBQVksRUFBRSxLQUFLLEVBQWMsV0FBVztJQUM1QyxnQkFBZ0IsRUFBRSxJQUFJLEVBQVcsWUFBWTtJQUU3QyxpQkFBaUI7SUFDakIsZUFBZSxFQUFFLEdBQUc7SUFDcEIsY0FBYyxFQUFFLEdBQUc7SUFDbkIsZ0JBQWdCLEVBQUUsUUFBUSxFQUFPLE9BQU87SUFFeEMsZ0JBQWdCO0lBQ2hCLFNBQVMsRUFBRSxFQUFFO0lBQ2IsZUFBZSxFQUFFLEdBQUc7SUFDcEIsV0FBVyxFQUFFLEdBQUc7SUFFaEIsbUJBQW1CO0lBQ25CLFFBQVEsRUFBRSxtQkFBbUI7SUFFN0IsNkNBQTZDO0lBQzdDLElBQUksRUFBRSxNQUFNO0NBQ2IsQ0FBQztBQUVGOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRztJQUMzQiw4Q0FBOEM7SUFDOUMsZ0VBQWdFO0lBQ2hFLElBQUksRUFBRSx5QkFBeUI7SUFFL0Isd0VBQXdFO0lBQ3hFLDZEQUE2RDtJQUM3RCxTQUFTLEVBQUUsK0VBQStFO0lBRTFGLG9FQUFvRTtJQUNwRSw2REFBNkQ7SUFDN0QsT0FBTyxFQUFFLDZFQUE2RTtJQUV0Rix3Q0FBd0M7SUFDeEMsS0FBSyxFQUFFLCtDQUErQztJQUV0RCxnREFBZ0Q7SUFDaEQsb0ZBQW9GO0lBQ3BGLHNGQUFzRjtJQUN0RixLQUFLLEVBQUUsNEJBQTRCO0lBRW5DLHNIQUFzSDtJQUN0SCxRQUFRLEVBQUUsK0RBQStEO0NBQzFFLENBQUM7QUFFRjs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUc7SUFDN0IsOEJBQThCO0lBQzlCLFVBQVUsRUFBRSxZQUFZO0lBQ3hCLElBQUksRUFBRSxNQUFNO0lBQ1osWUFBWSxFQUFFLFVBQVU7SUFFeEIsc0JBQXNCO0lBQ3RCLFFBQVEsRUFBRSxVQUFVO0lBQ3BCLElBQUksRUFBRSxNQUFNO0lBRVosd0JBQXdCO0lBQ3hCLG1CQUFtQixFQUFFLHFCQUFxQjtJQUMxQyxJQUFJLEVBQUUsTUFBTTtJQUNaLFFBQVEsRUFBRSxVQUFVO0lBQ3BCLEdBQUcsRUFBRSxLQUFLO0lBRVYsdUNBQXVDO0lBQ3ZDLGVBQWUsQ0FBQyxJQUFZLEVBQUUsU0FBMkI7UUFDdkQsT0FBTyxTQUFTLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksSUFBSSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ2pFLENBQUM7Q0FDRixDQUFDIn0=
|