@push.rocks/smartmta 9.4.1 → 9.5.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 (35) hide show
  1. package/changelog.md +14 -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 +1 -0
  6. package/dist_ts/index.js +2 -1
  7. package/dist_ts/mail/delivery/classes.delivery.queue.d.ts +63 -2
  8. package/dist_ts/mail/delivery/classes.delivery.queue.js +749 -193
  9. package/dist_ts/mail/delivery/classes.delivery.system.d.ts +6 -0
  10. package/dist_ts/mail/delivery/classes.delivery.system.js +146 -62
  11. package/dist_ts/mail/delivery/functions.raw-email.d.ts +9 -0
  12. package/dist_ts/mail/delivery/functions.raw-email.js +85 -0
  13. package/dist_ts/mail/delivery/symbols.delivery.queue.d.ts +6 -0
  14. package/dist_ts/mail/delivery/symbols.delivery.queue.js +7 -0
  15. package/dist_ts/mail/index.d.ts +1 -0
  16. package/dist_ts/mail/index.js +1 -1
  17. package/dist_ts/mail/routing/classes.unified.email.server.d.ts +40 -0
  18. package/dist_ts/mail/routing/classes.unified.email.server.js +222 -76
  19. package/dist_ts/mail/routing/symbols.unified.email.server.d.ts +2 -0
  20. package/dist_ts/mail/routing/symbols.unified.email.server.js +3 -0
  21. package/dist_ts/security/classes.rustsecuritybridge.d.ts +11 -0
  22. package/dist_ts/security/classes.rustsecuritybridge.js +1 -1
  23. package/package.json +2 -2
  24. package/readme.hints.md +8 -0
  25. package/readme.md +34 -3
  26. package/ts/00_commitinfo_data.ts +1 -1
  27. package/ts/index.ts +1 -0
  28. package/ts/mail/delivery/classes.delivery.queue.ts +923 -226
  29. package/ts/mail/delivery/classes.delivery.system.ts +192 -80
  30. package/ts/mail/delivery/functions.raw-email.ts +111 -0
  31. package/ts/mail/delivery/symbols.delivery.queue.ts +6 -0
  32. package/ts/mail/index.ts +1 -0
  33. package/ts/mail/routing/classes.unified.email.server.ts +329 -85
  34. package/ts/mail/routing/symbols.unified.email.server.ts +6 -0
  35. package/ts/security/classes.rustsecuritybridge.ts +6 -0
