@push.rocks/smartmta 6.5.1 → 7.0.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.
- package/changelog.md +20 -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 +3 -0
- package/dist_ts/index.js +4 -1
- package/dist_ts/mail/core/classes.bouncemanager.d.ts +5 -12
- package/dist_ts/mail/core/classes.bouncemanager.js +27 -92
- package/dist_ts/mail/core/classes.email.js +2 -2
- package/dist_ts/mail/core/classes.templatemanager.d.ts +10 -6
- package/dist_ts/mail/core/classes.templatemanager.js +35 -51
- package/dist_ts/mail/delivery/classes.delivery.queue.d.ts +15 -20
- package/dist_ts/mail/delivery/classes.delivery.queue.js +196 -114
- package/dist_ts/mail/delivery/classes.delivery.system.js +5 -5
- package/dist_ts/mail/interfaces.storage.d.ts +37 -6
- package/dist_ts/mail/interfaces.storage.js +33 -3
- package/dist_ts/mail/routing/classes.dkim.manager.d.ts +2 -2
- package/dist_ts/mail/routing/classes.dkim.manager.js +2 -3
- package/dist_ts/mail/routing/classes.dns.manager.d.ts +2 -2
- package/dist_ts/mail/routing/classes.dns.manager.js +1 -1
- package/dist_ts/mail/routing/classes.email.router.d.ts +2 -2
- package/dist_ts/mail/routing/classes.email.router.js +4 -5
- package/dist_ts/mail/routing/classes.unified.email.server.d.ts +8 -6
- package/dist_ts/mail/routing/classes.unified.email.server.js +12 -41
- package/dist_ts/mail/routing/interfaces.d.ts +0 -2
- package/dist_ts/mail/security/classes.dkimcreator.d.ts +15 -45
- package/dist_ts/mail/security/classes.dkimcreator.js +66 -294
- package/dist_ts/paths.d.ts +0 -12
- package/dist_ts/paths.js +3 -36
- package/dist_ts/plugins.d.ts +2 -5
- package/dist_ts/plugins.js +3 -6
- package/dist_ts/security/classes.contentscanner.js +1 -2
- package/dist_ts/security/classes.ipreputationchecker.d.ts +6 -6
- package/dist_ts/security/classes.ipreputationchecker.js +24 -84
- package/dist_ts/security/classes.rustsecuritybridge.d.ts +3 -3
- package/package.json +2 -3
- package/readme.md +12 -6
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/index.ts +4 -0
- package/ts/mail/core/classes.bouncemanager.ts +31 -110
- package/ts/mail/core/classes.email.ts +1 -1
- package/ts/mail/core/classes.templatemanager.ts +42 -57
- package/ts/mail/delivery/classes.delivery.queue.ts +264 -135
- package/ts/mail/delivery/classes.delivery.system.ts +7 -5
- package/ts/mail/interfaces.storage.ts +64 -10
- package/ts/mail/routing/classes.dkim.manager.ts +3 -3
- package/ts/mail/routing/classes.dns.manager.ts +3 -3
- package/ts/mail/routing/classes.email.router.ts +6 -6
- package/ts/mail/routing/classes.unified.email.server.ts +23 -44
- package/ts/mail/routing/interfaces.ts +0 -2
- package/ts/mail/security/classes.dkimcreator.ts +104 -352
- package/ts/paths.ts +2 -41
- package/ts/plugins.ts +1 -6
- package/ts/security/classes.contentscanner.ts +0 -1
- package/ts/security/classes.ipreputationchecker.ts +26 -90
- package/ts/security/classes.rustsecuritybridge.ts +3 -3
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import * as plugins from '../../plugins.js';
|
|
2
|
-
import * as paths from '../../paths.js';
|
|
3
1
|
import { logger } from '../../logger.js';
|
|
4
2
|
import { Email } from './classes.email.js';
|
|
5
3
|
/**
|
|
@@ -17,8 +15,12 @@ export var TemplateCategory;
|
|
|
17
15
|
*/
|
|
18
16
|
export class TemplateManager {
|
|
19
17
|
templates = new Map();
|
|
18
|
+
templateStorage;
|
|
19
|
+
attachmentStorage;
|
|
20
20
|
defaultConfig;
|
|
21
|
-
constructor(defaultConfig) {
|
|
21
|
+
constructor(defaultConfig, storage) {
|
|
22
|
+
this.templateStorage = storage?.templateStorage;
|
|
23
|
+
this.attachmentStorage = storage?.attachmentStorage;
|
|
22
24
|
// Set default configuration
|
|
23
25
|
this.defaultConfig = {
|
|
24
26
|
from: defaultConfig?.from || 'noreply@mail.lossless.com',
|
|
@@ -149,21 +151,23 @@ export class TemplateManager {
|
|
|
149
151
|
const attachments = [];
|
|
150
152
|
if (template.attachments && template.attachments.length > 0) {
|
|
151
153
|
for (const attachment of template.attachments) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
content: fileBuffer,
|
|
161
|
-
contentType: attachment.contentType || 'application/octet-stream'
|
|
162
|
-
});
|
|
154
|
+
let content = attachment.contentBase64
|
|
155
|
+
? Buffer.from(attachment.contentBase64, 'base64')
|
|
156
|
+
: null;
|
|
157
|
+
if (!content && attachment.storageKey) {
|
|
158
|
+
if (!this.attachmentStorage) {
|
|
159
|
+
throw new Error(`Template attachment ${attachment.name} requires blob storage`);
|
|
160
|
+
}
|
|
161
|
+
content = await this.attachmentStorage.get(attachment.storageKey);
|
|
163
162
|
}
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
if (!content) {
|
|
164
|
+
throw new Error(`Template attachment ${attachment.name} has no content`);
|
|
166
165
|
}
|
|
166
|
+
attachments.push({
|
|
167
|
+
filename: attachment.name,
|
|
168
|
+
content,
|
|
169
|
+
contentType: attachment.contentType || 'application/octet-stream',
|
|
170
|
+
});
|
|
167
171
|
}
|
|
168
172
|
}
|
|
169
173
|
// Create Email instance with template content
|
|
@@ -199,42 +203,22 @@ export class TemplateManager {
|
|
|
199
203
|
const email = await this.prepareEmail(templateId, context);
|
|
200
204
|
return email.toRFC822String(context);
|
|
201
205
|
}
|
|
202
|
-
/**
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
async loadTemplatesFromDirectory(directory) {
|
|
207
|
-
try {
|
|
208
|
-
// Ensure directory exists
|
|
209
|
-
if (!plugins.fs.existsSync(directory)) {
|
|
210
|
-
logger.log('error', `Template directory does not exist: ${directory}`);
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
// Get all JSON files
|
|
214
|
-
const files = plugins.fs.readdirSync(directory)
|
|
215
|
-
.filter(file => file.endsWith('.json'));
|
|
216
|
-
for (const file of files) {
|
|
217
|
-
try {
|
|
218
|
-
const filePath = plugins.path.join(directory, file);
|
|
219
|
-
const content = plugins.fs.readFileSync(filePath, 'utf8');
|
|
220
|
-
const template = JSON.parse(content);
|
|
221
|
-
// Validate template
|
|
222
|
-
if (!template.id || !template.subject || (!template.bodyHtml && !template.bodyText)) {
|
|
223
|
-
logger.log('warn', `Invalid template in ${file}: missing required fields`);
|
|
224
|
-
continue;
|
|
225
|
-
}
|
|
226
|
-
this.registerTemplate(template);
|
|
227
|
-
}
|
|
228
|
-
catch (error) {
|
|
229
|
-
logger.log('error', `Error loading template from ${file}: ${error.message}`);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
logger.log('info', `Loaded ${this.templates.size} email templates`);
|
|
206
|
+
/** Load JSON templates from the configured managed text store. */
|
|
207
|
+
async loadTemplatesFromStorage(prefix = '/email/templates/') {
|
|
208
|
+
if (!this.templateStorage) {
|
|
209
|
+
throw new Error('Template storage is not configured');
|
|
233
210
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
211
|
+
const keys = await this.templateStorage.list(prefix);
|
|
212
|
+
for (const key of keys.filter((candidate) => candidate.endsWith('.json'))) {
|
|
213
|
+
const content = await this.templateStorage.get(key);
|
|
214
|
+
if (!content)
|
|
215
|
+
continue;
|
|
216
|
+
const template = JSON.parse(content);
|
|
217
|
+
if (!template.id || !template.subject || (!template.bodyHtml && !template.bodyText)) {
|
|
218
|
+
throw new Error(`Invalid template in ${key}: missing required fields`);
|
|
219
|
+
}
|
|
220
|
+
this.registerTemplate(template);
|
|
237
221
|
}
|
|
238
222
|
}
|
|
239
223
|
}
|
|
240
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
224
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy50ZW1wbGF0ZW1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9tYWlsL2NvcmUvY2xhc3Nlcy50ZW1wbGF0ZW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxLQUFLLEVBQXdDLE1BQU0sb0JBQW9CLENBQUM7QUErQmpGOztHQUVHO0FBQ0gsTUFBTSxDQUFOLElBQVksZ0JBS1g7QUFMRCxXQUFZLGdCQUFnQjtJQUMxQixpREFBNkIsQ0FBQTtJQUM3QixtREFBK0IsQ0FBQTtJQUMvQiwyQ0FBdUIsQ0FBQTtJQUN2QixxQ0FBaUIsQ0FBQTtBQUNuQixDQUFDLEVBTFcsZ0JBQWdCLEtBQWhCLGdCQUFnQixRQUszQjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFDbEIsU0FBUyxHQUFnQyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQzFDLGVBQWUsQ0FBbUI7SUFDbEMsaUJBQWlCLENBQXVCO0lBQ2pELGFBQWEsQ0FLbkI7SUFFRixZQUFZLGFBS1gsRUFBRSxPQUdGO1FBQ0MsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLEVBQUUsZUFBZSxDQUFDO1FBQ2hELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxPQUFPLEVBQUUsaUJBQWlCLENBQUM7UUFDcEQsNEJBQTRCO1FBQzVCLElBQUksQ0FBQyxhQUFhLEdBQUc7WUFDbkIsSUFBSSxFQUFFLGFBQWEsRUFBRSxJQUFJLElBQUksMkJBQTJCO1lBQ3hELE9BQU8sRUFBRSxhQUFhLEVBQUUsT0FBTztZQUMvQixVQUFVLEVBQUUsYUFBYSxFQUFFLFVBQVUsSUFBSSxFQUFFO1lBQzNDLFVBQVUsRUFBRSxhQUFhLEVBQUUsVUFBVSxJQUFJLEVBQUU7U0FDNUMsQ0FBQztRQUVGLHFDQUFxQztRQUNyQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztJ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
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
|
+
import type { IBlobStorageManager } from '../interfaces.storage.js';
|
|
2
3
|
import { type EmailProcessingMode } from './interfaces.js';
|
|
3
4
|
import type { IEmailRoute } from '../routing/interfaces.js';
|
|
5
|
+
import { Email } from '../core/classes.email.js';
|
|
4
6
|
/**
|
|
5
7
|
* Queue item status
|
|
6
8
|
*/
|
|
@@ -11,7 +13,7 @@ export type QueueItemStatus = 'pending' | 'processing' | 'delivered' | 'failed'
|
|
|
11
13
|
export interface IQueueItem {
|
|
12
14
|
id: string;
|
|
13
15
|
processingMode: EmailProcessingMode;
|
|
14
|
-
processingResult:
|
|
16
|
+
processingResult: Email;
|
|
15
17
|
route?: IEmailRoute;
|
|
16
18
|
status: QueueItemStatus;
|
|
17
19
|
attempts: number;
|
|
@@ -25,8 +27,11 @@ export interface IQueueItem {
|
|
|
25
27
|
* Queue options interface
|
|
26
28
|
*/
|
|
27
29
|
export interface IQueueOptions {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
/** Persistence is always an explicit caller choice. */
|
|
31
|
+
storageMode: 'memory' | 'managed';
|
|
32
|
+
/** Required when storageMode is managed. */
|
|
33
|
+
storageManager?: IBlobStorageManager;
|
|
34
|
+
storagePrefix?: string;
|
|
30
35
|
checkInterval?: number;
|
|
31
36
|
maxQueueSize?: number;
|
|
32
37
|
maxPerDestination?: number;
|
|
@@ -34,9 +39,6 @@ export interface IQueueOptions {
|
|
|
34
39
|
baseRetryDelay?: number;
|
|
35
40
|
maxRetryDelay?: number;
|
|
36
41
|
}
|
|
37
|
-
/**
|
|
38
|
-
* Queue statistics interface
|
|
39
|
-
*/
|
|
40
42
|
export interface IQueueStats {
|
|
41
43
|
queueSize: number;
|
|
42
44
|
status: {
|
|
@@ -95,7 +97,7 @@ export declare class UnifiedDeliveryQueue extends EventEmitter {
|
|
|
95
97
|
* @param mode Processing mode
|
|
96
98
|
* @param route Email route
|
|
97
99
|
*/
|
|
98
|
-
enqueue(processingResult:
|
|
100
|
+
enqueue(processingResult: Email, mode: EmailProcessingMode, route?: IEmailRoute): Promise<string>;
|
|
99
101
|
/**
|
|
100
102
|
* Get an item from the queue
|
|
101
103
|
* @param id Item ID
|
|
@@ -123,20 +125,13 @@ export declare class UnifiedDeliveryQueue extends EventEmitter {
|
|
|
123
125
|
* @param id Item ID
|
|
124
126
|
*/
|
|
125
127
|
removeItem(id: string): Promise<boolean>;
|
|
126
|
-
|
|
127
|
-
* Persist an item to disk
|
|
128
|
-
* @param item Item to persist
|
|
129
|
-
*/
|
|
128
|
+
private storageKey;
|
|
130
129
|
private persistItem;
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
private
|
|
136
|
-
/**
|
|
137
|
-
* Load queue items from disk
|
|
138
|
-
*/
|
|
139
|
-
private loadFromDisk;
|
|
130
|
+
private serializeItem;
|
|
131
|
+
private applyPersistedMutation;
|
|
132
|
+
private removeItemFromStorage;
|
|
133
|
+
private deserializeItem;
|
|
134
|
+
private loadFromStorage;
|
|
140
135
|
/**
|
|
141
136
|
* Update queue statistics
|
|
142
137
|
*/
|