update
This commit is contained in:
@ -6,11 +6,7 @@ import * as paths from './paths.js';
|
||||
// Import the consolidated email config
|
||||
import type { IEmailConfig, IDomainRule } from './mail/routing/classes.email.config.js';
|
||||
import type { EmailProcessingMode } from './mail/delivery/interfaces.js';
|
||||
import { DomainRouter } from './mail/routing/classes.domain.router.js';
|
||||
import { UnifiedEmailServer } from './mail/routing/classes.unified.email.server.js';
|
||||
import { UnifiedDeliveryQueue, type IQueueOptions } from './mail/delivery/classes.delivery.queue.js';
|
||||
import { MultiModeDeliverySystem, type IMultiModeDeliveryOptions } from './mail/delivery/classes.delivery.system.js';
|
||||
import { UnifiedRateLimiter, type IHierarchicalRateLimits } from './mail/delivery/classes.unified.rate.limiter.js';
|
||||
import { logger } from './logger.js';
|
||||
// Import the email configuration helpers directly from mail/delivery
|
||||
import { configureEmailStorage, configureEmailServer } from './mail/delivery/index.js';
|
||||
@ -87,13 +83,7 @@ export class DcRouter {
|
||||
// Core services
|
||||
public smartProxy?: plugins.smartproxy.SmartProxy;
|
||||
public dnsServer?: plugins.smartdns.DnsServer;
|
||||
|
||||
// Unified email components
|
||||
public domainRouter?: DomainRouter;
|
||||
public unifiedEmailServer?: UnifiedEmailServer;
|
||||
public deliveryQueue?: UnifiedDeliveryQueue;
|
||||
public deliverySystem?: MultiModeDeliverySystem;
|
||||
public rateLimiter?: UnifiedRateLimiter;
|
||||
public emailServer?: UnifiedEmailServer;
|
||||
|
||||
|
||||
// Environment access
|
||||
@ -119,9 +109,9 @@ export class DcRouter {
|
||||
await this.setupUnifiedEmailHandling();
|
||||
|
||||
// Apply custom email storage configuration if available
|
||||
if (this.unifiedEmailServer && this.options.emailPortConfig?.receivedEmailsPath) {
|
||||
if (this.emailServer && this.options.emailPortConfig?.receivedEmailsPath) {
|
||||
logger.log('info', 'Applying custom email storage configuration');
|
||||
configureEmailStorage(this.unifiedEmailServer, this.options);
|
||||
configureEmailStorage(this.emailServer, this.options);
|
||||
}
|
||||
}
|
||||
|
||||
@ -402,8 +392,8 @@ export class DcRouter {
|
||||
try {
|
||||
// Stop all services in parallel for faster shutdown
|
||||
await Promise.all([
|
||||
// Stop unified email components if running
|
||||
this.domainRouter ? this.stopUnifiedEmailComponents().catch(err => console.error('Error stopping unified email components:', err)) : Promise.resolve(),
|
||||
// Stop unified email server if running
|
||||
this.emailServer ? this.emailServer.stop().catch(err => console.error('Error stopping email server:', err)) : Promise.resolve(),
|
||||
|
||||
// Stop HTTP SmartProxy if running
|
||||
this.smartProxy ? this.smartProxy.stop().catch(err => console.error('Error stopping SmartProxy:', err)) : Promise.resolve(),
|
||||
@ -485,78 +475,35 @@ export class DcRouter {
|
||||
}
|
||||
|
||||
try {
|
||||
// Create domain router for pattern matching
|
||||
this.domainRouter = new DomainRouter({
|
||||
// Create unified email server with all components
|
||||
this.emailServer = new UnifiedEmailServer(this, {
|
||||
ports: emailConfig.ports.map(port => portMapping[port] || port + 10000),
|
||||
hostname: 'localhost', // Listen on localhost for SmartProxy forwarding
|
||||
domains: emailConfig.domains || [],
|
||||
domainRules: emailConfig.domainRules,
|
||||
defaultMode: emailConfig.defaultMode,
|
||||
defaultServer: emailConfig.defaultServer,
|
||||
defaultPort: emailConfig.defaultPort,
|
||||
defaultTls: emailConfig.defaultTls
|
||||
});
|
||||
|
||||
// Initialize the rate limiter
|
||||
this.rateLimiter = new UnifiedRateLimiter({
|
||||
global: {
|
||||
maxMessagesPerMinute: 100,
|
||||
maxRecipientsPerMessage: 100,
|
||||
maxConnectionsPerIP: 20,
|
||||
maxErrorsPerIP: 10,
|
||||
maxAuthFailuresPerIP: 5
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize the unified delivery queue
|
||||
const queueOptions: IQueueOptions = {
|
||||
storageType: emailConfig.queue?.storageType || 'memory',
|
||||
persistentPath: emailConfig.queue?.persistentPath,
|
||||
maxRetries: emailConfig.queue?.maxRetries,
|
||||
baseRetryDelay: emailConfig.queue?.baseRetryDelay,
|
||||
maxRetryDelay: emailConfig.queue?.maxRetryDelay
|
||||
};
|
||||
|
||||
this.deliveryQueue = new UnifiedDeliveryQueue(queueOptions);
|
||||
await this.deliveryQueue.initialize();
|
||||
|
||||
// Initialize the delivery system
|
||||
const deliveryOptions: IMultiModeDeliveryOptions = {
|
||||
globalRateLimit: 100, // Default to 100 emails per minute
|
||||
concurrentDeliveries: 10
|
||||
};
|
||||
|
||||
this.deliverySystem = new MultiModeDeliverySystem(this.deliveryQueue, deliveryOptions);
|
||||
await this.deliverySystem.start();
|
||||
|
||||
// Initialize the unified email server with internal configuration
|
||||
this.unifiedEmailServer = new UnifiedEmailServer({
|
||||
ports: internalEmailConfig.ports,
|
||||
hostname: internalEmailConfig.hostname,
|
||||
defaultTls: emailConfig.defaultTls,
|
||||
maxMessageSize: emailConfig.maxMessageSize,
|
||||
auth: emailConfig.auth,
|
||||
tls: emailConfig.tls,
|
||||
domainRules: emailConfig.domainRules,
|
||||
defaultMode: emailConfig.defaultMode,
|
||||
defaultServer: emailConfig.defaultServer,
|
||||
defaultPort: emailConfig.defaultPort,
|
||||
defaultTls: emailConfig.defaultTls
|
||||
dkim: emailConfig.dkim,
|
||||
outbound: emailConfig.outbound,
|
||||
rateLimits: emailConfig.rateLimits,
|
||||
debug: emailConfig.debug
|
||||
});
|
||||
|
||||
// Set up event listeners
|
||||
this.unifiedEmailServer.on('error', (err) => {
|
||||
this.emailServer.on('error', (err: Error) => {
|
||||
logger.log('error', `UnifiedEmailServer error: ${err.message}`);
|
||||
});
|
||||
|
||||
// Connect the unified email server with the delivery queue
|
||||
this.unifiedEmailServer.on('emailProcessed', (email, mode, rule) => {
|
||||
this.deliveryQueue!.enqueue(email, mode, rule).catch(err => {
|
||||
logger.log('error', `Failed to enqueue email: ${err.message}`);
|
||||
});
|
||||
});
|
||||
|
||||
// Start the unified email server
|
||||
await this.unifiedEmailServer.start();
|
||||
await this.emailServer.start();
|
||||
|
||||
logger.log('info', `Unified email handling configured with ${emailConfig.domainRules.length} domain rules on internal ports`);
|
||||
logger.log('info', `Email server listening on ports: ${internalEmailConfig.ports.join(', ')}`);
|
||||
logger.log('info', `Unified email handling configured with ${emailConfig.domainRules.length} domain rules`);
|
||||
logger.log('info', `Email server listening on internal ports: ${this.emailServer['options'].ports.join(', ')}`);
|
||||
} catch (error) {
|
||||
logger.log('error', `Error setting up unified email handling: ${error.message}`);
|
||||
throw error;
|
||||
@ -585,39 +532,13 @@ export class DcRouter {
|
||||
*/
|
||||
private async stopUnifiedEmailComponents(): Promise<void> {
|
||||
try {
|
||||
// Stop all components in the correct order
|
||||
|
||||
// 1. Stop the unified email server first
|
||||
if (this.unifiedEmailServer) {
|
||||
await this.unifiedEmailServer.stop();
|
||||
// Stop the unified email server which contains all components
|
||||
if (this.emailServer) {
|
||||
await this.emailServer.stop();
|
||||
logger.log('info', 'Unified email server stopped');
|
||||
this.unifiedEmailServer = undefined;
|
||||
this.emailServer = undefined;
|
||||
}
|
||||
|
||||
// 2. Stop the delivery system
|
||||
if (this.deliverySystem) {
|
||||
await this.deliverySystem.stop();
|
||||
logger.log('info', 'Delivery system stopped');
|
||||
this.deliverySystem = undefined;
|
||||
}
|
||||
|
||||
// 3. Stop the delivery queue
|
||||
if (this.deliveryQueue) {
|
||||
await this.deliveryQueue.shutdown();
|
||||
logger.log('info', 'Delivery queue shut down');
|
||||
this.deliveryQueue = undefined;
|
||||
}
|
||||
|
||||
// 4. Stop the rate limiter
|
||||
if (this.rateLimiter) {
|
||||
this.rateLimiter.stop();
|
||||
logger.log('info', 'Rate limiter stopped');
|
||||
this.rateLimiter = undefined;
|
||||
}
|
||||
|
||||
// 5. Clear the domain router
|
||||
this.domainRouter = undefined;
|
||||
|
||||
logger.log('info', 'All unified email components stopped');
|
||||
} catch (error) {
|
||||
logger.log('error', `Error stopping unified email components: ${error.message}`);
|
||||
@ -638,14 +559,9 @@ export class DcRouter {
|
||||
// Update the configuration
|
||||
this.options.emailConfig.domainRules = rules;
|
||||
|
||||
// Update the domain router if it exists
|
||||
if (this.domainRouter) {
|
||||
this.domainRouter.updateRules(rules);
|
||||
}
|
||||
|
||||
// Update the unified email server if it exists
|
||||
if (this.unifiedEmailServer) {
|
||||
this.unifiedEmailServer.updateDomainRules(rules);
|
||||
if (this.emailServer) {
|
||||
this.emailServer.updateDomainRules(rules);
|
||||
}
|
||||
|
||||
console.log(`Domain rules updated with ${rules.length} rules`);
|
||||
@ -656,10 +572,7 @@ export class DcRouter {
|
||||
*/
|
||||
public getStats(): any {
|
||||
const stats: any = {
|
||||
unifiedEmailServer: this.unifiedEmailServer?.getStats(),
|
||||
deliveryQueue: this.deliveryQueue?.getStats(),
|
||||
deliverySystem: this.deliverySystem?.getStats(),
|
||||
rateLimiter: this.rateLimiter?.getStats()
|
||||
emailServer: this.emailServer?.getStats()
|
||||
};
|
||||
|
||||
return stats;
|
||||
@ -702,8 +615,8 @@ export class DcRouter {
|
||||
|
||||
// Use the dedicated helper to configure the email server
|
||||
// Pass through the options specified by the implementation
|
||||
if (this.unifiedEmailServer) {
|
||||
configureEmailServer(this.unifiedEmailServer, {
|
||||
if (this.emailServer) {
|
||||
configureEmailServer(this.emailServer, {
|
||||
ports: [config.internalPort], // Use whatever port the implementation specifies
|
||||
hostname: config.host,
|
||||
tls: config.secure ? {
|
||||
@ -717,7 +630,7 @@ export class DcRouter {
|
||||
}
|
||||
|
||||
// If email handling is already set up, restart it to apply changes
|
||||
if (this.unifiedEmailServer) {
|
||||
if (this.emailServer) {
|
||||
logger.log('info', 'Restarting unified email handling to apply MTA configuration changes');
|
||||
await this.stopUnifiedEmailComponents();
|
||||
await this.setupUnifiedEmailHandling();
|
||||
|
Reference in New Issue
Block a user