@push.rocks/smartmta 6.5.2 → 8.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.
Files changed (84) hide show
  1. package/changelog.md +40 -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/functions.errors.d.ts +3 -0
  6. package/dist_ts/functions.errors.js +8 -0
  7. package/dist_ts/index.d.ts +3 -0
  8. package/dist_ts/index.js +4 -1
  9. package/dist_ts/mail/core/classes.bouncemanager.d.ts +16 -12
  10. package/dist_ts/mail/core/classes.bouncemanager.js +146 -129
  11. package/dist_ts/mail/core/classes.email.js +15 -13
  12. package/dist_ts/mail/core/classes.emailvalidator.d.ts +3 -3
  13. package/dist_ts/mail/core/classes.emailvalidator.js +7 -5
  14. package/dist_ts/mail/core/classes.templatemanager.d.ts +10 -6
  15. package/dist_ts/mail/core/classes.templatemanager.js +35 -51
  16. package/dist_ts/mail/delivery/classes.delivery.queue.d.ts +92 -22
  17. package/dist_ts/mail/delivery/classes.delivery.queue.js +738 -151
  18. package/dist_ts/mail/delivery/classes.delivery.system.d.ts +13 -7
  19. package/dist_ts/mail/delivery/classes.delivery.system.js +458 -145
  20. package/dist_ts/mail/delivery/classes.unified.rate.limiter.js +9 -8
  21. package/dist_ts/mail/delivery/functions.safe-observers.d.ts +10 -0
  22. package/dist_ts/mail/delivery/functions.safe-observers.js +37 -0
  23. package/dist_ts/mail/delivery/interfaces.d.ts +21 -0
  24. package/dist_ts/mail/delivery/interfaces.js +1 -1
  25. package/dist_ts/mail/interfaces.storage.d.ts +37 -6
  26. package/dist_ts/mail/interfaces.storage.js +33 -3
  27. package/dist_ts/mail/routing/classes.dkim.manager.d.ts +10 -6
  28. package/dist_ts/mail/routing/classes.dkim.manager.js +47 -31
  29. package/dist_ts/mail/routing/classes.dns.manager.d.ts +7 -5
  30. package/dist_ts/mail/routing/classes.dns.manager.js +22 -11
  31. package/dist_ts/mail/routing/classes.email.action.executor.d.ts +2 -1
  32. package/dist_ts/mail/routing/classes.email.action.executor.js +45 -16
  33. package/dist_ts/mail/routing/classes.email.router.d.ts +5 -2
  34. package/dist_ts/mail/routing/classes.email.router.js +17 -12
  35. package/dist_ts/mail/routing/classes.unified.email.server.d.ts +12 -6
  36. package/dist_ts/mail/routing/classes.unified.email.server.js +69 -78
  37. package/dist_ts/mail/routing/interfaces.d.ts +0 -2
  38. package/dist_ts/mail/security/classes.dkimcreator.d.ts +22 -45
  39. package/dist_ts/mail/security/classes.dkimcreator.js +93 -296
  40. package/dist_ts/mail/security/classes.spfverifier.js +5 -3
  41. package/dist_ts/paths.d.ts +0 -12
  42. package/dist_ts/paths.js +3 -36
  43. package/dist_ts/plugins.d.ts +2 -5
  44. package/dist_ts/plugins.js +3 -6
  45. package/dist_ts/security/classes.contentscanner.js +14 -12
  46. package/dist_ts/security/classes.ipreputationchecker.d.ts +9 -6
  47. package/dist_ts/security/classes.ipreputationchecker.js +42 -93
  48. package/dist_ts/security/classes.rustsecuritybridge.d.ts +52 -4
  49. package/dist_ts/security/classes.rustsecuritybridge.js +201 -4
  50. package/dist_ts/security/classes.securitylogger.js +7 -5
  51. package/dist_ts/security/index.d.ts +1 -1
  52. package/dist_ts/security/index.js +2 -2
  53. package/package.json +8 -9
  54. package/readme.hints.md +4 -3
  55. package/readme.md +50 -18
  56. package/readme.plan.md +6 -0
  57. package/ts/00_commitinfo_data.ts +1 -1
  58. package/ts/functions.errors.ts +8 -0
  59. package/ts/index.ts +3 -0
  60. package/ts/mail/core/classes.bouncemanager.ts +188 -155
  61. package/ts/mail/core/classes.email.ts +20 -14
  62. package/ts/mail/core/classes.emailvalidator.ts +9 -7
  63. package/ts/mail/core/classes.templatemanager.ts +42 -57
  64. package/ts/mail/delivery/classes.delivery.queue.ts +996 -185
  65. package/ts/mail/delivery/classes.delivery.system.ts +583 -170
  66. package/ts/mail/delivery/classes.unified.rate.limiter.ts +9 -8
  67. package/ts/mail/delivery/functions.safe-observers.ts +45 -0
  68. package/ts/mail/delivery/interfaces.ts +27 -1
  69. package/ts/mail/interfaces.storage.ts +64 -10
  70. package/ts/mail/routing/classes.dkim.manager.ts +65 -40
  71. package/ts/mail/routing/classes.dns.manager.ts +39 -16
  72. package/ts/mail/routing/classes.email.action.executor.ts +64 -17
  73. package/ts/mail/routing/classes.email.router.ts +20 -13
  74. package/ts/mail/routing/classes.unified.email.server.ts +107 -86
  75. package/ts/mail/routing/interfaces.ts +0 -2
  76. package/ts/mail/security/classes.dkimcreator.ts +150 -355
  77. package/ts/mail/security/classes.spfverifier.ts +4 -2
  78. package/ts/paths.ts +2 -41
  79. package/ts/plugins.ts +1 -6
  80. package/ts/security/classes.contentscanner.ts +14 -12
  81. package/ts/security/classes.ipreputationchecker.ts +46 -99
  82. package/ts/security/classes.rustsecuritybridge.ts +272 -6
  83. package/ts/security/classes.securitylogger.ts +6 -4
  84. package/ts/security/index.ts +5 -1