@@ -0,0 +1,9 @@
1
+ export interface IRawSmtpEnvelope {
2
+ from: string;
3
+ to: string[];
4
+ }
5
+ export declare const MAX_RAW_SMTP_RECIPIENTS = 100;
6
+ export declare const assertCanonicalRawRfc822Message: (rawMessageArg: Buffer) => void;
7
+ export declare const normalizeRawSmtpEnvelope: (envelopeArg: IRawSmtpEnvelope) => IRawSmtpEnvelope;
8
+ export declare const cloneRawSmtpEnvelope: (envelopeArg: IRawSmtpEnvelope) => IRawSmtpEnvelope;
9
+ export declare const createRawQueueFingerprint: (rawMessageArg: Buffer, envelopeArg: IRawSmtpEnvelope) => string;
@@ -0,0 +1,85 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { domainToASCII } from 'node:url';
3
+ import { Email } from '../core/classes.email.js';
4
+ export const MAX_RAW_SMTP_RECIPIENTS = 100;
5
+ export const assertCanonicalRawRfc822Message = (rawMessageArg) => {
6
+ if (!Buffer.isBuffer(rawMessageArg) || rawMessageArg.length === 0) {
7
+ throw new Error('Raw outbound message must be a nonempty Buffer');
8
+ }
9
+ for (let index = 0; index < rawMessageArg.length; index++) {
10
+ const byte = rawMessageArg[index];
11
+ if (byte === 0x0d && rawMessageArg[index + 1] !== 0x0a) {
12
+ throw new Error('Raw outbound message must use canonical CRLF line endings');
13
+ }
14
+ if (byte === 0x0a && (index === 0 || rawMessageArg[index - 1] !== 0x0d)) {
15
+ throw new Error('Raw outbound message must use canonical CRLF line endings');
16
+ }
17
+ }
18
+ if (rawMessageArg.length < 2
19
+ || rawMessageArg[rawMessageArg.length - 2] !== 0x0d
20
+ || rawMessageArg[rawMessageArg.length - 1] !== 0x0a) {
21
+ throw new Error('Raw outbound message must end with CRLF');
22
+ }
23
+ };
24
+ const writeLengthFramed = (hashArg, labelArg, valueArg) => {
25
+ const label = Buffer.from(labelArg, 'utf8');
26
+ const labelLength = Buffer.allocUnsafe(4);
27
+ labelLength.writeUInt32BE(label.length);
28
+ const valueLength = Buffer.allocUnsafe(8);
29
+ valueLength.writeBigUInt64BE(BigInt(valueArg.length));
30
+ hashArg.update(labelLength).update(label).update(valueLength).update(valueArg);
31
+ };
32
+ const normalizeRawMailbox = (valueArg, fieldArg) => {
33
+ if (typeof valueArg !== 'string' || /[\r\n<>]/.test(valueArg)) {
34
+ throw new Error(`Raw SMTP envelope ${fieldArg} must be a plain mailbox address`);
35
+ }
36
+ const value = valueArg.trim();
37
+ const atIndex = value.indexOf('@');
38
+ if (atIndex < 1 || atIndex !== value.lastIndexOf('@') || atIndex === value.length - 1) {
39
+ throw new Error(`Raw SMTP envelope ${fieldArg} must be a plain mailbox address`);
40
+ }
41
+ const asciiDomain = domainToASCII(value.slice(atIndex + 1));
42
+ if (!asciiDomain) {
43
+ throw new Error(`Raw SMTP envelope ${fieldArg} has an invalid domain`);
44
+ }
45
+ const normalized = `${value.slice(0, atIndex).toLowerCase()}@${asciiDomain.toLowerCase()}`;
46
+ try {
47
+ new Email({ from: normalized, to: normalized, subject: '', text: '' });
48
+ }
49
+ catch {
50
+ throw new Error(`Raw SMTP envelope ${fieldArg} must be a valid mailbox address`);
51
+ }
52
+ return normalized;
53
+ };
54
+ export const normalizeRawSmtpEnvelope = (envelopeArg) => {
55
+ if (!envelopeArg || typeof envelopeArg !== 'object') {
56
+ throw new Error('Raw SMTP envelope is required');
57
+ }
58
+ if (!Array.isArray(envelopeArg.to)
59
+ || envelopeArg.to.length === 0
60
+ || envelopeArg.to.length > MAX_RAW_SMTP_RECIPIENTS) {
61
+ throw new Error(`Raw SMTP envelope requires 1 to ${MAX_RAW_SMTP_RECIPIENTS} recipients`);
62
+ }
63
+ const from = normalizeRawMailbox(envelopeArg.from, 'sender');
64
+ const to = envelopeArg.to.map((recipient, index) => (normalizeRawMailbox(recipient, `recipient ${index + 1}`)));
65
+ if (new Set(to).size !== to.length) {
66
+ throw new Error('Raw SMTP envelope recipients must be unique after canonicalization');
67
+ }
68
+ return { from, to };
69
+ };
70
+ export const cloneRawSmtpEnvelope = (envelopeArg) => ({
71
+ from: envelopeArg.from,
72
+ to: [...envelopeArg.to],
73
+ });
74
+ export const createRawQueueFingerprint = (rawMessageArg, envelopeArg) => {
75
+ const hash = createHash('sha256');
76
+ hash.update('smartmta:durable-raw-outbound-queue:fingerprint:v1\0');
77
+ writeLengthFramed(hash, 'raw-rfc822-bytes', rawMessageArg);
78
+ writeLengthFramed(hash, 'smtp-envelope-from', Buffer.from(envelopeArg.from, 'utf8'));
79
+ for (const recipient of envelopeArg.to) {
80
+ writeLengthFramed(hash, 'smtp-envelope-recipient', Buffer.from(recipient, 'utf8'));
81
+ }
82
+ writeLengthFramed(hash, 'processing-semantics', Buffer.from('raw-mta;dkim=required-current-sender-domain-key;transform=none', 'utf8'));
83
+ return hash.digest('hex');
84
+ };
85
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnVuY3Rpb25zLnJhdy1lbWFpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL21haWwvZGVsaXZlcnkvZnVuY3Rpb25zLnJhdy1lbWFpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFhLE1BQU0sYUFBYSxDQUFDO0FBQ3BELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFekMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBT2pELE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLEdBQUcsQ0FBQztBQUUzQyxNQUFNLENBQUMsTUFBTSwrQkFBK0IsR0FBRyxDQUFDLGFBQXFCLEVBQVEsRUFBRTtJQUM3RSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsSUFBSSxhQUFhLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ2xFLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0RBQWdELENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBQ0QsS0FBSyxJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUUsS0FBSyxHQUFHLGFBQWEsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQztRQUMxRCxNQUFNLElBQUksR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbEMsSUFBSSxJQUFJLEtBQUssSUFBSSxJQUFJLGFBQWEsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7WUFDdkQsTUFBTSxJQUFJLEtBQUssQ0FBQywyREFBMkQsQ0FBQyxDQUFDO1FBQy9FLENBQUM7UUFDRCxJQUFJLElBQUksS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssQ0FBQyxJQUFJLGFBQWEsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUN4RSxNQUFNLElBQUks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
@@ -0,0 +1,6 @@
1
+ export declare const kQueueCloseAdmission: unique symbol;
2
+ export declare const kQueueCreateItemSnapshot: unique symbol;
3
+ export declare const kQueueEnqueueRaw: unique symbol;
4
+ export declare const kQueueReserveRawAccess: unique symbol;
5
+ export declare const kQueueSetReadyItemsHandler: unique symbol;
6
+ export declare const kQueueWithRawMessage: unique symbol;
@@ -0,0 +1,7 @@
1
+ export const kQueueCloseAdmission = Symbol('smartmta.queue.closeAdmission');
2
+ export const kQueueCreateItemSnapshot = Symbol('smartmta.queue.createItemSnapshot');
3
+ export const kQueueEnqueueRaw = Symbol('smartmta.queue.enqueueRaw');
4
+ export const kQueueReserveRawAccess = Symbol('smartmta.queue.reserveRawAccess');
5
+ export const kQueueSetReadyItemsHandler = Symbol('smartmta.queue.setReadyItemsHandler');
6
+ export const kQueueWithRawMessage = Symbol('smartmta.queue.withRawMessage');
7
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ltYm9scy5kZWxpdmVyeS5xdWV1ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL21haWwvZGVsaXZlcnkvc3ltYm9scy5kZWxpdmVyeS5xdWV1ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBa0IsTUFBTSxDQUFDLCtCQUErQixDQUFDLENBQUM7QUFDM0YsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQWtCLE1BQU0sQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO0FBQ25HLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFrQixNQUFNLENBQUMsMkJBQTJCLENBQUMsQ0FBQztBQUNuRixNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBa0IsTUFBTSxDQUFDLGlDQUFpQyxDQUFDLENBQUM7QUFDL0YsTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQWtCLE1BQU0sQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO0FBQ3ZHLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFrQixNQUFNLENBQUMsK0JBQStCLENBQUMsQ0FBQyJ9
@@ -2,6 +2,7 @@ export * from './interfaces.storage.js';
2
2
  export * from './routing/index.js';
