@push.rocks/smartmta 5.1.2 → 5.2.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 (99) hide show
  1. package/changelog.md +14 -0
  2. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  3. package/dist_ts/00_commitinfo_data.js +9 -0
  4. package/dist_ts/index.d.ts +3 -0
  5. package/dist_ts/index.js +4 -0
  6. package/dist_ts/logger.d.ts +17 -0
  7. package/dist_ts/logger.js +76 -0
  8. package/dist_ts/mail/core/classes.bouncemanager.d.ts +185 -0
  9. package/dist_ts/mail/core/classes.bouncemanager.js +569 -0
  10. package/dist_ts/mail/core/classes.email.d.ts +291 -0
  11. package/dist_ts/mail/core/classes.email.js +802 -0
  12. package/dist_ts/mail/core/classes.emailvalidator.d.ts +61 -0
  13. package/dist_ts/mail/core/classes.emailvalidator.js +184 -0
  14. package/dist_ts/mail/core/classes.templatemanager.d.ts +95 -0
  15. package/dist_ts/mail/core/classes.templatemanager.js +240 -0
  16. package/dist_ts/mail/core/index.d.ts +4 -0
  17. package/dist_ts/mail/core/index.js +6 -0
  18. package/dist_ts/mail/delivery/classes.delivery.queue.d.ts +163 -0
  19. package/dist_ts/mail/delivery/classes.delivery.queue.js +488 -0
  20. package/dist_ts/mail/delivery/classes.delivery.system.d.ts +160 -0
  21. package/dist_ts/mail/delivery/classes.delivery.system.js +630 -0
  22. package/dist_ts/mail/delivery/classes.unified.rate.limiter.d.ts +200 -0
  23. package/dist_ts/mail/delivery/classes.unified.rate.limiter.js +820 -0
  24. package/dist_ts/mail/delivery/index.d.ts +4 -0
  25. package/dist_ts/mail/delivery/index.js +6 -0
  26. package/dist_ts/mail/delivery/interfaces.d.ts +140 -0
  27. package/dist_ts/mail/delivery/interfaces.js +17 -0
  28. package/dist_ts/mail/index.d.ts +7 -0
  29. package/dist_ts/mail/index.js +12 -0
  30. package/dist_ts/mail/routing/classes.dkim.manager.d.ts +25 -0
  31. package/dist_ts/mail/routing/classes.dkim.manager.js +127 -0
  32. package/dist_ts/mail/routing/classes.dns.manager.d.ts +79 -0
  33. package/dist_ts/mail/routing/classes.dns.manager.js +415 -0
  34. package/dist_ts/mail/routing/classes.domain.registry.d.ts +54 -0
  35. package/dist_ts/mail/routing/classes.domain.registry.js +119 -0
  36. package/dist_ts/mail/routing/classes.email.action.executor.d.ts +33 -0
  37. package/dist_ts/mail/routing/classes.email.action.executor.js +137 -0
  38. package/dist_ts/mail/routing/classes.email.router.d.ts +171 -0
  39. package/dist_ts/mail/routing/classes.email.router.js +494 -0
  40. package/dist_ts/mail/routing/classes.unified.email.server.d.ts +241 -0
  41. package/dist_ts/mail/routing/classes.unified.email.server.js +935 -0
  42. package/dist_ts/mail/routing/index.d.ts +7 -0
  43. package/dist_ts/mail/routing/index.js +9 -0
  44. package/dist_ts/mail/routing/interfaces.d.ts +187 -0
  45. package/dist_ts/mail/routing/interfaces.js +2 -0
  46. package/dist_ts/mail/security/classes.dkimcreator.d.ts +72 -0
  47. package/dist_ts/mail/security/classes.dkimcreator.js +360 -0
  48. package/dist_ts/mail/security/classes.spfverifier.d.ts +62 -0
  49. package/dist_ts/mail/security/classes.spfverifier.js +87 -0
  50. package/dist_ts/mail/security/index.d.ts +2 -0
  51. package/dist_ts/mail/security/index.js +4 -0
  52. package/dist_ts/paths.d.ts +14 -0
  53. package/dist_ts/paths.js +39 -0
  54. package/dist_ts/plugins.d.ts +24 -0
  55. package/dist_ts/plugins.js +28 -0
  56. package/dist_ts/security/classes.contentscanner.d.ts +130 -0
  57. package/dist_ts/security/classes.contentscanner.js +338 -0
  58. package/dist_ts/security/classes.ipreputationchecker.d.ts +73 -0
  59. package/dist_ts/security/classes.ipreputationchecker.js +263 -0
  60. package/dist_ts/security/classes.rustsecuritybridge.d.ts +398 -0
  61. package/dist_ts/security/classes.rustsecuritybridge.js +484 -0
  62. package/dist_ts/security/classes.securitylogger.d.ts +140 -0
  63. package/dist_ts/security/classes.securitylogger.js +235 -0
  64. package/dist_ts/security/index.d.ts +4 -0
  65. package/dist_ts/security/index.js +5 -0
  66. package/package.json +6 -1
  67. package/readme.md +52 -9
  68. package/ts/00_commitinfo_data.ts +8 -0
  69. package/ts/index.ts +3 -0
  70. package/ts/logger.ts +91 -0
  71. package/ts/mail/core/classes.bouncemanager.ts +731 -0
  72. package/ts/mail/core/classes.email.ts +942 -0
  73. package/ts/mail/core/classes.emailvalidator.ts +239 -0
  74. package/ts/mail/core/classes.templatemanager.ts +320 -0
  75. package/ts/mail/core/index.ts +5 -0
  76. package/ts/mail/delivery/classes.delivery.queue.ts +645 -0
  77. package/ts/mail/delivery/classes.delivery.system.ts +816 -0
  78. package/ts/mail/delivery/classes.unified.rate.limiter.ts +1053 -0
  79. package/ts/mail/delivery/index.ts +5 -0
  80. package/ts/mail/delivery/interfaces.ts +167 -0
  81. package/ts/mail/index.ts +17 -0
  82. package/ts/mail/routing/classes.dkim.manager.ts +157 -0
  83. package/ts/mail/routing/classes.dns.manager.ts +573 -0
  84. package/ts/mail/routing/classes.domain.registry.ts +139 -0
  85. package/ts/mail/routing/classes.email.action.executor.ts +175 -0
  86. package/ts/mail/routing/classes.email.router.ts +575 -0
  87. package/ts/mail/routing/classes.unified.email.server.ts +1207 -0
  88. package/ts/mail/routing/index.ts +9 -0
  89. package/ts/mail/routing/interfaces.ts +202 -0
  90. package/ts/mail/security/classes.dkimcreator.ts +447 -0
  91. package/ts/mail/security/classes.spfverifier.ts +126 -0
  92. package/ts/mail/security/index.ts +3 -0
  93. package/ts/paths.ts +48 -0
  94. package/ts/plugins.ts +53 -0
  95. package/ts/security/classes.contentscanner.ts +400 -0
  96. package/ts/security/classes.ipreputationchecker.ts +315 -0
  97. package/ts/security/classes.rustsecuritybridge.ts +943 -0
  98. package/ts/security/classes.securitylogger.ts +299 -0
  99. package/ts/security/index.ts +40 -0
