@push.rocks/smartmta 5.3.1 → 5.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +15 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/mail/core/classes.bouncemanager.d.ts +2 -1
- package/dist_ts/mail/core/classes.bouncemanager.js +6 -5
- package/dist_ts/mail/delivery/classes.delivery.queue.d.ts +3 -2
- package/dist_ts/mail/delivery/classes.delivery.queue.js +4 -1
- package/dist_ts/mail/index.d.ts +1 -0
- package/dist_ts/mail/index.js +2 -1
- package/dist_ts/mail/interfaces.storage.d.ts +7 -0
- package/dist_ts/mail/interfaces.storage.js +4 -0
- package/dist_ts/mail/routing/classes.dkim.manager.d.ts +2 -1
- package/dist_ts/mail/routing/classes.dkim.manager.js +17 -8
- package/dist_ts/mail/routing/classes.dns.manager.d.ts +1 -5
- package/dist_ts/mail/routing/classes.dns.manager.js +2 -2
- package/dist_ts/mail/routing/classes.email.router.d.ts +2 -1
- package/dist_ts/mail/routing/classes.email.router.js +6 -5
- package/dist_ts/mail/routing/classes.unified.email.server.d.ts +17 -3
- package/dist_ts/mail/routing/classes.unified.email.server.js +32 -8
- package/dist_ts/mail/security/classes.dkimcreator.d.ts +10 -5
- package/dist_ts/mail/security/classes.dkimcreator.js +91 -70
- package/dist_ts/security/classes.ipreputationchecker.d.ts +4 -3
- package/dist_ts/security/classes.ipreputationchecker.js +4 -3
- package/package.json +11 -11
- package/readme.hints.md +1 -1
- package/readme.md +17 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/mail/core/classes.bouncemanager.ts +7 -6
- package/ts/mail/delivery/classes.delivery.queue.ts +7 -3
- package/ts/mail/index.ts +2 -1
- package/ts/mail/interfaces.storage.ts +13 -0
- package/ts/mail/routing/classes.dkim.manager.ts +24 -11
- package/ts/mail/routing/classes.dns.manager.ts +3 -8
- package/ts/mail/routing/classes.email.router.ts +7 -6
- package/ts/mail/routing/classes.unified.email.server.ts +52 -12
- package/ts/mail/security/classes.dkimcreator.ts +115 -91
- package/ts/security/classes.ipreputationchecker.ts +7 -6
|
@@ -18,7 +18,7 @@ export interface IQueueItem {
|
|
|
18
18
|
id: string;
|
|
19
19
|
processingMode: EmailProcessingMode;
|
|
20
20
|
processingResult: any;
|
|
21
|
-
route
|
|
21
|
+
route?: IEmailRoute;
|
|
22
22
|
status: QueueItemStatus;
|
|
23
23
|
attempts: number;
|
|
24
24
|
nextAttempt: Date;
|
|
@@ -237,7 +237,7 @@ export class UnifiedDeliveryQueue extends EventEmitter {
|
|
|
237
237
|
* @param mode Processing mode
|
|
238
238
|
* @param route Email route
|
|
239
239
|
*/
|
|
240
|
-
public async enqueue(processingResult: any, mode: EmailProcessingMode, route
|
|
240
|
+
public async enqueue(processingResult: any, mode: EmailProcessingMode, route?: IEmailRoute): Promise<string> {
|
|
241
241
|
// Check if queue is full
|
|
242
242
|
if (this.queue.size >= this.options.maxQueueSize) {
|
|
243
243
|
throw new Error('Queue is full');
|
|
@@ -284,6 +284,10 @@ export class UnifiedDeliveryQueue extends EventEmitter {
|
|
|
284
284
|
public getItem(id: string): IQueueItem | undefined {
|
|
285
285
|
return this.queue.get(id);
|
|
286
286
|
}
|
|
287
|
+
|
|
288
|
+
public listItems(): IQueueItem[] {
|
|
289
|
+
return Array.from(this.queue.values()).map((item) => ({ ...item }));
|
|
290
|
+
}
|
|
287
291
|
|
|
288
292
|
/**
|
|
289
293
|
* Mark an item as being processed
|
|
@@ -657,4 +661,4 @@ export class UnifiedDeliveryQueue extends EventEmitter {
|
|
|
657
661
|
this.emit('shutdown');
|
|
658
662
|
logger.log('info', 'UnifiedDeliveryQueue shut down successfully');
|
|
659
663
|
}
|
|
660
|
-
}
|
|
664
|
+
}
|
package/ts/mail/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Export all mail modules for simplified imports
|
|
2
|
+
export * from './interfaces.storage.js';
|
|
2
3
|
export * from './routing/index.js';
|
|
3
4
|
export * from './security/index.js';
|
|
4
5
|
|
|
@@ -14,4 +15,4 @@ import { Email } from './core/classes.email.js';
|
|
|
14
15
|
// Re-export commonly used classes
|
|
15
16
|
export {
|
|
16
17
|
Email,
|
|
17
|
-
};
|
|
18
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface IStorageManagerLike {
|
|
2
|
+
get?(key: string): Promise<string | null>;
|
|
3
|
+
set?(key: string, value: string): Promise<void>;
|
|
4
|
+
list?(prefix: string): Promise<string[]>;
|
|
5
|
+
delete?(key: string): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function hasStorageManagerMethods<T extends keyof IStorageManagerLike>(
|
|
9
|
+
storageManager: IStorageManagerLike | undefined,
|
|
10
|
+
methods: T[],
|
|
11
|
+
): storageManager is IStorageManagerLike & Required<Pick<IStorageManagerLike, T>> {
|
|
12
|
+
return !!storageManager && methods.every((method) => typeof storageManager[method] === 'function');
|
|
13
|
+
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { logger } from '../../logger.js';
|
|
2
2
|
import { DKIMCreator } from '../security/classes.dkimcreator.js';
|
|
3
|
+
import { hasStorageManagerMethods, type IStorageManagerLike } from '../interfaces.storage.js';
|
|
3
4
|
import { DomainRegistry } from './classes.domain.registry.js';
|
|
4
5
|
import { RustSecurityBridge } from '../../security/classes.rustsecuritybridge.js';
|
|
5
6
|
import { Email } from '../core/classes.email.js';
|
|
6
7
|
|
|
7
8
|
/** External DcRouter interface shape used by DkimManager */
|
|
8
9
|
interface DcRouter {
|
|
9
|
-
storageManager
|
|
10
|
+
storageManager?: IStorageManagerLike;
|
|
10
11
|
dnsServer?: any;
|
|
11
12
|
}
|
|
12
13
|
|
|
@@ -39,11 +40,19 @@ export class DkimManager {
|
|
|
39
40
|
let keyPair: { privateKey: string; publicKey: string };
|
|
40
41
|
|
|
41
42
|
try {
|
|
42
|
-
keyPair =
|
|
43
|
+
keyPair = selector === 'default'
|
|
44
|
+
? await this.dkimCreator.readDKIMKeys(domain)
|
|
45
|
+
: await this.dkimCreator.readDKIMKeysForSelector(domain, selector);
|
|
43
46
|
logger.log('info', `Using existing DKIM keys for domain: ${domain}`);
|
|
44
|
-
} catch
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
} catch {
|
|
48
|
+
await this.dkimCreator.handleDKIMKeysForSelector(
|
|
49
|
+
domain,
|
|
50
|
+
selector,
|
|
51
|
+
domainConfig.dkim?.keySize || 2048,
|
|
52
|
+
);
|
|
53
|
+
keyPair = selector === 'default'
|
|
54
|
+
? await this.dkimCreator.readDKIMKeys(domain)
|
|
55
|
+
: await this.dkimCreator.readDKIMKeysForSelector(domain, selector);
|
|
47
56
|
logger.log('info', `Generated new DKIM keys for domain: ${domain}`);
|
|
48
57
|
}
|
|
49
58
|
|
|
@@ -106,10 +115,12 @@ export class DkimManager {
|
|
|
106
115
|
|
|
107
116
|
logger.log('info', `DKIM DNS handler registered for new selector: ${newSelector}._domainkey.${domain}`);
|
|
108
117
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
118
|
+
if (hasStorageManagerMethods(this.dcRouter.storageManager, ['set'])) {
|
|
119
|
+
await this.dcRouter.storageManager.set(
|
|
120
|
+
`/email/dkim/${domain}/public.key`,
|
|
121
|
+
keyPair.publicKey
|
|
122
|
+
);
|
|
123
|
+
}
|
|
113
124
|
}
|
|
114
125
|
|
|
115
126
|
this.dkimCreator.cleanupOldKeys(domain, 30).catch(error => {
|
|
@@ -127,8 +138,10 @@ export class DkimManager {
|
|
|
127
138
|
|
|
128
139
|
async handleDkimSigning(email: Email, domain: string, selector: string): Promise<void> {
|
|
129
140
|
try {
|
|
130
|
-
await this.dkimCreator.
|
|
131
|
-
const { privateKey } =
|
|
141
|
+
await this.dkimCreator.handleDKIMKeysForSelector(domain, selector);
|
|
142
|
+
const { privateKey } = selector === 'default'
|
|
143
|
+
? await this.dkimCreator.readDKIMKeys(domain)
|
|
144
|
+
: await this.dkimCreator.readDKIMKeysForSelector(domain, selector);
|
|
132
145
|
const rawEmail = email.toRFC822String();
|
|
133
146
|
|
|
134
147
|
// Detect key type from PEM header
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
2
|
import type { IEmailDomainConfig } from './interfaces.js';
|
|
3
|
+
import type { IStorageManagerLike } from '../interfaces.storage.js';
|
|
3
4
|
import { logger } from '../../logger.js';
|
|
4
5
|
/** External DcRouter interface shape used by DnsManager */
|
|
5
6
|
interface IDcRouterLike {
|
|
@@ -8,12 +9,6 @@ interface IDcRouterLike {
|
|
|
8
9
|
options?: { dnsNsDomains?: string[]; dnsScopes?: string[] };
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
/** External StorageManager interface shape used by DnsManager */
|
|
12
|
-
interface IStorageManagerLike {
|
|
13
|
-
get(key: string): Promise<string | null>;
|
|
14
|
-
set(key: string, value: string): Promise<void>;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
12
|
/**
|
|
18
13
|
* DNS validation result
|
|
19
14
|
*/
|
|
@@ -528,7 +523,7 @@ export class DnsManager {
|
|
|
528
523
|
|
|
529
524
|
try {
|
|
530
525
|
// Get DKIM DNS record from DKIMCreator
|
|
531
|
-
const dnsRecord = await dkimCreator.getDNSRecordForDomain(domain);
|
|
526
|
+
const dnsRecord = await dkimCreator.getDNSRecordForDomain(domain, selector);
|
|
532
527
|
|
|
533
528
|
// For internal-dns domains, register the DNS handler
|
|
534
529
|
if (domainConfig.dnsMode === 'internal-dns' && this.dcRouter.dnsServer) {
|
|
@@ -570,4 +565,4 @@ export class DnsManager {
|
|
|
570
565
|
}
|
|
571
566
|
}
|
|
572
567
|
}
|
|
573
|
-
}
|
|
568
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
2
|
import { EventEmitter } from 'node:events';
|
|
3
|
+
import { hasStorageManagerMethods, type IStorageManagerLike } from '../interfaces.storage.js';
|
|
3
4
|
import type { IEmailRoute, IEmailMatch, IEmailAction, IEmailContext } from './interfaces.js';
|
|
4
5
|
import type { Email } from '../core/classes.email.js';
|
|
5
6
|
|
|
@@ -9,7 +10,7 @@ import type { Email } from '../core/classes.email.js';
|
|
|
9
10
|
export class EmailRouter extends EventEmitter {
|
|
10
11
|
private routes: IEmailRoute[];
|
|
11
12
|
private patternCache: Map<string, boolean> = new Map();
|
|
12
|
-
private storageManager?:
|
|
13
|
+
private storageManager?: IStorageManagerLike;
|
|
13
14
|
private persistChanges: boolean;
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -18,7 +19,7 @@ export class EmailRouter extends EventEmitter {
|
|
|
18
19
|
* @param options Router options
|
|
19
20
|
*/
|
|
20
21
|
constructor(routes: IEmailRoute[], options?: {
|
|
21
|
-
storageManager?:
|
|
22
|
+
storageManager?: IStorageManagerLike;
|
|
22
23
|
persistChanges?: boolean;
|
|
23
24
|
}) {
|
|
24
25
|
super();
|
|
@@ -27,7 +28,7 @@ export class EmailRouter extends EventEmitter {
|
|
|
27
28
|
this.persistChanges = options?.persistChanges ?? !!this.storageManager;
|
|
28
29
|
|
|
29
30
|
// If storage manager is provided, try to load persisted routes
|
|
30
|
-
if (this.storageManager) {
|
|
31
|
+
if (hasStorageManagerMethods(this.storageManager, ['get'])) {
|
|
31
32
|
this.loadRoutes({ merge: true }).catch(error => {
|
|
32
33
|
console.error(`Failed to load persisted routes: ${error.message}`);
|
|
33
34
|
});
|
|
@@ -394,7 +395,7 @@ export class EmailRouter extends EventEmitter {
|
|
|
394
395
|
* Save current routes to storage
|
|
395
396
|
*/
|
|
396
397
|
public async saveRoutes(): Promise<void> {
|
|
397
|
-
if (!this.storageManager) {
|
|
398
|
+
if (!hasStorageManagerMethods(this.storageManager, ['set'])) {
|
|
398
399
|
this.emit('persistenceWarning', 'Cannot save routes: StorageManager not configured');
|
|
399
400
|
return;
|
|
400
401
|
}
|
|
@@ -425,7 +426,7 @@ export class EmailRouter extends EventEmitter {
|
|
|
425
426
|
merge?: boolean; // Merge with existing routes
|
|
426
427
|
replace?: boolean; // Replace existing routes
|
|
427
428
|
}): Promise<IEmailRoute[]> {
|
|
428
|
-
if (!this.storageManager) {
|
|
429
|
+
if (!hasStorageManagerMethods(this.storageManager, ['get'])) {
|
|
429
430
|
this.emit('persistenceWarning', 'Cannot load routes: StorageManager not configured');
|
|
430
431
|
return [];
|
|
431
432
|
}
|
|
@@ -572,4 +573,4 @@ export class EmailRouter extends EventEmitter {
|
|
|
572
573
|
public getRoute(name: string): IEmailRoute | undefined {
|
|
573
574
|
return this.routes.find(r => r.name === name);
|
|
574
575
|
}
|
|
575
|
-
}
|
|
576
|
+
}
|
|
@@ -8,17 +8,18 @@ import {
|
|
|
8
8
|
SecurityEventType
|
|
9
9
|
} from '../../security/index.js';
|
|
10
10
|
import { DKIMCreator } from '../security/classes.dkimcreator.js';
|
|
11
|
+
import { hasStorageManagerMethods, type IStorageManagerLike } from '../interfaces.storage.js';
|
|
11
12
|
import { RustSecurityBridge } from '../../security/classes.rustsecuritybridge.js';
|
|
12
|
-
import type { IEmailReceivedEvent, IAuthRequestEvent
|
|
13
|
+
import type { IEmailReceivedEvent, IAuthRequestEvent } from '../../security/classes.rustsecuritybridge.js';
|
|
13
14
|
import { EmailRouter } from './classes.email.router.js';
|
|
14
|
-
import type { IEmailRoute,
|
|
15
|
+
import type { IEmailRoute, IEmailContext, IEmailDomainConfig } from './interfaces.js';
|
|
15
16
|
import { Email } from '../core/classes.email.js';
|
|
16
17
|
import { DomainRegistry } from './classes.domain.registry.js';
|
|
17
18
|
import { DnsManager } from './classes.dns.manager.js';
|
|
18
19
|
import { BounceManager, BounceType, BounceCategory } from '../core/classes.bouncemanager.js';
|
|
19
20
|
import type { ISmtpSendResult, IOutboundEmail } from '../../security/classes.rustsecuritybridge.js';
|
|
20
|
-
import { MultiModeDeliverySystem, type IMultiModeDeliveryOptions } from '../delivery/classes.delivery.system.js';
|
|
21
|
-
import { UnifiedDeliveryQueue, type IQueueOptions } from '../delivery/classes.delivery.queue.js';
|
|
21
|
+
import { MultiModeDeliverySystem, type IDeliveryStats, type IMultiModeDeliveryOptions } from '../delivery/classes.delivery.system.js';
|
|
22
|
+
import { UnifiedDeliveryQueue, type IQueueItem, type IQueueOptions, type IQueueStats } from '../delivery/classes.delivery.queue.js';
|
|
22
23
|
import { UnifiedRateLimiter, type IHierarchicalRateLimits } from '../delivery/classes.unified.rate.limiter.js';
|
|
23
24
|
import { SmtpState } from '../delivery/interfaces.js';
|
|
24
25
|
import type { EmailProcessingMode, ISmtpSession as IBaseSmtpSession } from '../delivery/interfaces.js';
|
|
@@ -28,7 +29,7 @@ import { DkimManager } from './classes.dkim.manager.js';
|
|
|
28
29
|
|
|
29
30
|
/** External DcRouter interface shape used by UnifiedEmailServer */
|
|
30
31
|
interface DcRouter {
|
|
31
|
-
storageManager:
|
|
32
|
+
storageManager: IStorageManagerLike;
|
|
32
33
|
dnsServer?: any;
|
|
33
34
|
options?: any;
|
|
34
35
|
}
|
|
@@ -49,11 +50,14 @@ export interface IExtendedSmtpSession extends ISmtpSession {
|
|
|
49
50
|
export interface IUnifiedEmailServerOptions {
|
|
50
51
|
// Base server options
|
|
51
52
|
ports: number[];
|
|
53
|
+
/** Public SMTP hostname used for greeting/banner and as the default outbound identity. */
|
|
52
54
|
hostname: string;
|
|
53
55
|
domains: IEmailDomainConfig[]; // Domain configurations
|
|
54
56
|
banner?: string;
|
|
55
57
|
debug?: boolean;
|
|
56
58
|
useSocketHandler?: boolean; // Use socket-handler mode instead of port listening
|
|
59
|
+
/** Persist router changes back into storage when a storage manager is available. */
|
|
60
|
+
persistRoutes?: boolean;
|
|
57
61
|
|
|
58
62
|
// Authentication options
|
|
59
63
|
auth?: {
|
|
@@ -92,6 +96,8 @@ export interface IUnifiedEmailServerOptions {
|
|
|
92
96
|
|
|
93
97
|
// Outbound settings
|
|
94
98
|
outbound?: {
|
|
99
|
+
/** Override the SMTP identity used for outbound delivery. Defaults to `hostname`. */
|
|
100
|
+
hostname?: string;
|
|
95
101
|
maxConnections?: number;
|
|
96
102
|
connectionTimeout?: number;
|
|
97
103
|
socketTimeout?: number;
|
|
@@ -99,6 +105,9 @@ export interface IUnifiedEmailServerOptions {
|
|
|
99
105
|
defaultFrom?: string;
|
|
100
106
|
};
|
|
101
107
|
|
|
108
|
+
// Delivery queue
|
|
109
|
+
queue?: IQueueOptions;
|
|
110
|
+
|
|
102
111
|
// Rate limiting (global limits, can be overridden per domain)
|
|
103
112
|
rateLimits?: IHierarchicalRateLimits;
|
|
104
113
|
}
|
|
@@ -206,7 +215,7 @@ export class UnifiedEmailServer extends EventEmitter {
|
|
|
206
215
|
// Initialize email router with routes and storage manager
|
|
207
216
|
this.emailRouter = new EmailRouter(options.routes || [], {
|
|
208
217
|
storageManager: dcRouter.storageManager,
|
|
209
|
-
persistChanges:
|
|
218
|
+
persistChanges: options.persistRoutes ?? hasStorageManagerMethods(dcRouter.storageManager, ['get', 'set'])
|
|
210
219
|
});
|
|
211
220
|
|
|
212
221
|
// Initialize rate limiter
|
|
@@ -226,7 +235,8 @@ export class UnifiedEmailServer extends EventEmitter {
|
|
|
226
235
|
storageType: 'memory', // Default to memory storage
|
|
227
236
|
maxRetries: 3,
|
|
228
237
|
baseRetryDelay: 300000, // 5 minutes
|
|
229
|
-
maxRetryDelay: 3600000 // 1 hour
|
|
238
|
+
maxRetryDelay: 3600000, // 1 hour
|
|
239
|
+
...options.queue,
|
|
230
240
|
};
|
|
231
241
|
|
|
232
242
|
this.deliveryQueue = new UnifiedDeliveryQueue(queueOptions);
|
|
@@ -277,6 +287,14 @@ export class UnifiedEmailServer extends EventEmitter {
|
|
|
277
287
|
// We'll create the SMTP servers during the start() method
|
|
278
288
|
}
|
|
279
289
|
|
|
290
|
+
private getAdvertisedHostname(): string {
|
|
291
|
+
return this.options.hostname;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
private getOutboundHostname(): string {
|
|
295
|
+
return this.options.outbound?.hostname || this.options.hostname;
|
|
296
|
+
}
|
|
297
|
+
|
|
280
298
|
/**
|
|
281
299
|
* Send an outbound email via the Rust SMTP client.
|
|
282
300
|
* Uses connection pooling in the Rust binary for efficiency.
|
|
@@ -314,7 +332,7 @@ export class UnifiedEmailServer extends EventEmitter {
|
|
|
314
332
|
host,
|
|
315
333
|
port,
|
|
316
334
|
secure: port === 465,
|
|
317
|
-
domain: this.
|
|
335
|
+
domain: this.getOutboundHostname(),
|
|
318
336
|
auth: options?.auth,
|
|
319
337
|
email: outboundEmail,
|
|
320
338
|
dkim,
|
|
@@ -455,7 +473,7 @@ export class UnifiedEmailServer extends EventEmitter {
|
|
|
455
473
|
const securePort = (this.options.ports as number[]).find(p => p === 465);
|
|
456
474
|
|
|
457
475
|
const started = await this.rustBridge.startSmtpServer({
|
|
458
|
-
hostname: this.
|
|
476
|
+
hostname: this.getAdvertisedHostname(),
|
|
459
477
|
ports: smtpPorts,
|
|
460
478
|
securePort: securePort,
|
|
461
479
|
tlsCertPem,
|
|
@@ -518,6 +536,9 @@ export class UnifiedEmailServer extends EventEmitter {
|
|
|
518
536
|
logger.log('info', 'Email delivery queue shut down');
|
|
519
537
|
}
|
|
520
538
|
|
|
539
|
+
this.bounceManager.stop();
|
|
540
|
+
logger.log('info', 'Bounce manager stopped');
|
|
541
|
+
|
|
521
542
|
// Close all Rust SMTP client connection pools
|
|
522
543
|
try {
|
|
523
544
|
await this.rustBridge.closeSmtpPool();
|
|
@@ -973,6 +994,10 @@ export class UnifiedEmailServer extends EventEmitter {
|
|
|
973
994
|
this.emailRouter.updateRoutes(routes);
|
|
974
995
|
}
|
|
975
996
|
|
|
997
|
+
public getEmailRoutes(): IEmailRoute[] {
|
|
998
|
+
return this.emailRouter.getRoutes();
|
|
999
|
+
}
|
|
1000
|
+
|
|
976
1001
|
/**
|
|
977
1002
|
* Get server statistics
|
|
978
1003
|
*/
|
|
@@ -980,6 +1005,22 @@ export class UnifiedEmailServer extends EventEmitter {
|
|
|
980
1005
|
return { ...this.stats };
|
|
981
1006
|
}
|
|
982
1007
|
|
|
1008
|
+
public getQueueStats(): IQueueStats {
|
|
1009
|
+
return this.deliveryQueue.getStats();
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
public getQueueItems(): IQueueItem[] {
|
|
1013
|
+
return this.deliveryQueue.listItems();
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
public getQueueItem(id: string): IQueueItem | undefined {
|
|
1017
|
+
return this.deliveryQueue.getItem(id);
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
public getDeliveryStats(): IDeliveryStats {
|
|
1021
|
+
return this.deliverySystem.getStats();
|
|
1022
|
+
}
|
|
1023
|
+
|
|
983
1024
|
/**
|
|
984
1025
|
* Get domain registry
|
|
985
1026
|
*/
|
|
@@ -1039,11 +1080,10 @@ export class UnifiedEmailServer extends EventEmitter {
|
|
|
1039
1080
|
// Sign with DKIM if configured
|
|
1040
1081
|
if (mode === 'mta' && route?.action.options?.mtaOptions?.dkimSign) {
|
|
1041
1082
|
const domain = email.from.split('@')[1];
|
|
1042
|
-
await this.dkimManager.handleDkimSigning(email, domain, route.action.options.mtaOptions.dkimOptions?.keySelector || '
|
|
1083
|
+
await this.dkimManager.handleDkimSigning(email, domain, route.action.options.mtaOptions.dkimOptions?.keySelector || 'default');
|
|
1043
1084
|
}
|
|
1044
1085
|
|
|
1045
|
-
const id =
|
|
1046
|
-
await this.deliveryQueue.enqueue(email, mode, route);
|
|
1086
|
+
const id = await this.deliveryQueue.enqueue(email, mode, route);
|
|
1047
1087
|
|
|
1048
1088
|
logger.log('info', `Email queued with ID: ${id}`);
|
|
1049
1089
|
return id;
|