3
3
  export * from './security/index.js';
4
4
  export type { ISmtpTransactionAttempt } from './delivery/interfaces.js';
5
+ export type { IRawSmtpEnvelope } from './delivery/functions.raw-email.js';
5
6
  import * as Core from './core/index.js';
6
7
  import * as Delivery from './delivery/index.js';
7
8
  export { Core, Delivery };
@@ -10,4 +10,4 @@ export { Core, Delivery };
10
10
  import { Email } from './core/classes.email.js';
11
11
  // Re-export commonly used classes
12
12
  export { Email, };
13
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tYWlsL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGlEQUFpRDtBQUNqRCxjQUFjLHlCQUF5QixDQUFDO0FBQ3hDLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYyxxQkFBcUIsQ0FBQztBQUdwQyxnREFBZ0Q7QUFDaEQsT0FBTyxLQUFLLElBQUksTUFBTSxpQkFBaUIsQ0FBQztBQUN4QyxPQUFPLEtBQUssUUFBUSxNQUFNLHFCQUFxQixDQUFDO0FBRWhELE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7QUFFMUIscUJBQXFCO0FBQ3JCLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUVoRCxrQ0FBa0M7QUFDbEMsT0FBTyxFQUNMLEtBQUssR0FDTixDQUFDIn0=
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tYWlsL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGlEQUFpRDtBQUNqRCxjQUFjLHlCQUF5QixDQUFDO0FBQ3hDLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYyxxQkFBcUIsQ0FBQztBQUlwQyxnREFBZ0Q7QUFDaEQsT0FBTyxLQUFLLElBQUksTUFBTSxpQkFBaUIsQ0FBQztBQUN4QyxPQUFPLEtBQUssUUFBUSxNQUFNLHFCQUFxQixDQUFDO0FBRWhELE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7QUFFMUIscUJBQXFCO0FBQ3JCLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUVoRCxrQ0FBa0M7QUFDbEMsT0FBTyxFQUNMLEtBQUssR0FDTixDQUFDIn0=
@@ -11,6 +11,8 @@ import { MultiModeDeliverySystem, type IDeliveryStats } from '../delivery/classe
11
11
  import { UnifiedDeliveryQueue, type IQueueItem, type IQueueOptions, type IQueueStats } from '../delivery/classes.delivery.queue.js';
