@push.rocks/smartmta 5.1.3 → 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.
- package/changelog.md +7 -0
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/index.d.ts +3 -0
- package/dist_ts/index.js +4 -0
- package/dist_ts/logger.d.ts +17 -0
- package/dist_ts/logger.js +76 -0
- package/dist_ts/mail/core/classes.bouncemanager.d.ts +185 -0
- package/dist_ts/mail/core/classes.bouncemanager.js +569 -0
- package/dist_ts/mail/core/classes.email.d.ts +291 -0
- package/dist_ts/mail/core/classes.email.js +802 -0
- package/dist_ts/mail/core/classes.emailvalidator.d.ts +61 -0
- package/dist_ts/mail/core/classes.emailvalidator.js +184 -0
- package/dist_ts/mail/core/classes.templatemanager.d.ts +95 -0
- package/dist_ts/mail/core/classes.templatemanager.js +240 -0
- package/dist_ts/mail/core/index.d.ts +4 -0
- package/dist_ts/mail/core/index.js +6 -0
- package/dist_ts/mail/delivery/classes.delivery.queue.d.ts +163 -0
- package/dist_ts/mail/delivery/classes.delivery.queue.js +488 -0
- package/dist_ts/mail/delivery/classes.delivery.system.d.ts +160 -0
- package/dist_ts/mail/delivery/classes.delivery.system.js +630 -0
- package/dist_ts/mail/delivery/classes.unified.rate.limiter.d.ts +200 -0
- package/dist_ts/mail/delivery/classes.unified.rate.limiter.js +820 -0
- package/dist_ts/mail/delivery/index.d.ts +4 -0
- package/dist_ts/mail/delivery/index.js +6 -0
- package/dist_ts/mail/delivery/interfaces.d.ts +140 -0
- package/dist_ts/mail/delivery/interfaces.js +17 -0
- package/dist_ts/mail/index.d.ts +7 -0
- package/dist_ts/mail/index.js +12 -0
- package/dist_ts/mail/routing/classes.dkim.manager.d.ts +25 -0
- package/dist_ts/mail/routing/classes.dkim.manager.js +127 -0
- package/dist_ts/mail/routing/classes.dns.manager.d.ts +79 -0
- package/dist_ts/mail/routing/classes.dns.manager.js +415 -0
- package/dist_ts/mail/routing/classes.domain.registry.d.ts +54 -0
- package/dist_ts/mail/routing/classes.domain.registry.js +119 -0
- package/dist_ts/mail/routing/classes.email.action.executor.d.ts +33 -0
- package/dist_ts/mail/routing/classes.email.action.executor.js +137 -0
- package/dist_ts/mail/routing/classes.email.router.d.ts +171 -0
- package/dist_ts/mail/routing/classes.email.router.js +494 -0
- package/dist_ts/mail/routing/classes.unified.email.server.d.ts +241 -0
- package/dist_ts/mail/routing/classes.unified.email.server.js +935 -0
- package/dist_ts/mail/routing/index.d.ts +7 -0
- package/dist_ts/mail/routing/index.js +9 -0
- package/dist_ts/mail/routing/interfaces.d.ts +187 -0
- package/dist_ts/mail/routing/interfaces.js +2 -0
- package/dist_ts/mail/security/classes.dkimcreator.d.ts +72 -0
- package/dist_ts/mail/security/classes.dkimcreator.js +360 -0
- package/dist_ts/mail/security/classes.spfverifier.d.ts +62 -0
- package/dist_ts/mail/security/classes.spfverifier.js +87 -0
- package/dist_ts/mail/security/index.d.ts +2 -0
- package/dist_ts/mail/security/index.js +4 -0
- package/dist_ts/paths.d.ts +14 -0
- package/dist_ts/paths.js +39 -0
- package/dist_ts/plugins.d.ts +24 -0
- package/dist_ts/plugins.js +28 -0
- package/dist_ts/security/classes.contentscanner.d.ts +130 -0
- package/dist_ts/security/classes.contentscanner.js +338 -0
- package/dist_ts/security/classes.ipreputationchecker.d.ts +73 -0
- package/dist_ts/security/classes.ipreputationchecker.js +263 -0
- package/dist_ts/security/classes.rustsecuritybridge.d.ts +398 -0
- package/dist_ts/security/classes.rustsecuritybridge.js +484 -0
- package/dist_ts/security/classes.securitylogger.d.ts +140 -0
- package/dist_ts/security/classes.securitylogger.js +235 -0
- package/dist_ts/security/index.d.ts +4 -0
- package/dist_ts/security/index.js +5 -0
- package/package.json +6 -1
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/index.ts +3 -0
- package/ts/logger.ts +91 -0
- package/ts/mail/core/classes.bouncemanager.ts +731 -0
- package/ts/mail/core/classes.email.ts +942 -0
- package/ts/mail/core/classes.emailvalidator.ts +239 -0
- package/ts/mail/core/classes.templatemanager.ts +320 -0
- package/ts/mail/core/index.ts +5 -0
- package/ts/mail/delivery/classes.delivery.queue.ts +645 -0
- package/ts/mail/delivery/classes.delivery.system.ts +816 -0
- package/ts/mail/delivery/classes.unified.rate.limiter.ts +1053 -0
- package/ts/mail/delivery/index.ts +5 -0
- package/ts/mail/delivery/interfaces.ts +167 -0
- package/ts/mail/index.ts +17 -0
- package/ts/mail/routing/classes.dkim.manager.ts +157 -0
- package/ts/mail/routing/classes.dns.manager.ts +573 -0
- package/ts/mail/routing/classes.domain.registry.ts +139 -0
- package/ts/mail/routing/classes.email.action.executor.ts +175 -0
- package/ts/mail/routing/classes.email.router.ts +575 -0
- package/ts/mail/routing/classes.unified.email.server.ts +1207 -0
- package/ts/mail/routing/index.ts +9 -0
- package/ts/mail/routing/interfaces.ts +202 -0
- package/ts/mail/security/classes.dkimcreator.ts +447 -0
- package/ts/mail/security/classes.spfverifier.ts +126 -0
- package/ts/mail/security/index.ts +3 -0
- package/ts/paths.ts +48 -0
- package/ts/plugins.ts +53 -0
- package/ts/security/classes.contentscanner.ts +400 -0
- package/ts/security/classes.ipreputationchecker.ts +315 -0
- package/ts/security/classes.rustsecuritybridge.ts +943 -0
- package/ts/security/classes.securitylogger.ts +299 -0
- package/ts/security/index.ts +40 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { logger } from '../../logger.js';
|
|
2
|
+
import { SecurityLogger, SecurityLogLevel, SecurityEventType } from '../../security/index.js';
|
|
3
|
+
import { Email } from '../core/classes.email.js';
|
|
4
|
+
import { BounceManager } from '../core/classes.bouncemanager.js';
|
|
5
|
+
import { UnifiedDeliveryQueue } from '../delivery/classes.delivery.queue.js';
|
|
6
|
+
/**
|
|
7
|
+
* Executes email routing actions (forward, process, deliver, reject)
|
|
8
|
+
*/
|
|
9
|
+
export class EmailActionExecutor {
|
|
10
|
+
deps;
|
|
11
|
+
constructor(deps) {
|
|
12
|
+
this.deps = deps;
|
|
13
|
+
}
|
|
14
|
+
async executeAction(action, email, context) {
|
|
15
|
+
switch (action.type) {
|
|
16
|
+
case 'forward':
|
|
17
|
+
await this.handleForwardAction(action, email, context);
|
|
18
|
+
break;
|
|
19
|
+
case 'process':
|
|
20
|
+
await this.handleProcessAction(action, email, context);
|
|
21
|
+
break;
|
|
22
|
+
case 'deliver':
|
|
23
|
+
await this.handleDeliverAction(action, email, context);
|
|
24
|
+
break;
|
|
25
|
+
case 'reject':
|
|
26
|
+
await this.handleRejectAction(action, email, context);
|
|
27
|
+
break;
|
|
28
|
+
default:
|
|
29
|
+
throw new Error(`Unknown action type: ${action.type}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async handleForwardAction(action, email, context) {
|
|
33
|
+
if (!action.forward) {
|
|
34
|
+
throw new Error('Forward action requires forward configuration');
|
|
35
|
+
}
|
|
36
|
+
const { host, port = 25, auth, addHeaders } = action.forward;
|
|
37
|
+
logger.log('info', `Forwarding email to ${host}:${port}`);
|
|
38
|
+
// Add forwarding headers
|
|
39
|
+
if (addHeaders) {
|
|
40
|
+
for (const [key, value] of Object.entries(addHeaders)) {
|
|
41
|
+
email.headers[key] = value;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Add standard forwarding headers
|
|
45
|
+
email.headers['X-Forwarded-For'] = context.session.remoteAddress || 'unknown';
|
|
46
|
+
email.headers['X-Forwarded-To'] = email.to.join(', ');
|
|
47
|
+
email.headers['X-Forwarded-Date'] = new Date().toISOString();
|
|
48
|
+
try {
|
|
49
|
+
// Send email via Rust SMTP client
|
|
50
|
+
await this.deps.sendOutboundEmail(host, port, email, {
|
|
51
|
+
auth: auth,
|
|
52
|
+
});
|
|
53
|
+
logger.log('info', `Successfully forwarded email to ${host}:${port}`);
|
|
54
|
+
SecurityLogger.getInstance().logEvent({
|
|
55
|
+
level: SecurityLogLevel.INFO,
|
|
56
|
+
type: SecurityEventType.EMAIL_FORWARDING,
|
|
57
|
+
message: 'Email forwarded successfully',
|
|
58
|
+
ipAddress: context.session.remoteAddress,
|
|
59
|
+
details: {
|
|
60
|
+
sessionId: context.session.id,
|
|
61
|
+
routeName: context.session.matchedRoute?.name,
|
|
62
|
+
targetHost: host,
|
|
63
|
+
targetPort: port,
|
|
64
|
+
recipients: email.to
|
|
65
|
+
},
|
|
66
|
+
success: true
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
logger.log('error', `Failed to forward email: ${error.message}`);
|
|
71
|
+
SecurityLogger.getInstance().logEvent({
|
|
72
|
+
level: SecurityLogLevel.ERROR,
|
|
73
|
+
type: SecurityEventType.EMAIL_FORWARDING,
|
|
74
|
+
message: 'Email forwarding failed',
|
|
75
|
+
ipAddress: context.session.remoteAddress,
|
|
76
|
+
details: {
|
|
77
|
+
sessionId: context.session.id,
|
|
78
|
+
routeName: context.session.matchedRoute?.name,
|
|
79
|
+
targetHost: host,
|
|
80
|
+
targetPort: port,
|
|
81
|
+
error: error.message
|
|
82
|
+
},
|
|
83
|
+
success: false
|
|
84
|
+
});
|
|
85
|
+
// Handle as bounce
|
|
86
|
+
for (const recipient of email.getAllRecipients()) {
|
|
87
|
+
await this.deps.bounceManager.processSmtpFailure(recipient, error.message, {
|
|
88
|
+
sender: email.from,
|
|
89
|
+
originalEmailId: email.headers['Message-ID']
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async handleProcessAction(action, email, context) {
|
|
96
|
+
logger.log('info', `Processing email with action options`);
|
|
97
|
+
// Apply scanning if requested
|
|
98
|
+
if (action.process?.scan) {
|
|
99
|
+
logger.log('info', 'Content scanning requested');
|
|
100
|
+
}
|
|
101
|
+
// Queue for delivery
|
|
102
|
+
const queue = action.process?.queue || 'normal';
|
|
103
|
+
await this.deps.deliveryQueue.enqueue(email, 'process', context.session.matchedRoute);
|
|
104
|
+
logger.log('info', `Email queued for delivery in ${queue} queue`);
|
|
105
|
+
}
|
|
106
|
+
async handleDeliverAction(_action, email, context) {
|
|
107
|
+
logger.log('info', `Delivering email locally`);
|
|
108
|
+
// Queue for local delivery
|
|
109
|
+
await this.deps.deliveryQueue.enqueue(email, 'mta', context.session.matchedRoute);
|
|
110
|
+
logger.log('info', 'Email queued for local delivery');
|
|
111
|
+
}
|
|
112
|
+
async handleRejectAction(action, _email, context) {
|
|
113
|
+
const code = action.reject?.code || 550;
|
|
114
|
+
const message = action.reject?.message || 'Message rejected';
|
|
115
|
+
logger.log('info', `Rejecting email with code ${code}: ${message}`);
|
|
116
|
+
SecurityLogger.getInstance().logEvent({
|
|
117
|
+
level: SecurityLogLevel.WARN,
|
|
118
|
+
type: SecurityEventType.EMAIL_PROCESSING,
|
|
119
|
+
message: 'Email rejected by routing rule',
|
|
120
|
+
ipAddress: context.session.remoteAddress,
|
|
121
|
+
details: {
|
|
122
|
+
sessionId: context.session.id,
|
|
123
|
+
routeName: context.session.matchedRoute?.name,
|
|
124
|
+
rejectCode: code,
|
|
125
|
+
rejectMessage: message,
|
|
126
|
+
from: _email.from,
|
|
127
|
+
to: _email.to
|
|
128
|
+
},
|
|
129
|
+
success: false
|
|
130
|
+
});
|
|
131
|
+
// Throw error with SMTP code and message
|
|
132
|
+
const error = new Error(message);
|
|
133
|
+
error.responseCode = code;
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5lbWFpbC5hY3Rpb24uZXhlY3V0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9tYWlsL3JvdXRpbmcvY2xhc3Nlcy5lbWFpbC5hY3Rpb24uZXhlY3V0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFDTCxjQUFjLEVBQ2QsZ0JBQWdCLEVBQ2hCLGlCQUFpQixFQUNsQixNQUFNLHlCQUF5QixDQUFDO0FBRWpDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDakUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFpQjdFOztHQUVHO0FBQ0gsTUFBTSxPQUFPLG1CQUFtQjtJQUNWO0lBQXBCLFlBQW9CLElBQXlCO1FBQXpCLFNBQUksR0FBSixJQUFJLENBQXFCO0lBQUcsQ0FBQztJQUVqRCxLQUFLLENBQUMsYUFBYSxDQUFDLE1BQW9CLEVBQUUsS0FBWSxFQUFFLE9BQXNCO1FBQzVFLFFBQVEsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3BCLEtBQUssU0FBUztnQkFDWixNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUN2RCxNQUFNO1lBQ1IsS0FBSyxTQUFTO2dCQUNaLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ3ZELE1BQU07WUFDUixLQUFLLFNBQVM7Z0JBQ1osTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDdkQsTUFBTTtZQUNSLEtBQUssUUFBUTtnQkFDWCxN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
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import type { IEmailRoute, IEmailContext } from './interfaces.js';
|
|
3
|
+
/**
|
|
4
|
+
* Email router that evaluates routes and determines actions
|
|
5
|
+
*/
|
|
6
|
+
export declare class EmailRouter extends EventEmitter {
|
|
7
|
+
private routes;
|
|
8
|
+
private patternCache;
|
|
9
|
+
private storageManager?;
|
|
10
|
+
private persistChanges;
|
|
11
|
+
/**
|
|
12
|
+
* Create a new email router
|
|
13
|
+
* @param routes Array of email routes
|
|
14
|
+
* @param options Router options
|
|
15
|
+
*/
|
|
16
|
+
constructor(routes: IEmailRoute[], options?: {
|
|
17
|
+
storageManager?: any;
|
|
18
|
+
persistChanges?: boolean;
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* Sort routes by priority (higher priority first)
|
|
22
|
+
* @param routes Routes to sort
|
|
23
|
+
* @returns Sorted routes
|
|
24
|
+
*/
|
|
25
|
+
private sortRoutesByPriority;
|
|
26
|
+
/**
|
|
27
|
+
* Get all configured routes
|
|
28
|
+
* @returns Array of routes
|
|
29
|
+
*/
|
|
30
|
+
getRoutes(): IEmailRoute[];
|
|
31
|
+
/**
|
|
32
|
+
* Update routes
|
|
33
|
+
* @param routes New routes
|
|
34
|
+
* @param persist Whether to persist changes (defaults to persistChanges setting)
|
|
35
|
+
*/
|
|
36
|
+
updateRoutes(routes: IEmailRoute[], persist?: boolean): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Set routes (alias for updateRoutes)
|
|
39
|
+
* @param routes New routes
|
|
40
|
+
* @param persist Whether to persist changes
|
|
41
|
+
*/
|
|
42
|
+
setRoutes(routes: IEmailRoute[], persist?: boolean): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Clear the pattern cache
|
|
45
|
+
*/
|
|
46
|
+
clearCache(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Evaluate routes and find the first match
|
|
49
|
+
* @param context Email context
|
|
50
|
+
* @returns Matched route or null
|
|
51
|
+
*/
|
|
52
|
+
evaluateRoutes(context: IEmailContext): Promise<IEmailRoute | null>;
|
|
53
|
+
/**
|
|
54
|
+
* Check if a route matches the context
|
|
55
|
+
* @param route Route to check
|
|
56
|
+
* @param context Email context
|
|
57
|
+
* @returns True if route matches
|
|
58
|
+
*/
|
|
59
|
+
private matchesRoute;
|
|
60
|
+
/**
|
|
61
|
+
* Check if email recipients match patterns
|
|
62
|
+
* @param email Email to check
|
|
63
|
+
* @param patterns Patterns to match
|
|
64
|
+
* @returns True if any recipient matches
|
|
65
|
+
*/
|
|
66
|
+
private matchesRecipients;
|
|
67
|
+
/**
|
|
68
|
+
* Check if email sender matches patterns
|
|
69
|
+
* @param email Email to check
|
|
70
|
+
* @param patterns Patterns to match
|
|
71
|
+
* @returns True if sender matches
|
|
72
|
+
*/
|
|
73
|
+
private matchesSenders;
|
|
74
|
+
/**
|
|
75
|
+
* Check if client IP matches patterns
|
|
76
|
+
* @param context Email context
|
|
77
|
+
* @param patterns IP patterns to match
|
|
78
|
+
* @returns True if IP matches
|
|
79
|
+
*/
|
|
80
|
+
private matchesClientIp;
|
|
81
|
+
/**
|
|
82
|
+
* Check if email headers match patterns
|
|
83
|
+
* @param email Email to check
|
|
84
|
+
* @param headerPatterns Header patterns to match
|
|
85
|
+
* @returns True if headers match
|
|
86
|
+
*/
|
|
87
|
+
private matchesHeaders;
|
|
88
|
+
/**
|
|
89
|
+
* Check if email size matches range
|
|
90
|
+
* @param email Email to check
|
|
91
|
+
* @param sizeRange Size range to match
|
|
92
|
+
* @returns True if size is in range
|
|
93
|
+
*/
|
|
94
|
+
private matchesSize;
|
|
95
|
+
/**
|
|
96
|
+
* Check if email subject matches pattern
|
|
97
|
+
* @param email Email to check
|
|
98
|
+
* @param pattern Pattern to match
|
|
99
|
+
* @returns True if subject matches
|
|
100
|
+
*/
|
|
101
|
+
private matchesSubject;
|
|
102
|
+
/**
|
|
103
|
+
* Check if a string matches a glob pattern
|
|
104
|
+
* @param str String to check
|
|
105
|
+
* @param pattern Glob pattern
|
|
106
|
+
* @returns True if matches
|
|
107
|
+
*/
|
|
108
|
+
private matchesPattern;
|
|
109
|
+
/**
|
|
110
|
+
* Convert glob pattern to RegExp
|
|
111
|
+
* @param pattern Glob pattern
|
|
112
|
+
* @returns Regular expression
|
|
113
|
+
*/
|
|
114
|
+
private globToRegExp;
|
|
115
|
+
/**
|
|
116
|
+
* Check if IP is in CIDR range
|
|
117
|
+
* @param ip IP address to check
|
|
118
|
+
* @param cidr CIDR notation (e.g., '192.168.0.0/16')
|
|
119
|
+
* @returns True if IP is in range
|
|
120
|
+
*/
|
|
121
|
+
private ipInCidr;
|
|
122
|
+
/**
|
|
123
|
+
* Convert IP address to number
|
|
124
|
+
* @param ip IP address
|
|
125
|
+
* @returns Number representation
|
|
126
|
+
*/
|
|
127
|
+
private ipToNumber;
|
|
128
|
+
/**
|
|
129
|
+
* Calculate approximate email size in bytes
|
|
130
|
+
* @param email Email to measure
|
|
131
|
+
* @returns Size in bytes
|
|
132
|
+
*/
|
|
133
|
+
private calculateEmailSize;
|
|
134
|
+
/**
|
|
135
|
+
* Save current routes to storage
|
|
136
|
+
*/
|
|
137
|
+
saveRoutes(): Promise<void>;
|
|
138
|
+
/**
|
|
139
|
+
* Load routes from storage
|
|
140
|
+
* @param options Load options
|
|
141
|
+
*/
|
|
142
|
+
loadRoutes(options?: {
|
|
143
|
+
merge?: boolean;
|
|
144
|
+
replace?: boolean;
|
|
145
|
+
}): Promise<IEmailRoute[]>;
|
|
146
|
+
/**
|
|
147
|
+
* Add a route
|
|
148
|
+
* @param route Route to add
|
|
149
|
+
* @param persist Whether to persist changes
|
|
150
|
+
*/
|
|
151
|
+
addRoute(route: IEmailRoute, persist?: boolean): Promise<void>;
|
|
152
|
+
/**
|
|
153
|
+
* Remove a route by name
|
|
154
|
+
* @param name Route name
|
|
155
|
+
* @param persist Whether to persist changes
|
|
156
|
+
*/
|
|
157
|
+
removeRoute(name: string, persist?: boolean): Promise<void>;
|
|
158
|
+
/**
|
|
159
|
+
* Update a route
|
|
160
|
+
* @param name Route name
|
|
161
|
+
* @param route Updated route data
|
|
162
|
+
* @param persist Whether to persist changes
|
|
163
|
+
*/
|
|
164
|
+
updateRoute(name: string, route: IEmailRoute, persist?: boolean): Promise<void>;
|
|
165
|
+
/**
|
|
166
|
+
* Get a route by name
|
|
167
|
+
* @param name Route name
|
|
168
|
+
* @returns Route or undefined
|
|
169
|
+
*/
|
|
170
|
+
getRoute(name: string): IEmailRoute | undefined;
|
|
171
|
+
}
|