@@ -0,0 +1,61 @@
1
+ export interface IEmailValidationResult {
2
+ isValid: boolean;
3
+ hasMx: boolean;
4
+ hasSpamMarkings: boolean;
5
+ score: number;
6
+ details?: {
7
+ formatValid?: boolean;
8
+ mxRecords?: string[];
9
+ disposable?: boolean;
10
+ role?: boolean;
11
+ spamIndicators?: string[];
12
+ errorMessage?: string;
13
+ };
14
+ }
15
+ /**
16
+ * Advanced email validator class using smartmail's capabilities
17
+ */
18
+ export declare class EmailValidator {
19
+ private validator;
20
+ private dnsCache;
21
+ constructor(options?: {
22
+ maxCacheSize?: number;
23
+ cacheTTL?: number;
24
+ });
25
+ /**
26
+ * Validates an email address using comprehensive checks
27
+ * @param email The email to validate
28
+ * @param options Validation options
29
+ * @returns Validation result with details
30
+ */
31
+ validate(email: string, options?: {
32
+ checkMx?: boolean;
33
+ checkDisposable?: boolean;
34
+ checkRole?: boolean;
35
+ checkSyntaxOnly?: boolean;
36
+ }): Promise<IEmailValidationResult>;
37
+ /**
38
+ * Gets MX records for a domain with caching
39
+ * @param domain Domain to check
40
+ * @returns Array of MX records
41
+ */
42
+ private getMxRecords;
43
+ /**
44
+ * Validates multiple email addresses in batch
45
+ * @param emails Array of emails to validate
46
+ * @param options Validation options
47
+ * @returns Object with email addresses as keys and validation results as values
48
+ */
49
+ validateBatch(emails: string[], options?: {
50
+ checkMx?: boolean;
51
+ checkDisposable?: boolean;
52
+ checkRole?: boolean;
53
+ checkSyntaxOnly?: boolean;
54
+ }): Promise<Record<string, IEmailValidationResult>>;
55
+ /**
56
+ * Quick check if an email format is valid (synchronous, no DNS checks)
57
+ * @param email Email to check
58
+ * @returns Boolean indicating if format is valid
59
+ */
60
+ isValidFormat(email: string): boolean;
61
+ }
@@ -0,0 +1,184 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { logger } from '../../logger.js';
3
+ import { LRUCache } from 'lru-cache';
4
+ /**
5
+ * Advanced email validator class using smartmail's capabilities
6
+ */
7
+ export class EmailValidator {
8
+ validator;
9
+ dnsCache;
10
+ constructor(options) {
11
+ this.validator = new plugins.smartmail.EmailAddressValidator();
12
+ // Initialize LRU cache for DNS records
13
+ this.dnsCache = new LRUCache({
14
+ // Default to 1000 entries (reasonable for most applications)
15
+ max: options?.maxCacheSize || 1000,
16
+ // Default TTL of 1 hour (DNS records don't change frequently)
17
+ ttl: options?.cacheTTL || 60 * 60 * 1000,
18
+ // Optional cache monitoring
19
+ allowStale: false,
20
+ updateAgeOnGet: true,
21
+ // Add logging for cache events in production environments
22
+ disposeAfter: (value, key) => {
23
+ logger.log('debug', `DNS cache entry expired for domain: ${key}`);
24
+ },
25
+ });
26
+ }
27
+ /**
28
+ * Validates an email address using comprehensive checks
29
+ * @param email The email to validate
30
+ * @param options Validation options
31
+ * @returns Validation result with details
32
+ */
33
+ async validate(email, options = {}) {
34
+ try {
35
+ const result = {
36
+ isValid: false,
37
+ hasMx: false,
38
+ hasSpamMarkings: false,
39
+ score: 0,
40
+ details: {
41
+ formatValid: false,
42
+ spamIndicators: []
43
+ }
44
+ };
45
+ // Always check basic format
46
+ result.details.formatValid = this.validator.isValidEmailFormat(email);
47
+ if (!result.details.formatValid) {
48
+ result.details.errorMessage = 'Invalid email format';
49
+ return result;
50
+ }
51
+ // If syntax-only check is requested, return early
52
+ if (options.checkSyntaxOnly) {
53
+ result.isValid = true;
54
+ result.score = 0.5;
55
+ return result;
56
+ }
57
+ // Get domain for additional checks
58
+ const domain = email.split('@')[1];
59
+ // Check MX records
60
+ if (options.checkMx !== false) {
61
+ try {
62
+ const mxRecords = await this.getMxRecords(domain);
63
+ result.details.mxRecords = mxRecords;
64
+ result.hasMx = mxRecords && mxRecords.length > 0;
65
+ if (!result.hasMx) {
66
+ result.details.spamIndicators.push('No MX records');
67
+ result.details.errorMessage = 'Domain has no MX records';
68
+ }
69
+ }
70
+ catch (error) {
71
+ logger.log('error', `Error checking MX records: ${error.message}`);
72
+ result.details.errorMessage = 'Unable to check MX records';
73
+ }
74
+ }
75
+ // Check if domain is disposable
76
+ if (options.checkDisposable !== false) {
77
+ result.details.disposable = await this.validator.isDisposableEmail(email);
78
+ if (result.details.disposable) {
79
+ result.details.spamIndicators.push('Disposable email');
80
+ }
81
+ }
82
+ // Check if email is a role account
83
+ if (options.checkRole !== false) {
84
+ result.details.role = this.validator.isRoleAccount(email);
85
+ if (result.details.role) {
86
+ result.details.spamIndicators.push('Role account');
87
+ }
88
+ }
89
+ // Calculate spam score and final validity
90
+ result.hasSpamMarkings = result.details.spamIndicators.length > 0;
91
+ // Calculate a score between 0-1 based on checks
92
+ let scoreFactors = 0;
93
+ let scoreTotal = 0;
94
+ // Format check (highest weight)
95
+ scoreFactors += 0.4;
96
+ if (result.details.formatValid)
97
+ scoreTotal += 0.4;
98
+ // MX check (high weight)
99
+ if (options.checkMx !== false) {
100
+ scoreFactors += 0.3;
101
+ if (result.hasMx)
102
+ scoreTotal += 0.3;
103
+ }
104
+ // Disposable check (medium weight)
105
+ if (options.checkDisposable !== false) {
106
+ scoreFactors += 0.2;
107
+ if (!result.details.disposable)
108
+ scoreTotal += 0.2;
109
+ }
110
+ // Role account check (low weight)
111
+ if (options.checkRole !== false) {
112
+ scoreFactors += 0.1;
113
+ if (!result.details.role)
114
+ scoreTotal += 0.1;
115
+ }
116
+ // Normalize score based on factors actually checked
117
+ result.score = scoreFactors > 0 ? scoreTotal / scoreFactors : 0;
118
+ // Email is valid if score is above 0.7 (configurable threshold)
119
+ result.isValid = result.score >= 0.7;
120
+ return result;
121
+ }
122
+ catch (error) {
123
+ logger.log('error', `Email validation error: ${error.message}`);
124
+ return {
125
+ isValid: false,
126
+ hasMx: false,
127
+ hasSpamMarkings: true,
128
+ score: 0,
129
+ details: {
130
+ formatValid: false,
131
+ errorMessage: `Validation error: ${error.message}`,
132
+ spamIndicators: ['Validation error']
133
+ }
134
+ };
135
+ }
136
+ }
137
+ /**
138
+ * Gets MX records for a domain with caching
139
+ * @param domain Domain to check
140
+ * @returns Array of MX records
141
+ */
142
+ async getMxRecords(domain) {
143
+ // Check cache first
144
+ const cachedRecords = this.dnsCache.get(domain);
145
+ if (cachedRecords) {
146
+ logger.log('debug', `Using cached MX records for domain: ${domain}`);
147
+ return cachedRecords;
148
+ }
149
+ try {
150
+ // Use smartmail's getMxRecords method
151
+ const records = await this.validator.getMxRecords(domain);
152
+ // Store in cache (TTL is handled by the LRU cache configuration)
153
+ this.dnsCache.set(domain, records);
154
+ logger.log('debug', `Cached MX records for domain: ${domain}`);
155
+ return records;
156
+ }
157
+ catch (error) {
158
+ logger.log('error', `Error fetching MX records for ${domain}: ${error.message}`);
159
+ return [];
160
+ }
161
+ }
162
+ /**
163
+ * Validates multiple email addresses in batch
164
+ * @param emails Array of emails to validate
165
+ * @param options Validation options
166
+ * @returns Object with email addresses as keys and validation results as values
167
+ */
168
+ async validateBatch(emails, options = {}) {
169
+ const results = {};
170
+ for (const email of emails) {
171
+ results[email] = await this.validate(email, options);
172
+ }
173
+ return results;
174
+ }
175
+ /**
176
+ * Quick check if an email format is valid (synchronous, no DNS checks)
177
+ * @param email Email to check
178
+ * @returns Boolean indicating if format is valid
179
+ */
180
+ isValidFormat(email) {
181
+ return this.validator.isValidEmailFormat(email);
182
+ }
183
+ }
184
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5lbWFpbHZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL21haWwvY29yZS9jbGFzc2VzLmVtYWlsdmFsaWRhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFpQnJDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGNBQWM7SUFDakIsU0FBUyxDQUEwQztJQUNuRCxRQUFRLENBQTZCO0lBRTdDLFlBQVksT0FHWDtRQUNDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxPQUFPLENBQUMsU0FBUyxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFFL0QsdUNBQXVDO1FBQ3ZDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxRQUFRLENBQW1CO1lBQzdDLDZEQUE2RDtZQUM3RCxHQUFHLEVBQUUsT0FBTyxFQUFFLFlBQVksSUFBSSxJQUFJO1lBQ2xDLDhEQUE4RDtZQUM5RCxHQUFHLEVBQUUsT0FBTyxFQUFFLFFBQVEsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUk7WUFDeEMsNEJBQTRCO1lBQzVCLFVBQVUsRUFBRSxLQUFLO1lBQ2pCLGNBQWMsRUFBRSxJQUFJO1lBQ3BCLDBEQUEwRDtZQUMxRCxZQUFZLEVBQUUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUU7Z0JBQzNCLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLHVDQUF1QyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ3BFLENBQUM7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxLQUFLLENBQUMsUUFBUSxDQUNuQixLQUFhLEVBQ2IsVUFLSSxFQUFFO1FBRU4sSUFBSSxDQUFDO1lBQ0gsTUFB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
@@ -0,0 +1,95 @@
1
+ import { Email } from './classes.email.js';
2
+ /**
3
+ * Email template type definition
4
+ */
5
+ export interface IEmailTemplate<T = any> {
6
+ id: string;
7
+ name: string;
8
+ description: string;
9
+ from: string;
10
+ subject: string;
11
+ bodyHtml: string;
12
+ bodyText?: string;
13
+ category?: string;
14
+ sampleData?: T;
15
+ attachments?: Array<{
16
+ name: string;
17
+ path: string;
18
+ contentType?: string;
19
+ }>;
20
+ }
21
+ /**
22
+ * Email template context - data used to render the template
23
+ */
24
+ export interface ITemplateContext {
25
+ [key: string]: any;
26
+ }
27
+ /**
28
+ * Template category definitions
29
+ */
30
+ export declare enum TemplateCategory {
31
+ NOTIFICATION = "notification",
32
+ TRANSACTIONAL = "transactional",
33
+ MARKETING = "marketing",
34
+ SYSTEM = "system"
35
+ }
36
+ /**
37
+ * Enhanced template manager using Email class for template rendering
38
+ */
39
+ export declare class TemplateManager {
40
+ private templates;
41
+ private defaultConfig;
42
+ constructor(defaultConfig?: {
43
+ from?: string;
44
+ replyTo?: string;
45
+ footerHtml?: string;
46
+ footerText?: string;
47
+ });
48
+ /**
49
+ * Register built-in email templates
50
+ */
51
+ private registerBuiltinTemplates;
52
+ /**
53
+ * Register a new email template
54
+ * @param template The email template to register
55
+ */
56
+ registerTemplate<T = any>(template: IEmailTemplate<T>): void;
57
+ /**
58
+ * Get an email template by ID
59
+ * @param templateId The template ID
60
+ * @returns The template or undefined if not found
61
+ */
62
+ getTemplate<T = any>(templateId: string): IEmailTemplate<T> | undefined;
63
+ /**
64
+ * List all available templates
65
+ * @param category Optional category filter
66
+ * @returns Array of email templates
67
+ */
68
+ listTemplates(category?: TemplateCategory): IEmailTemplate[];
69
+ /**
70
+ * Create an Email instance from a template
71
+ * @param templateId The template ID
72
+ * @param context The template context data
73
+ * @returns A configured Email instance
74
+ */
75
+ createEmail<T = any>(templateId: string, context?: ITemplateContext): Promise<Email>;
76
+ /**
77
+ * Create and completely process an Email instance from a template
78
+ * @param templateId The template ID
79
+ * @param context The template context data
80
+ * @returns A complete, processed Email instance ready to send
81
+ */
82
+ prepareEmail<T = any>(templateId: string, context?: ITemplateContext): Promise<Email>;
83
+ /**
84
+ * Create a MIME-formatted email from a template
85
+ * @param templateId The template ID
86
+ * @param context The template context data
87
+ * @returns A MIME-formatted email string
88
+ */
89
+ createMimeEmail(templateId: string, context?: ITemplateContext): Promise<string>;
90
+ /**
91
+ * Load templates from a directory
92
+ * @param directory The directory containing template JSON files
93
+ */
94
+ loadTemplatesFromDirectory(directory: string): Promise<void>;
95
+ }
@@ -0,0 +1,240 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import * as paths from '../../paths.js';
3
+ import { logger } from '../../logger.js';
4
+ import { Email } from './classes.email.js';
5
+ /**
6
+ * Template category definitions
7
+ */
8
+ export var TemplateCategory;
9
+ (function (TemplateCategory) {
10
+ TemplateCategory["NOTIFICATION"] = "notification";
11
+ TemplateCategory["TRANSACTIONAL"] = "transactional";
12
+ TemplateCategory["MARKETING"] = "marketing";
13
+ TemplateCategory["SYSTEM"] = "system";
14
+ })(TemplateCategory || (TemplateCategory = {}));
15
+ /**
16
+ * Enhanced template manager using Email class for template rendering
17
+ */
18
+ export class TemplateManager {
19
+ templates = new Map();
20
+ defaultConfig;
21
+ constructor(defaultConfig) {
22
+ // Set default configuration
23
+ this.defaultConfig = {
24
+ from: defaultConfig?.from || 'noreply@mail.lossless.com',
25
+ replyTo: defaultConfig?.replyTo,
26
+ footerHtml: defaultConfig?.footerHtml || '',
27
+ footerText: defaultConfig?.footerText || ''
28
+ };
29
+ // Initialize with built-in templates
30
+ this.registerBuiltinTemplates();
31
+ }
32
+ /**
33
+ * Register built-in email templates
34
+ */
35
+ registerBuiltinTemplates() {
36
+ // Welcome email
37
+ this.registerTemplate({
38
+ id: 'welcome',
39
+ name: 'Welcome Email',
40
+ description: 'Sent to users when they first sign up',
41
+ from: this.defaultConfig.from,
42
+ subject: 'Welcome to {{serviceName}}!',
43
+ category: TemplateCategory.TRANSACTIONAL,
44
+ bodyHtml: `
45
+ <h1>Welcome, {{firstName}}!</h1>
46
+ <p>Thank you for joining {{serviceName}}. We're excited to have you on board.</p>
47
+ <p>To get started, <a href="{{accountUrl}}">visit your account</a>.</p>
48
+ `,
49
+ bodyText: `Welcome, {{firstName}}!
50
+
51
+ Thank you for joining {{serviceName}}. We're excited to have you on board.
52
+
53
+ To get started, visit your account: {{accountUrl}}
54
+ `,
55
+ sampleData: {
56
+ firstName: 'John',
57
+ accountUrl: 'https://example.com/account'
58
+ }
59
+ });
60
+ // Password reset
61
+ this.registerTemplate({
62
+ id: 'password-reset',
63
+ name: 'Password Reset',
64
+ description: 'Sent when a user requests a password reset',
65
+ from: this.defaultConfig.from,
66
+ subject: 'Password Reset Request',
67
+ category: TemplateCategory.TRANSACTIONAL,
68
+ bodyHtml: `
69
+ <h2>Password Reset Request</h2>
70
+ <p>You recently requested to reset your password. Click the link below to reset it:</p>
71
+ <p><a href="{{resetUrl}}">Reset Password</a></p>
72
+ <p>This link will expire in {{expiryHours}} hours.</p>
73
+ <p>If you didn't request a password reset, please ignore this email.</p>
74
+ `,
75
+ sampleData: {
76
+ resetUrl: 'https://example.com/reset-password?token=abc123',
77
+ expiryHours: 24
78
+ }
79
+ });
80
+ // System notification
81
+ this.registerTemplate({
82
+ id: 'system-notification',
83
+ name: 'System Notification',
84
+ description: 'General system notification template',
85
+ from: this.defaultConfig.from,
86
+ subject: '{{subject}}',
87
+ category: TemplateCategory.SYSTEM,
88
+ bodyHtml: `
89
+ <h2>{{title}}</h2>
90
+ <div>{{message}}</div>
91
+ `,
92
+ sampleData: {
93
+ subject: 'Important System Notification',
94
+ title: 'System Maintenance',
95
+ message: 'The system will be undergoing maintenance on Saturday from 2-4am UTC.'
96
+ }
97
+ });
98
+ }
99
+ /**
100
+ * Register a new email template
101
+ * @param template The email template to register
102
+ */
103
+ registerTemplate(template) {
104
+ if (this.templates.has(template.id)) {
105
+ logger.log('warn', `Template with ID '${template.id}' already exists and will be overwritten`);
106
+ }
107
+ // Add footer to templates if configured
108
+ if (this.defaultConfig.footerHtml && template.bodyHtml) {
109
+ template.bodyHtml += this.defaultConfig.footerHtml;
110
+ }
111
+ if (this.defaultConfig.footerText && template.bodyText) {
112
+ template.bodyText += this.defaultConfig.footerText;
113
+ }
114
+ this.templates.set(template.id, template);
115
+ logger.log('info', `Registered email template: ${template.id}`);
116
+ }
117
+ /**
118
+ * Get an email template by ID
119
+ * @param templateId The template ID
120
+ * @returns The template or undefined if not found
121
+ */
122
+ getTemplate(templateId) {
123
+ return this.templates.get(templateId);
124
+ }
125
+ /**
126
+ * List all available templates
127
+ * @param category Optional category filter
128
+ * @returns Array of email templates
129
+ */
130
+ listTemplates(category) {
131
+ const templates = Array.from(this.templates.values());
132
+ if (category) {
133
+ return templates.filter(template => template.category === category);
134
+ }
135
+ return templates;
136
+ }
137
+ /**
138
+ * Create an Email instance from a template
139
+ * @param templateId The template ID
140
+ * @param context The template context data
141
+ * @returns A configured Email instance
142
+ */
143
+ async createEmail(templateId, context) {
144
+ const template = this.getTemplate(templateId);
145
+ if (!template) {
146
+ throw new Error(`Template with ID '${templateId}' not found`);
147
+ }
148
+ // Build attachments array for Email
149
+ const attachments = [];
150
+ if (template.attachments && template.attachments.length > 0) {
151
+ for (const attachment of template.attachments) {
152
+ try {
153
+ const attachmentPath = plugins.path.isAbsolute(attachment.path)
154
+ ? attachment.path
155
+ : plugins.path.join(paths.MtaAttachmentsDir, attachment.path);
156
+ // Read the file
157
+ const fileBuffer = await plugins.fs.promises.readFile(attachmentPath);
158
+ attachments.push({
159
+ filename: attachment.name,
160
+ content: fileBuffer,
161
+ contentType: attachment.contentType || 'application/octet-stream'
162
+ });
163
+ }
164
+ catch (error) {
165
+ logger.log('error', `Failed to add attachment '${attachment.name}': ${error.message}`);
166
+ }
167
+ }
168
+ }
169
+ // Create Email instance with template content
170
+ const emailOptions = {
171
+ from: template.from || this.defaultConfig.from,
172
+ subject: template.subject,
173
+ text: template.bodyText || '',
174
+ html: template.bodyHtml,
175
+ // Note: 'to' is intentionally omitted for templates
176
+ attachments,
177
+ variables: context || {}
178
+ };
179
+ return new Email(emailOptions);
180
+ }
181
+ /**
182
+ * Create and completely process an Email instance from a template
183
+ * @param templateId The template ID
184
+ * @param context The template context data
185
+ * @returns A complete, processed Email instance ready to send
186
+ */
187
+ async prepareEmail(templateId, context = {}) {
188
+ const email = await this.createEmail(templateId, context);
189
+ // Email class processes variables when needed, no pre-compilation required
190
+ return email;
191
+ }
192
+ /**
193
+ * Create a MIME-formatted email from a template
194
+ * @param templateId The template ID
195
+ * @param context The template context data
196
+ * @returns A MIME-formatted email string
197
+ */
198
+ async createMimeEmail(templateId, context = {}) {
199
+ const email = await this.prepareEmail(templateId, context);
200
+ return email.toRFC822String(context);
201
+ }
202
+ /**
203
+ * Load templates from a directory
204
+ * @param directory The directory containing template JSON files
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`);
233
+ }
234
+ catch (error) {
235
+ logger.log('error', `Failed to load templates from directory: ${error.message}`);
236
+ throw error;
237
+ }
238
+ }
239
+ }
240
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy50ZW1wbGF0ZW1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9tYWlsL2NvcmUvY2xhc3Nlcy50ZW1wbGF0ZW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEtBQUssS0FBSyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsS0FBSyxFQUF3QyxNQUFNLG9CQUFvQixDQUFDO0FBNkJqRjs7R0FFRztBQUNILE1BQU0sQ0FBTixJQUFZLGdCQUtYO0FBTEQsV0FBWSxnQkFBZ0I7SUFDMUIsaURBQTZCLENBQUE7SUFDN0IsbURBQStCLENBQUE7SUFDL0IsMkNBQXVCLENBQUE7SUFDdkIscUNBQWlCLENBQUE7QUFDbkIsQ0FBQyxFQUxXLGdCQUFnQixLQUFoQixnQkFBZ0IsUUFLM0I7QUFFRDs7R0FFRztBQUNILE1BQU0sT0FBTyxlQUFlO0lBQ2xCLFNBQVMsR0FBZ0MsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNuRCxhQUFhLENBS25CO0lBRUYsWUFBWSxhQUtYO1FBQ0MsNEJBQTRCO1FBQzVCLElBQUksQ0FBQyxhQUFhLEdBQUc7WUFDbkIsSUFBSSxFQUFFLGFBQWEsRUFBRSxJQUFJLElBQUksMkJBQTJCO1lBQ3hELE9BQU8sRUFBRSxhQUFhLEVBQUUsT0FBTztZQUMvQixVQUFVLEVBQUUsYUFBYSxFQUFFLFVBQVUsSUFBSSxFQUFFO1lBQzNDLFVBQVUsRUFBRSxhQUFhLEVBQUUsVUFBVSxJQUFJLEVBQUU7U0FDNUMsQ0FBQztRQUVGLHFDQUFxQztRQUNyQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7O09BRUc7SUFDSyx3QkFBd0I7UUFDOUIsZ0JBQWdCO1FBQ2hCLElBQUksQ0FBQyxnQkFB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
@@ -0,0 +1,4 @@
1
+ export * from './classes.email.js';
2
+ export * from './classes.emailvalidator.js';
3
+ export * from './classes.templatemanager.js';
4
+ export * from './classes.bouncemanager.js';
@@ -0,0 +1,6 @@
1
+ // Core email components
2
+ export * from './classes.email.js';
3
+ export * from './classes.emailvalidator.js';
4
+ export * from './classes.templatemanager.js';
5
+ export * from './classes.bouncemanager.js';
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9tYWlsL2NvcmUvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsd0JBQXdCO0FBQ3hCLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYyw2QkFBNkIsQ0FBQztBQUM1QyxjQUFjLDhCQUE4QixDQUFDO0FBQzdDLGNBQWMsNEJBQTRCLENBQUMifQ==