12
12
  import { UnifiedRateLimiter, type IHierarchicalRateLimits } from '../delivery/classes.unified.rate.limiter.js';
13
13
  import type { EmailProcessingMode, ISmtpSession as IBaseSmtpSession } from '../delivery/interfaces.js';
14
+ import { type IRawSmtpEnvelope } from '../delivery/functions.raw-email.js';
15
+ import { kSendOutboundEmailInternal, kSendRawOutboundEmailInternal } from './symbols.unified.email.server.js';
14
16
  /** External DcRouter interface shape used by UnifiedEmailServer */
15
17
  interface DcRouter {
16
18
  storageManager: IStorageManager;
@@ -373,6 +375,10 @@ export declare class UnifiedEmailServer extends EventEmitter {
373
375
  private smtpListenerActive;
374
376
  private smtpListenerShutdown;
375
377
  private smtpListenerRestartPromise?;
378
+ private acceptingOutboundWork;
379
+ private readonly outboundWorkFlights;
380
+ private readonly outboundAuthenticationFlights;
381
+ private stopFlight?;
376
382
  private static readonly VERIFIER_DERIVATION_CONCURRENCY;
377
383
  private static readonly VERIFIER_DERIVATION_MAX_QUEUE;
378
384
  private verifierDerivationActive;
@@ -380,6 +386,8 @@ export declare class UnifiedEmailServer extends EventEmitter {
380
386
  /** Compiled scope patterns; keys are config-supplied, bounded by config size. */
381
387
  private scopePatternCache;
382
388
  constructor(dcRouter: DcRouter, options: IUnifiedEmailServerOptions);
389
+ private assertAcceptingOutboundWork;
390
+ private trackOutboundWork;
383
391
  onRecipientRejected(listener: (event: IRecipientRejectedEvent) => Promise<void> | void): this;
384
392
  offRecipientRejected(listener: (event: IRecipientRejectedEvent) => Promise<void> | void): this;
385
393
  private getAdvertisedHostname;
@@ -410,6 +418,36 @@ export declare class UnifiedEmailServer extends EventEmitter {
410
418
  dkimSelector?: string;
411
419
  tlsOpportunistic?: boolean;
412
420
  }): Promise<ISmtpSendResult>;
421
+ [kSendOutboundEmailInternal](host: string, port: number, email: Email, options?: {
422
+ auth?: {
423
+ user: string;
424
+ pass: string;
425
+ };
426
+ dkimDomain?: string;
427
+ dkimSelector?: string;
428
+ tlsOpportunistic?: boolean;
429
+ }): Promise<ISmtpSendResult>;
430
+ /** Send exact RFC822 bytes through the same outbound transport path as structured mail. */
431
+ sendRawOutboundEmail(host: string, port: number, rawMessage: Buffer, envelopeArg: IRawSmtpEnvelope, options: {
432
+ auth?: {
433
+ user: string;
434
+ pass: string;
435
+ };
436
+ dkimDomain: string;
437
+ dkimSelector: string;
438
+ tlsOpportunistic?: boolean;
439
+ }): Promise<ISmtpSendResult>;
440
+ [kSendRawOutboundEmailInternal](host: string, port: number, rawMessage: Buffer, envelopeArg: IRawSmtpEnvelope, options: {
441
+ auth?: {
442
+ user: string;
443
+ pass: string;
444
+ };
445
+ dkimDomain: string;
446
+ dkimSelector: string;
447
+ tlsOpportunistic?: boolean;
448
+ }): Promise<ISmtpSendResult>;
449
+ private resolveOutboundDkim;
450
+ private sendWithOutboundTransport;
413
451
  private createOutboundAuthenticationHandle;
414
452
  /**
415
453
  * Start the unified email server
@@ -453,6 +491,7 @@ export declare class UnifiedEmailServer extends EventEmitter {
453
491
  * Stop the unified email server
454
492
  */
455
493
  stop(): Promise<void>;
494
+ private stopOnce;
456
495
  private handleRustRcptToRequest;
457
496
  private evaluateDefaultRcptToPolicy;
458
497
  private resolveRecipientPolicy;
@@ -644,6 +683,7 @@ export declare class UnifiedEmailServer extends EventEmitter {
644
683
  /**
645
684
  * Send an email through the delivery system
646
685
  */
686
+ enqueueRawEmail(rawMessage: Buffer, envelope: IRawSmtpEnvelope, idempotencyKey: string): Promise<string>;
647
687
  sendEmail(email: Email, mode?: EmailProcessingMode, route?: IEmailRoute, options?: {
648
688
  skipSuppressionCheck?: boolean;
649
689
  ipAddress?: string;