@push.rocks/smartmta 8.0.1 → 8.1.1
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 +51 -0
- package/dist_rust/mailer-bin_linux_amd64 +0 -0
- package/dist_rust/mailer-bin_linux_arm64 +0 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/index.d.ts +6 -0
- package/dist_ts/index.js +7 -1
- package/dist_ts/mail/delivery/classes.delivery.queue.d.ts +43 -3
- package/dist_ts/mail/delivery/classes.delivery.queue.js +310 -10
- package/dist_ts/mail/delivery/classes.delivery.system.d.ts +13 -2
- package/dist_ts/mail/delivery/classes.delivery.system.js +106 -36
- package/dist_ts/mail/interfaces.storage.d.ts +34 -0
- package/dist_ts/mail/interfaces.storage.js +89 -3
- package/dist_ts/mail/routing/classes.domain.registry.js +5 -1
- package/dist_ts/mail/routing/classes.email.action.executor.d.ts +15 -0
- package/dist_ts/mail/routing/classes.email.action.executor.js +38 -13
- package/dist_ts/mail/routing/classes.email.router.d.ts +2 -0
- package/dist_ts/mail/routing/classes.email.router.js +28 -21
- package/dist_ts/mail/routing/classes.unified.email.server.d.ts +156 -4
- package/dist_ts/mail/routing/classes.unified.email.server.js +1001 -61
- package/dist_ts/mail/routing/functions.routing.validation.d.ts +8 -0
- package/dist_ts/mail/routing/functions.routing.validation.js +18 -0
- package/dist_ts/mail/routing/interfaces.d.ts +11 -1
- package/dist_ts/plugins.d.ts +2 -1
- package/dist_ts/plugins.js +3 -2
- package/dist_ts/security/classes.rustsecuritybridge.d.ts +32 -1
- package/dist_ts/security/classes.rustsecuritybridge.js +13 -1
- package/dist_ts/security/index.d.ts +1 -1
- package/dist_ts/security/index.js +1 -1
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/index.ts +6 -0
- package/ts/mail/delivery/classes.delivery.queue.ts +429 -7
- package/ts/mail/delivery/classes.delivery.system.ts +137 -41
- package/ts/mail/interfaces.storage.ts +148 -2
- package/ts/mail/routing/classes.domain.registry.ts +4 -0
- package/ts/mail/routing/classes.email.action.executor.ts +97 -13
- package/ts/mail/routing/classes.email.router.ts +33 -20
- package/ts/mail/routing/classes.unified.email.server.ts +1367 -74
- package/ts/mail/routing/functions.routing.validation.ts +36 -0
- package/ts/mail/routing/interfaces.ts +13 -1
- package/ts/plugins.ts +2 -0
- package/ts/security/classes.rustsecuritybridge.ts +46 -1
- package/ts/security/index.ts +2 -0
package/changelog.md
CHANGED
|
@@ -1,5 +1,56 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-07-21 - 8.1.1
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- add exact accepted-envelope dispatch for durable consumers
|
|
8
|
+
- Snapshot resolved per-recipient actions as immutable JSON-safe plans and replay them without consulting live routes.
|
|
9
|
+
- Scope parsed messages and SMTP sessions per envelope recipient while preserving the accepted raw RFC822 bytes unchanged.
|
|
10
|
+
- Queue forward, process, and deliver actions with durable deterministic idempotency keys and return their queue IDs.
|
|
11
|
+
- Persist bounded replay checkpoints through caller-managed storage; no filesystem persistence is introduced.
|
|
12
|
+
- Add backend-bounded prefix pagination and use it for convergent checkpoint and queue-tombstone cleanup.
|
|
13
|
+
- add exact accepted-envelope dispatch (accepted-envelope-dispatch)
|
|
14
|
+
- Snapshot resolved per-recipient actions as immutable JSON-safe plans for replay without consulting live routes.
|
|
15
|
+
- Queue forward, process, and deliver actions with deterministic durable idempotency keys and return queue IDs.
|
|
16
|
+
- Add accepted-envelope replay checkpoints with bounded cleanup backed by caller-managed storage.
|
|
17
|
+
- Introduce backend-bounded prefix pagination and use it for checkpoint and queue tombstone cleanup.
|
|
18
|
+
|
|
19
|
+
## 2026-07-21 - 8.1.0
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
- add fail-closed inbound storage policies and durable envelope acceptance
|
|
24
|
+
- Add per-domain store/reject fallbacks that run only after explicit recipient routes.
|
|
25
|
+
- Expose one awaited envelope hook with the exact raw message, complete SMTP envelope, resolved routes, typed security verdicts, and attachment count before the SMTP 250 response.
|
|
26
|
+
- Emit typed recipient-rejection observations with truthful local-mailbox and non-hosted-domain responses.
|
|
27
|
+
- expose complete SMTP delivery evidence
|
|
28
|
+
- Preserve lossless outbound attachments across the TypeScript/Rust boundary, including binary payloads, Unicode filenames, content IDs, and hardened MIME parameters.
|
|
29
|
+
- Record structured DATA transfer bytes, write-chunk counts, and duration on SMTP transaction entries.
|
|
30
|
+
- Persist materialized attachment counts on managed queue records with backward-compatible hydration.
|
|
31
|
+
- classify self-MX against the complete listener topology
|
|
32
|
+
- Normalize DNS names and IP literals, follow bounded CNAME chains, compare A/AAAA answers with explicit and dynamic listener identities, and fail closed on indeterminate DNS.
|
|
33
|
+
- Treat configured topology identity providers that return no proof, throw, or time out as indeterminate and perform no SMTP dial.
|
|
34
|
+
- Skip local MX candidates while continuing to eligible backup MX hosts, recording synthetic no-dial attempts for every skipped candidate.
|
|
35
|
+
- add inbound storage policies and durable delivery evidence (mail)
|
|
36
|
+
- Add per-domain inbound store/reject policies with route validation and awaited envelope acceptance context.
|
|
37
|
+
- Preserve outbound attachments across the TypeScript/Rust bridge with hardened MIME parameter handling.
|
|
38
|
+
- Record SMTP DATA transfer statistics and persist queue attachment counts for delivery diagnostics.
|
|
39
|
+
- Classify self-MX candidates against listener topology, skip local MX hosts, and continue to eligible backups.
|
|
40
|
+
- Add a durable delivery-failure outbox for terminal transport and local-topology failures.
|
|
41
|
+
|
|
42
|
+
### Fixes
|
|
43
|
+
|
|
44
|
+
- preserve delivery semantics when retries are exhausted
|
|
45
|
+
- Terminalize unresolved recipients atomically with a separate durable delivery-failure operation.
|
|
46
|
+
- Drain delivery-failure operations in bounded startup and periodic batches with durable retry backoff and idempotent operation IDs.
|
|
47
|
+
- Keep local topology and transport exhaustion out of the SMTP-recipient suppression/bounce evidence path.
|
|
48
|
+
- Make explicit self-MX configuration failures terminal while allowing dynamic or DNS-derived topology to recover on retry.
|
|
49
|
+
- preserve rejection and transfer diagnostics under failure pressure
|
|
50
|
+
- Observe RCPT policy callback exceptions and timeouts exactly once as policy errors before returning SMTP 451.
|
|
51
|
+
- Reserve the structured DATA transfer summary when the bounded SMTP transcript reaches its entry cap.
|
|
52
|
+
- stop the rate-limiter cleanup timer when UnifiedEmailServer shuts down
|
|
53
|
+
|
|
3
54
|
## 2026-07-20 - 8.0.1
|
|
4
55
|
|
|
5
56
|
### Fixes
|
|
Binary file
|
|
Binary file
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartmta',
|
|
6
|
-
version: '8.
|
|
6
|
+
version: '8.1.1',
|
|
7
7
|
description: 'A high-performance, enterprise-grade Mail Transfer Agent (MTA) built from scratch in TypeScript with Rust acceleration.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHlIQUF5SDtDQUN2SSxDQUFBIn0=
|
package/dist_ts/index.d.ts
CHANGED
|
@@ -7,4 +7,10 @@ export declare const smartMtaCapabilities: Readonly<{
|
|
|
7
7
|
readonly callerManagedDkimKeys: true;
|
|
8
8
|
readonly structuredSmtpTransactions: true;
|
|
9
9
|
readonly typedDeliveryFailures: true;
|
|
10
|
+
readonly inboundStorePolicies: true;
|
|
11
|
+
readonly smtpTransferStats: true;
|
|
12
|
+
readonly outboundAttachments: true;
|
|
13
|
+
readonly topologyAwareSelfMx: true;
|
|
14
|
+
readonly durableDeliveryFailureOutbox: true;
|
|
15
|
+
readonly exactAcceptedEnvelopeDispatch: true;
|
|
10
16
|
}>;
|
package/dist_ts/index.js
CHANGED
|
@@ -7,5 +7,11 @@ export const smartMtaCapabilities = Object.freeze({
|
|
|
7
7
|
callerManagedDkimKeys: true,
|
|
8
8
|
structuredSmtpTransactions: true,
|
|
9
9
|
typedDeliveryFailures: true,
|
|
10
|
+
inboundStorePolicies: true,
|
|
11
|
+
smtpTransferStats: true,
|
|
12
|
+
outboundAttachments: true,
|
|
13
|
+
topologyAwareSelfMx: true,
|
|
14
|
+
durableDeliveryFailureOutbox: true,
|
|
15
|
+
exactAcceptedEnvelopeDispatch: true,
|
|
10
16
|
});
|
|
11
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
17
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHlCQUF5QixDQUFDO0FBQ3hDLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUVqRCxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ2hELDBCQUEwQixFQUFFLElBQUk7SUFDaEMscUJBQXFCLEVBQUUsSUFBSTtJQUMzQiwwQkFBMEIsRUFBRSxJQUFJO0lBQ2hDLHFCQUFxQixFQUFFLElBQUk7SUFDM0Isb0JBQW9CLEVBQUUsSUFBSTtJQUMxQixpQkFBaUIsRUFBRSxJQUFJO0lBQ3ZCLG1CQUFtQixFQUFFLElBQUk7SUFDekIsbUJBQW1CLEVBQUUsSUFBSTtJQUN6Qiw0QkFBNEIsRUFBRSxJQUFJO0lBQ2xDLDZCQUE2QixFQUFFLElBQUk7Q0FDM0IsQ0FBQyxDQUFDIn0=
|
|
@@ -24,7 +24,8 @@ export interface IRecipientPermanentFailure {
|
|
|
24
24
|
}
|
|
25
25
|
export interface IBounceOperation {
|
|
26
26
|
operationId: string;
|
|
27
|
-
kind: 'smtpFailure';
|
|
27
|
+
kind: 'smtpFailure' | 'deliveryFailure';
|
|
28
|
+
failureClass?: 'localTopology' | 'transport';
|
|
28
29
|
recipient: string;
|
|
29
30
|
normalizedRecipient: string;
|
|
30
31
|
smtpCode: number;
|
|
@@ -40,8 +41,14 @@ export interface IBounceOperation {
|
|
|
40
41
|
*/
|
|
41
42
|
export interface IQueueItem {
|
|
42
43
|
id: string;
|
|
44
|
+
/** Stable caller-supplied key used to make enqueue replay-safe. */
|
|
45
|
+
idempotencyKey?: string;
|
|
46
|
+
/** Fingerprint of the exact work associated with the idempotency key. */
|
|
47
|
+
idempotencyFingerprint?: string;
|
|
43
48
|
processingMode: EmailProcessingMode;
|
|
44
49
|
processingResult: Email;
|
|
50
|
+
/** Materialized attachment count for queue/detail consumers. */
|
|
51
|
+
attachmentCount?: number;
|
|
45
52
|
route?: IEmailRoute;
|
|
46
53
|
status: QueueItemStatus;
|
|
47
54
|
attempts: number;
|
|
@@ -56,9 +63,15 @@ export interface IQueueItem {
|
|
|
56
63
|
bounceOperations?: IBounceOperation[];
|
|
57
64
|
smtpTransactions?: ISmtpTransactionAttempt[];
|
|
58
65
|
}
|
|
66
|
+
export declare const ACCEPTED_ENVELOPE_IDEMPOTENCY_RETENTION_MS: number;
|
|
59
67
|
export interface IQueueFailureOptions {
|
|
60
68
|
/** Unknown failures default to retryable so temporary internal faults do not lose mail. */
|
|
61
69
|
retryable?: boolean;
|
|
70
|
+
/** Durable work created atomically when unresolved recipients become terminal. */
|
|
71
|
+
terminalFailure?: {
|
|
72
|
+
failureClass: 'localTopology' | 'transport';
|
|
73
|
+
smtpCode?: number;
|
|
74
|
+
};
|
|
62
75
|
}
|
|
63
76
|
export interface IQueueFailureTransition {
|
|
64
77
|
updated: boolean;
|
|
@@ -82,6 +95,14 @@ export interface IQueueOptions {
|
|
|
82
95
|
baseRetryDelay?: number;
|
|
83
96
|
maxRetryDelay?: number;
|
|
84
97
|
}
|
|
98
|
+
export interface IQueueEnqueueOptions {
|
|
99
|
+
/** Stable key that resolves to one deterministic queue item id. */
|
|
100
|
+
idempotencyKey?: string;
|
|
101
|
+
/** Required with idempotencyKey to reject reuse for different work. */
|
|
102
|
+
idempotencyFingerprint?: string;
|
|
103
|
+
/** Fail closed unless the queue is backed by managed blob storage. */
|
|
104
|
+
requireDurable?: boolean;
|
|
105
|
+
}
|
|
85
106
|
export interface IQueueStats {
|
|
86
107
|
queueSize: number;
|
|
87
108
|
status: {
|
|
@@ -115,12 +136,25 @@ export declare class UnifiedDeliveryQueue extends EventEmitter {
|
|
|
115
136
|
private totalProcessed;
|
|
116
137
|
private ownsManagedPrefix;
|
|
117
138
|
private lifecycleState;
|
|
139
|
+
private readonly idempotentEnqueueFlights;
|
|
140
|
+
private idempotencyTombstoneCleanupCursor?;
|
|
118
141
|
/**
|
|
119
142
|
* Create a new unified delivery queue
|
|
120
143
|
* @param options Queue options
|
|
121
144
|
*/
|
|
122
145
|
constructor(options: IQueueOptions);
|
|
123
146
|
private assertMutable;
|
|
147
|
+
/** Whether queue entries are committed through caller-managed blob storage. */
|
|
148
|
+
hasManagedStorage(): boolean;
|
|
149
|
+
/** Whether managed storage can list a backend-bounded page of keys. */
|
|
150
|
+
hasPaginatedManagedStorage(): boolean;
|
|
151
|
+
private idempotentQueueId;
|
|
152
|
+
private idempotencyTombstonePrefix;
|
|
153
|
+
private idempotencyTombstoneKey;
|
|
154
|
+
private readIdempotencyTombstone;
|
|
155
|
+
private parseIdempotencyTombstone;
|
|
156
|
+
private persistIdempotencyTombstone;
|
|
157
|
+
private cleanupExpiredIdempotencyTombstones;
|
|
124
158
|
private createInitialRecipientStates;
|
|
125
159
|
private createBounceOperationId;
|
|
126
160
|
/**
|
|
@@ -149,7 +183,8 @@ export declare class UnifiedDeliveryQueue extends EventEmitter {
|
|
|
149
183
|
* @param mode Processing mode
|
|
150
184
|
* @param route Email route
|
|
151
185
|
*/
|
|
152
|
-
enqueue(processingResult: Email, mode: EmailProcessingMode, route?: IEmailRoute): Promise<string>;
|
|
186
|
+
enqueue(processingResult: Email, mode: EmailProcessingMode, route?: IEmailRoute, enqueueOptions?: IQueueEnqueueOptions): Promise<string>;
|
|
187
|
+
private enqueueNew;
|
|
153
188
|
/**
|
|
154
189
|
* Get an item from the queue
|
|
155
190
|
* @param id Item ID
|
|
@@ -189,7 +224,12 @@ export declare class UnifiedDeliveryQueue extends EventEmitter {
|
|
|
189
224
|
permanentFailures: string[];
|
|
190
225
|
};
|
|
191
226
|
/** Includes terminal queue items because bounce work outlives delivery status. */
|
|
192
|
-
listPendingBounceOperations(now?: Date): Array<{
|
|
227
|
+
listPendingBounceOperations(now?: Date, limitArg?: number): Array<{
|
|
228
|
+
itemId: string;
|
|
229
|
+
operation: IBounceOperation;
|
|
230
|
+
}>;
|
|
231
|
+
/** Durable terminal-delivery notices. These never enter SMTP recipient suppression. */
|
|
232
|
+
listPendingDeliveryFailureOperations(now?: Date, limitArg?: number): Array<{
|
|
193
233
|
itemId: string;
|
|
194
234
|
operation: IBounceOperation;
|
|
195
235
|
}>;
|