@push.rocks/smartmta 8.0.0 → 8.1.0

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.
Files changed (45) hide show
  1. package/changelog.md +41 -0
  2. package/dist_rust/mailer-bin_linux_amd64 +0 -0
  3. package/dist_rust/mailer-bin_linux_arm64 +0 -0
  4. package/dist_ts/00_commitinfo_data.js +1 -1
  5. package/dist_ts/index.d.ts +5 -0
  6. package/dist_ts/index.js +6 -1
  7. package/dist_ts/mail/delivery/classes.delivery.queue.d.ts +15 -2
  8. package/dist_ts/mail/delivery/classes.delivery.queue.js +91 -8
  9. package/dist_ts/mail/delivery/classes.delivery.system.d.ts +13 -2
  10. package/dist_ts/mail/delivery/classes.delivery.system.js +106 -36
  11. package/dist_ts/mail/delivery/index.d.ts +1 -0
  12. package/dist_ts/mail/delivery/index.js +2 -1
  13. package/dist_ts/mail/index.d.ts +1 -0
  14. package/dist_ts/mail/index.js +1 -1
  15. package/dist_ts/mail/routing/classes.domain.registry.js +5 -1
  16. package/dist_ts/mail/routing/classes.email.action.executor.js +3 -1
  17. package/dist_ts/mail/routing/classes.email.router.d.ts +2 -0
  18. package/dist_ts/mail/routing/classes.email.router.js +28 -21
  19. package/dist_ts/mail/routing/classes.unified.email.server.d.ts +85 -3
  20. package/dist_ts/mail/routing/classes.unified.email.server.js +517 -60
  21. package/dist_ts/mail/routing/functions.routing.validation.d.ts +8 -0
  22. package/dist_ts/mail/routing/functions.routing.validation.js +18 -0
  23. package/dist_ts/mail/routing/interfaces.d.ts +11 -1
  24. package/dist_ts/plugins.d.ts +2 -1
  25. package/dist_ts/plugins.js +3 -2
  26. package/dist_ts/security/classes.rustsecuritybridge.d.ts +32 -1
  27. package/dist_ts/security/classes.rustsecuritybridge.js +13 -1
  28. package/dist_ts/security/index.d.ts +1 -1
  29. package/dist_ts/security/index.js +1 -1
  30. package/package.json +1 -1
  31. package/ts/00_commitinfo_data.ts +1 -1
  32. package/ts/index.ts +5 -0
  33. package/ts/mail/delivery/classes.delivery.queue.ts +126 -6
  34. package/ts/mail/delivery/classes.delivery.system.ts +137 -41
  35. package/ts/mail/delivery/index.ts +1 -0
  36. package/ts/mail/index.ts +1 -0
  37. package/ts/mail/routing/classes.domain.registry.ts +4 -0
  38. package/ts/mail/routing/classes.email.action.executor.ts +4 -0
  39. package/ts/mail/routing/classes.email.router.ts +33 -20
  40. package/ts/mail/routing/classes.unified.email.server.ts +703 -72
  41. package/ts/mail/routing/functions.routing.validation.ts +36 -0
  42. package/ts/mail/routing/interfaces.ts +13 -1
  43. package/ts/plugins.ts +2 -0
  44. package/ts/security/classes.rustsecuritybridge.ts +46 -1
  45. package/ts/security/index.ts +3 -0
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Reject retention values that cannot be represented and scheduled reliably.
3
+ */
4
+ export function assertValidRetentionDays(
5
+ retentionDays: unknown,
6
+ owner: string,
7
+ ): asserts retentionDays is number {
8
+ if (
9
+ typeof retentionDays !== 'number'
10
+ || !Number.isSafeInteger(retentionDays)
11
+ || retentionDays <= 0
12
+ ) {
13
+ throw new Error(`${owner} retentionDays must be a finite positive integer`);
14
+ }
15
+ }
16
+
17
+ export function assertValidInboundPolicy(
18
+ inboundPolicy: {
19
+ defaultAction: unknown;
20
+ retentionDays: unknown;
21
+ },
22
+ domain: string,
23
+ ): void {
24
+ if (
25
+ inboundPolicy.defaultAction !== 'store'
26
+ && inboundPolicy.defaultAction !== 'reject'
27
+ ) {
28
+ throw new Error(
29
+ `Inbound policy for domain ${domain} defaultAction must be store or reject`,
30
+ );
31
+ }
32
+ assertValidRetentionDays(
33
+ inboundPolicy.retentionDays,
34
+ `Inbound policy for domain ${domain}`,
35
+ );
36
+ }
@@ -44,7 +44,7 @@ export interface IEmailMatch {
44
44
  */
45
45
  export interface IEmailAction {
46
46
  /** Type of action to perform */
47
- type: 'forward' | 'deliver' | 'reject' | 'process';
47
+ type: 'forward' | 'deliver' | 'reject' | 'process' | 'store';
48
48
  /** Explicitly permits this route to relay to non-local recipients. */
49
49
  allowRelay?: boolean;
50
50
 
@@ -82,6 +82,12 @@ export interface IEmailAction {
82
82
  /** Delivery queue priority */
83
83
  queue?: 'normal' | 'priority' | 'bulk';
84
84
  };
85
+
86
+ /** Durable inbound storage configuration. */
87
+ store?: {
88
+ /** Number of days the stored message should be retained. */
89
+ retentionDays: number;
90
+ };
85
91
 
86
92
  /** Options for various action types */
87
93
  options?: {
@@ -173,6 +179,12 @@ export interface IEmailDomainConfig {
173
179
  requiredRecords?: ('MX' | 'SPF' | 'DKIM' | 'DMARC')[];
174
180
  };
175
181
  };
182
+
183
+ /** Default behavior after no explicit route matches an inbound recipient. */
184
+ inboundPolicy?: {
185
+ defaultAction: 'store' | 'reject';
186
+ retentionDays: number;
187
+ };
176
188
 
177
189
  /** Per-domain DKIM settings (DKIM always enabled) */
178
190
  dkim?: {
package/ts/plugins.ts CHANGED
@@ -6,6 +6,7 @@ import * as net from 'net';
6
6
  import * as os from 'os';
7
7
  import * as path from 'path';
8
8
  import * as tls from 'tls';
9
+ import * as url from 'url';
9
10
  import * as util from 'util';
10
11
 
11
12
  export {
@@ -16,6 +17,7 @@ export {
16
17
  os,
17
18
  path,
18
19
  tls,
20
+ url,
19
21
  util,
20
22
  }
21
23
 
@@ -32,6 +32,28 @@ interface IDmarcResult {
32
32
  details: string | null;
33
33
  }
34
34
 
35
+ export interface IInboundIpReputationResult {
36
+ score: number;
37
+ is_spam: boolean;
38
+ ip: string;
39
+ dnsbl: {
40
+ ip: string;
41
+ listed_count: number;
42
+ listed_on: string[];
43
+ total_checked: number;
44
+ };
45
+ ip_type: string;
46
+ }
47
+
48
+ export interface IInboundEmailSecurityResult {
49
+ dkim: IDkimVerificationResult[];
50
+ spf: ISpfResult | null;
51
+ dmarc: IDmarcResult | null;
52
+ contentScan: IContentScanResult;
53
+ ipReputation: IInboundIpReputationResult | null;
54
+ }
55
+
56
+ /** Compound verification response returned by the explicit verifyEmail command. */
35
57
  interface IEmailSecurityResult {
36
58
  dkim: IDkimVerificationResult[];
37
59
  spf: ISpfResult | null;
@@ -92,6 +114,11 @@ export interface ISmtpTranscriptEntry {
92
114
  direction: 'client' | 'server' | 'system';
93
115
  text: string;
94
116
  responseCode?: number;
117
+ transferStats?: {
118
+ bytes: number;
119
+ chunks: number;
120
+ durationMs: number;
121
+ };
95
122
  }
96
123
 
97
124
  /** Persisted SMTP traces are bounded by entries, Unicode code points, and UTF-8 bytes. */
@@ -167,6 +194,17 @@ export const normalizeSmtpTranscript = (entriesArg: unknown[]): ISmtpTranscriptE
167
194
  continue;
168
195
  }
169
196
 
197
+ const transferStats = value.transferStats;
198
+ const validTransferStats = transferStats
199
+ && typeof transferStats === 'object'
200
+ && Number.isSafeInteger(transferStats.bytes)
201
+ && transferStats.bytes >= 0
202
+ && Number.isSafeInteger(transferStats.chunks)
203
+ && transferStats.chunks >= 0
204
+ && Number.isSafeInteger(transferStats.durationMs)
205
+ && transferStats.durationMs >= 0
206
+ ? { ...transferStats }
207
+ : undefined;
170
208
  const direction = value.direction as ISmtpTranscriptEntry['direction'];
171
209
  const text = truncateCodePoints(redactAuthTranscriptText(value.phase, direction, value.text));
172
210
  const textBytes = utf8ByteLength(text);
@@ -186,6 +224,7 @@ export const normalizeSmtpTranscript = (entriesArg: unknown[]): ISmtpTranscriptE
186
224
  ...(typeof value.responseCode === 'number' && Number.isInteger(value.responseCode)
187
225
  ? { responseCode: value.responseCode }
188
226
  : {}),
227
+ ...(validTransferStats ? { transferStats: validTransferStats } : {}),
189
228
  });
190
229
  totalUtf8Bytes += textBytes;
191
230
  }
@@ -323,6 +362,12 @@ interface IOutboundEmail {
323
362
  text?: string;
324
363
  html?: string;
325
364
  headers?: Record<string, string>;
365
+ attachments?: Array<{
366
+ filename: string;
367
+ contentBase64: string;
368
+ contentType: string;
369
+ contentId?: string;
370
+ }>;
326
371
  }
327
372
 
328
373
  interface ISmtpSendResult {
@@ -445,7 +490,7 @@ interface IEmailReceivedEvent {
445
490
  clientHostname: string | null;
446
491
  secure: boolean;
447
492
  authenticatedUser: string | null;
448
- securityResults: any | null;
493
+ securityResults: IInboundEmailSecurityResult | null;
449
494
  }
450
495
 
451
496
  interface IRcptToRequestEvent {
@@ -32,12 +32,15 @@ export {
32
32
  type ISpfResult,
33
33
  type IDmarcResult,
34
34
  type IEmailSecurityResult,
35
+ type IInboundEmailSecurityResult,
36
+ type IInboundIpReputationResult,
35
37
  type IValidationResult,
36
38
  type IBounceDetection,
37
39
  type IRustReputationResult,
38
40
  type IVersionInfo,
39
41
  type IOutboundEmail,
40
42
  type ISmtpSendResult,
43
+ type ISmtpRecipientResult,
41
44
  type ISmtpSendOptions,
42
45
  type ISmtpVerifyResult,
43
46
  type ISmtpPoolStatus,