@@ -1,7 +1,6 @@
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, type IEmailOptions, type IAttachment } from './classes.email.js';
3
+ import type { IBlobStorageManager, IStorageManager } from '../interfaces.storage.js';
5
4
 
6
5
  /**
7
6
  * Email template type definition
@@ -18,7 +17,8 @@ export interface IEmailTemplate<T = any> {
18
17
  sampleData?: T;
19
18
  attachments?: Array<{
20
19
  name: string;
21
- path: string;
20
+ contentBase64?: string;
21
+ storageKey?: string;
22
22
  contentType?: string;
23
23
  }>;
24
24
  }
@@ -45,6 +45,8 @@ export enum TemplateCategory {
45
45
  */
46
46
  export class TemplateManager {
47
47
  private templates: Map<string, IEmailTemplate> = new Map();
48
+ private readonly templateStorage?: IStorageManager;
49
+ private readonly attachmentStorage?: IBlobStorageManager;
48
50
  private defaultConfig: {
49
51
  from: string;
50
52
  replyTo?: string;
@@ -57,7 +59,12 @@ export class TemplateManager {
57
59
  replyTo?: string;
58
60
  footerHtml?: string;
59
61
  footerText?: string;
62
+ }, storage?: {
63
+ templateStorage?: IStorageManager;
64
+ attachmentStorage?: IBlobStorageManager;
60
65
  }) {
66
+ this.templateStorage = storage?.templateStorage;
67
+ this.attachmentStorage = storage?.attachmentStorage;
61
68
  // Set default configuration
62
69
  this.defaultConfig = {
63
70
  from: defaultConfig?.from || 'noreply@mail.lossless.com',
@@ -212,25 +219,26 @@ export class TemplateManager {
212
219
 
213
220
  if (template.attachments && template.attachments.length > 0) {
214
221
  for (const attachment of template.attachments) {
215
- try {
216
- const attachmentPath = plugins.path.isAbsolute(attachment.path)
217
- ? attachment.path
218
- : plugins.path.join(paths.MtaAttachmentsDir, attachment.path);
219
-
220
- // Read the file
221
- const fileBuffer = await plugins.fs.promises.readFile(attachmentPath);
222
-
223
- attachments.push({
224
- filename: attachment.name,
225
- content: fileBuffer,
226
- contentType: attachment.contentType || 'application/octet-stream'
227
- });
228
- } catch (error) {
229
- logger.log('error', `Failed to add attachment '${attachment.name}': ${error.message}`);
222
+ let content: Buffer | null = attachment.contentBase64
223
+ ? Buffer.from(attachment.contentBase64, 'base64')
224
+ : null;
225
+ if (!content && attachment.storageKey) {
226
+ if (!this.attachmentStorage) {
227
+ throw new Error(`Template attachment ${attachment.name} requires blob storage`);
228
+ }
229
+ content = await this.attachmentStorage.get(attachment.storageKey);
230
+ }
231
+ if (!content) {
232
+ throw new Error(`Template attachment ${attachment.name} has no content`);
230
233
  }
234
+ attachments.push({
235
+ filename: attachment.name,
236
+ content,
237
+ contentType: attachment.contentType || 'application/octet-stream',
238
+ });
231
239
  }
232
240
  }
233
-
241
+
234
242
  // Create Email instance with template content
235
243
  const emailOptions: IEmailOptions = {
236
244
  from: template.from || this.defaultConfig.from,
@@ -277,44 +285,21 @@ export class TemplateManager {
277
285
  }
278
286
 
279
287
 
280
- /**
281
- * Load templates from a directory
282
- * @param directory The directory containing template JSON files
283
- */
284
- public async loadTemplatesFromDirectory(directory: string): Promise<void> {
285
- try {
286
- // Ensure directory exists
287
- if (!plugins.fs.existsSync(directory)) {
288
- logger.log('error', `Template directory does not exist: ${directory}`);
289
- return;
290
- }
291
-
292
- // Get all JSON files
293
- const files = plugins.fs.readdirSync(directory)
294
- .filter(file => file.endsWith('.json'));
295
-
296
- for (const file of files) {
297
- try {
298
- const filePath = plugins.path.join(directory, file);
299
- const content = plugins.fs.readFileSync(filePath, 'utf8');
300
- const template = JSON.parse(content) as IEmailTemplate;
301
-
302
- // Validate template
303
- if (!template.id || !template.subject || (!template.bodyHtml && !template.bodyText)) {
304
- logger.log('warn', `Invalid template in ${file}: missing required fields`);
305
- continue;
306
- }
307
-
308
- this.registerTemplate(template);
309
- } catch (error) {
310
- logger.log('error', `Error loading template from ${file}: ${error.message}`);
311
- }
288
+ /** Load JSON templates from the configured managed text store. */
289
+ public async loadTemplatesFromStorage(prefix = '/email/templates/'): Promise<void> {
290
+ if (!this.templateStorage) {
291
+ throw new Error('Template storage is not configured');
292
+ }
293
+ const keys = await this.templateStorage.list(prefix);
294
+ for (const key of keys.filter((candidate) => candidate.endsWith('.json'))) {
295
+ const content = await this.templateStorage.get(key);
296
+ if (!content) continue;
297
+ const template = JSON.parse(content) as IEmailTemplate;
298
+ if (!template.id || !template.subject || (!template.bodyHtml && !template.bodyText)) {
299
+ throw new Error(`Invalid template in ${key}: missing required fields`);
312
300
  }
313
-
314
- logger.log('info', `Loaded ${this.templates.size} email templates`);
315
- } catch (error) {
316
- logger.log('error', `Failed to load templates from directory: ${error.message}`);
317
- throw error;
301
+ this.registerTemplate(template);
318
302
  }
319
303
  }
320
- }
304
+
305
+ }