@serve.zone/dcrouter 7.4.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.
@@ -1,6 +1,5 @@
1
1
  import * as plugins from '../../plugins.js';
2
2
  import * as interfaces from '../../../dist_ts_interfaces/index.js';
3
- import { SecurityLogger } from '../../security/index.js';
4
3
  export class EmailOpsHandler {
5
4
  opsServerRef;
6
5
  typedrouter = new plugins.typedrequest.TypedRouter();
@@ -11,36 +10,15 @@ export class EmailOpsHandler {
11
10
  this.registerHandlers();
12
11
  }
13
12
  registerHandlers() {
14
- // Get Queued Emails Handler
15
- this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getQueuedEmails', async (dataArg) => {
16
- const emailServer = this.opsServerRef.dcRouterRef.emailServer;
17
- if (!emailServer?.deliveryQueue) {
18
- return { items: [], total: 0 };
19
- }
20
- const queue = emailServer.deliveryQueue;
21
- const stats = queue.getStats();
22
- // Get all queue items and filter by status if provided
23
- const items = this.getQueueItems(dataArg.status, dataArg.limit || 50, dataArg.offset || 0);
24
- return {
25
- items,
26
- total: stats.queueSize,
27
- };
13
+ // Get All Emails Handler
14
+ this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getAllEmails', async (dataArg) => {
15
+ const emails = this.getAllQueueEmails();
16
+ return { emails };
28
17
  }));
29
- // Get Sent Emails Handler
30
- this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getSentEmails', async (dataArg) => {
31
- const items = this.getQueueItems('delivered', dataArg.limit || 50, dataArg.offset || 0);
32
- return {
33
- items,
34
- total: items.length, // Note: total would ideally come from a counter
35
- };
36
- }));
37
- // Get Failed Emails Handler
38
- this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getFailedEmails', async (dataArg) => {
39
- const items = this.getQueueItems('failed', dataArg.limit || 50, dataArg.offset || 0);
40
- return {
41
- items,
42
- total: items.length,
43
- };
18
+ // Get Email Detail Handler
19
+ this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getEmailDetail', async (dataArg) => {
20
+ const email = this.getEmailDetail(dataArg.emailId);
21
+ return { email };
44
22
  }));
45
23
  // Resend Failed Email Handler
46
24
  this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('resendEmail', async (dataArg) => {
@@ -57,10 +35,7 @@ export class EmailOpsHandler {
57
35
  return { success: false, error: `Email is not in failed state (current: ${item.status})` };
58
36
  }
59
37
  try {
60
- // Re-enqueue the failed email by creating a new queue entry
61
- // with the same data but reset attempt count
62
38
  const newQueueId = await queue.enqueue(item.processingResult, item.processingMode, item.route);
63
- // Optionally remove the old failed entry
64
39
  await queue.removeItem(dataArg.emailId);
65
40
  return { success: true, newQueueId };
66
41
  }
@@ -71,149 +46,181 @@ export class EmailOpsHandler {
71
46
  };
72
47
  }
73
48
  }));
74
- // Get Security Incidents Handler
75
- this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getSecurityIncidents', async (dataArg) => {
76
- const securityLogger = SecurityLogger.getInstance();
77
- const filter = {};
78
- if (dataArg.level) {
79
- filter.level = dataArg.level;
80
- }
81
- if (dataArg.type) {
82
- filter.type = dataArg.type;
83
- }
84
- const incidents = securityLogger.getRecentEvents(dataArg.limit || 100, Object.keys(filter).length > 0 ? filter : undefined);
85
- return {
86
- incidents: incidents.map(event => ({
87
- timestamp: event.timestamp,
88
- level: event.level,
89
- type: event.type,
90
- message: event.message,
91
- details: event.details,
92
- ipAddress: event.ipAddress,
93
- userId: event.userId,
94
- sessionId: event.sessionId,
95
- emailId: event.emailId,
96
- domain: event.domain,
97
- action: event.action,
98
- result: event.result,
99
- success: event.success,
100
- })),
101
- total: incidents.length,
102
- };
103
- }));
104
- // Get Bounce Records Handler
105
- this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getBounceRecords', async (dataArg) => {
106
- const emailServer = this.opsServerRef.dcRouterRef.emailServer;
107
- if (!emailServer) {
108
- return { records: [], suppressionList: [], total: 0 };
109
- }
110
- // Use smartmta's public API for bounce/suppression data
111
- const suppressionList = emailServer.getSuppressionList();
112
- const hardBouncedAddresses = emailServer.getHardBouncedAddresses();
113
- // Create bounce records from the available data
114
- const records = [];
115
- for (const email of hardBouncedAddresses) {
116
- const bounceInfo = emailServer.getBounceHistory(email);
117
- if (bounceInfo) {
118
- records.push({
119
- id: `bounce-${email}`,
120
- recipient: email,
121
- sender: '',
122
- domain: email.split('@')[1] || '',
123
- bounceType: bounceInfo.type,
124
- bounceCategory: bounceInfo.category,
125
- timestamp: bounceInfo.lastBounce,
126
- processed: true,
127
- });
128
- }
129
- }
130
- // Apply limit and offset
131
- const limit = dataArg.limit || 50;
132
- const offset = dataArg.offset || 0;
133
- const paginatedRecords = records.slice(offset, offset + limit);
134
- return {
135
- records: paginatedRecords,
136
- suppressionList,
137
- total: records.length,
138
- };
139
- }));
140
- // Remove from Suppression List Handler
141
- this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('removeFromSuppressionList', async (dataArg) => {
142
- const emailServer = this.opsServerRef.dcRouterRef.emailServer;
143
- if (!emailServer) {
144
- return { success: false, error: 'Email server not available' };
145
- }
146
- try {
147
- emailServer.removeFromSuppressionList(dataArg.email);
148
- return { success: true };
149
- }
150
- catch (error) {
151
- return {
152
- success: false,
153
- error: error instanceof Error ? error.message : 'Failed to remove from suppression list'
154
- };
155
- }
156
- }));
157
49
  }
158
50
  /**
159
- * Helper method to get queue items with filtering and pagination
51
+ * Get all queue items mapped to catalog IEmail format
160
52
  */
161
- getQueueItems(status, limit = 50, offset = 0) {
53
+ getAllQueueEmails() {
162
54
  const emailServer = this.opsServerRef.dcRouterRef.emailServer;
163
55
  if (!emailServer?.deliveryQueue) {
164
56
  return [];
165
57
  }
166
58
  const queue = emailServer.deliveryQueue;
167
- const items = [];
168
- // Access the internal queue map via reflection
169
- // This is necessary because the queue doesn't expose iteration methods
170
59
  const queueMap = queue.queue;
171
60
  if (!queueMap) {
172
61
  return [];
173
62
  }
174
- // Filter and convert items
63
+ const emails = [];
175
64
  for (const [id, item] of queueMap.entries()) {
176
- // Apply status filter if provided
177
- if (status && item.status !== status) {
178
- continue;
65
+ emails.push(this.mapQueueItemToEmail(item));
66
+ }
67
+ // Sort by createdAt descending (newest first)
68
+ emails.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
69
+ return emails;
70
+ }
71
+ /**
72
+ * Get a single email detail by ID
73
+ */
74
+ getEmailDetail(emailId) {
75
+ const emailServer = this.opsServerRef.dcRouterRef.emailServer;
76
+ if (!emailServer?.deliveryQueue) {
77
+ return null;
78
+ }
79
+ const queue = emailServer.deliveryQueue;
80
+ const item = queue.getItem(emailId);
81
+ if (!item) {
82
+ return null;
83
+ }
84
+ return this.mapQueueItemToEmailDetail(item);
85
+ }
86
+ /**
87
+ * Map a queue item to catalog IEmail format
88
+ */
89
+ mapQueueItemToEmail(item) {
90
+ const processingResult = item.processingResult;
91
+ let from = '';
92
+ let to = '';
93
+ let subject = '';
94
+ let messageId = '';
95
+ let size = '0 B';
96
+ if (processingResult) {
97
+ if (processingResult.email) {
98
+ from = processingResult.email.from || '';
99
+ to = (processingResult.email.to || [])[0] || '';
100
+ subject = processingResult.email.subject || '';
179
101
  }
180
- // Extract email details from processingResult if available
181
- const processingResult = item.processingResult;
182
- let from = '';
183
- let to = [];
184
- let subject = '';
185
- if (processingResult) {
186
- // Check if it's an Email object or raw email data
187
- if (processingResult.email) {
188
- from = processingResult.email.from || '';
189
- to = processingResult.email.to || [];
190
- subject = processingResult.email.subject || '';
102
+ else if (processingResult.from) {
103
+ from = processingResult.from;
104
+ to = (processingResult.to || [])[0] || '';
105
+ subject = processingResult.subject || '';
106
+ }
107
+ // Try to get messageId
108
+ if (typeof processingResult.getMessageId === 'function') {
109
+ try {
110
+ messageId = processingResult.getMessageId() || '';
191
111
  }
192
- else if (processingResult.from) {
193
- from = processingResult.from;
194
- to = processingResult.to || [];
195
- subject = processingResult.subject || '';
112
+ catch {
113
+ messageId = '';
196
114
  }
197
115
  }
198
- items.push({
199
- id: item.id,
200
- processingMode: item.processingMode,
201
- status: item.status,
202
- attempts: item.attempts,
203
- nextAttempt: item.nextAttempt instanceof Date ? item.nextAttempt.getTime() : item.nextAttempt,
204
- lastError: item.lastError,
205
- createdAt: item.createdAt instanceof Date ? item.createdAt.getTime() : item.createdAt,
206
- updatedAt: item.updatedAt instanceof Date ? item.updatedAt.getTime() : item.updatedAt,
207
- deliveredAt: item.deliveredAt instanceof Date ? item.deliveredAt.getTime() : item.deliveredAt,
208
- from,
209
- to,
210
- subject,
211
- });
116
+ // Compute approximate size
117
+ const textLen = processingResult.text?.length || 0;
118
+ const htmlLen = processingResult.html?.length || 0;
119
+ let attachSize = 0;
120
+ if (typeof processingResult.getAttachmentsSize === 'function') {
121
+ try {
122
+ attachSize = processingResult.getAttachmentsSize() || 0;
123
+ }
124
+ catch {
125
+ attachSize = 0;
126
+ }
127
+ }
128
+ size = this.formatSize(textLen + htmlLen + attachSize);
212
129
  }
213
- // Sort by createdAt descending (newest first)
214
- items.sort((a, b) => b.createdAt - a.createdAt);
215
- // Apply pagination
216
- return items.slice(offset, offset + limit);
130
+ // Map queue status to catalog TEmailStatus
131
+ const status = this.mapStatus(item.status);
132
+ const createdAt = item.createdAt instanceof Date ? item.createdAt.getTime() : item.createdAt;
133
+ return {
134
+ id: item.id,
135
+ direction: 'outbound',
136
+ status,
137
+ from,
138
+ to,
139
+ subject,
140
+ timestamp: new Date(createdAt).toISOString(),
141
+ messageId,
142
+ size,
143
+ };
144
+ }
145
+ /**
146
+ * Map a queue item to catalog IEmailDetail format
147
+ */
148
+ mapQueueItemToEmailDetail(item) {
149
+ const base = this.mapQueueItemToEmail(item);
150
+ const processingResult = item.processingResult;
151
+ let toList = [];
152
+ let cc = [];
153
+ let headers = {};
154
+ let body = '';
155
+ if (processingResult) {
156
+ if (processingResult.email) {
157
+ toList = processingResult.email.to || [];
158
+ cc = processingResult.email.cc || [];
159
+ }
160
+ else {
161
+ toList = processingResult.to || [];
162
+ cc = processingResult.cc || [];
163
+ }
164
+ headers = processingResult.headers || {};
165
+ body = processingResult.html || processingResult.text || '';
166
+ }
167
+ return {
168
+ ...base,
169
+ toList,
170
+ cc,
171
+ smtpLog: [],
172
+ connectionInfo: {
173
+ sourceIp: '',
174
+ sourceHostname: '',
175
+ destinationIp: '',
176
+ destinationPort: 0,
177
+ tlsVersion: '',
178
+ tlsCipher: '',
179
+ authenticated: false,
180
+ authMethod: '',
181
+ authUser: '',
182
+ },
183
+ authenticationResults: {
184
+ spf: 'none',
185
+ spfDomain: '',
186
+ dkim: 'none',
187
+ dkimDomain: '',
188
+ dmarc: 'none',
189
+ dmarcPolicy: '',
190
+ },
191
+ rejectionReason: item.status === 'failed' ? item.lastError : undefined,
192
+ bounceMessage: item.status === 'failed' ? item.lastError : undefined,
193
+ headers,
194
+ body,
195
+ };
196
+ }
197
+ /**
198
+ * Map queue status to catalog TEmailStatus
199
+ */
200
+ mapStatus(queueStatus) {
201
+ switch (queueStatus) {
202
+ case 'pending':
203
+ case 'processing':
204
+ return 'pending';
205
+ case 'delivered':
206
+ return 'delivered';
207
+ case 'failed':
208
+ return 'bounced';
209
+ case 'deferred':
210
+ return 'deferred';
211
+ default:
212
+ return 'pending';
213
+ }
214
+ }
215
+ /**
216
+ * Format byte size to human-readable string
217
+ */
218
+ formatSize(bytes) {
219
+ if (bytes < 1024)
220
+ return `${bytes} B`;
221
+ if (bytes < 1024 * 1024)
222
+ return `${(bytes / 1024).toFixed(1)} KB`;
223
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
217
224
  }
218
225
  }
219
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW1haWwtb3BzLmhhbmRsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90cy9vcHNzZXJ2ZXIvaGFuZGxlcnMvZW1haWwtb3BzLmhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUU1QyxPQUFPLEtBQUssVUFBVSxNQUFNLGlDQUFpQyxDQUFDO0FBQzlELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUV6RCxNQUFNLE9BQU8sZUFBZTtJQUdOO0lBRmIsV0FBVyxHQUFHLElBQUksT0FBTyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUU1RCxZQUFvQixZQUF1QjtRQUF2QixpQkFBWSxHQUFaLFlBQVksQ0FBVztRQUN6QywwQ0FBMEM7UUFDMUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMvRCxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRU8sZ0JBQWdCO1FBQ3RCLDRCQUE0QjtRQUM1QixJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FDOUIsSUFBSSxPQUFPLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FDbkMsaUJBQWlCLEVBQ2pCLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtZQUNoQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUM7WUFDOUQsSUFBSSxDQUFDLFdBQVcsRUFBRSxhQUFhLEVBQUUsQ0FBQztnQkFDaEMsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ2pDLENBQUM7WUFFRCxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsYUFBYSxDQUFDO1lBQ3hDLE1BQU0sS0FBSyxHQUFHLEtBQUss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
226
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW1haWwtb3BzLmhhbmRsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90cy9vcHNzZXJ2ZXIvaGFuZGxlcnMvZW1haWwtb3BzLmhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUU1QyxPQUFPLEtBQUssVUFBVSxNQUFNLGlDQUFpQyxDQUFDO0FBRTlELE1BQU0sT0FBTyxlQUFlO0lBR047SUFGYixXQUFXLEdBQUcsSUFBSSxPQUFPLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBRTVELFlBQW9CLFlBQXVCO1FBQXZCLGlCQUFZLEdBQVosWUFBWSxDQUFXO1FBQ3pDLDBDQUEwQztRQUMxQyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQy9ELElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFTyxnQkFBZ0I7UUFDdEIseUJBQXlCO1FBQ3pCLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUM5QixJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUNuQyxjQUFjLEVBQ2QsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO1lBQ2hCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3hDLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQztRQUNwQixDQUFDLENBQ0YsQ0FDRixDQUFDO1FBRUYsMkJBQTJCO1FBQzNCLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUM5QixJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUNuQyxnQkFBZ0IsRUFDaEIsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO1lBQ2hCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FB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
@@ -1,91 +1,71 @@
1
1
  import * as plugins from '../plugins.js';
2
2
  import * as authInterfaces from '../data/auth.js';
3
- export type TEmailQueueStatus = 'pending' | 'processing' | 'delivered' | 'failed' | 'deferred';
4
- export interface IEmailQueueItem {
3
+ export type TEmailStatus = 'delivered' | 'bounced' | 'rejected' | 'deferred' | 'pending';
4
+ export type TEmailDirection = 'inbound' | 'outbound';
5
+ export interface IEmail {
5
6
  id: string;
6
- processingMode: 'forward' | 'mta' | 'process';
7
- status: TEmailQueueStatus;
8
- attempts: number;
9
- nextAttempt: number;
10
- lastError?: string;
11
- createdAt: number;
12
- updatedAt: number;
13
- deliveredAt?: number;
14
- from?: string;
15
- to?: string[];
16
- subject?: string;
7
+ direction: TEmailDirection;
8
+ status: TEmailStatus;
9
+ from: string;
10
+ to: string;
11
+ subject: string;
12
+ timestamp: string;
13
+ messageId: string;
14
+ size: string;
17
15
  }
18
- export type TBounceType = 'invalid_recipient' | 'domain_not_found' | 'mailbox_full' | 'mailbox_inactive' | 'blocked' | 'spam_related' | 'policy_related' | 'server_unavailable' | 'temporary_failure' | 'quota_exceeded' | 'network_error' | 'timeout' | 'auto_response' | 'challenge_response' | 'unknown';
19
- export type TBounceCategory = 'hard' | 'soft' | 'auto_response' | 'unknown';
20
- export interface IBounceRecord {
21
- id: string;
22
- originalEmailId?: string;
23
- recipient: string;
24
- sender: string;
25
- domain: string;
26
- subject?: string;
27
- bounceType: TBounceType;
28
- bounceCategory: TBounceCategory;
29
- timestamp: number;
30
- smtpResponse?: string;
31
- diagnosticCode?: string;
32
- statusCode?: string;
33
- processed: boolean;
34
- retryCount?: number;
35
- nextRetryTime?: number;
16
+ export interface ISmtpLogEntry {
17
+ timestamp: string;
18
+ direction: 'client' | 'server';
19
+ command: string;
20
+ responseCode?: number;
36
21
  }
37
- export type TSecurityLogLevel = 'info' | 'warn' | 'error' | 'critical';
38
- export type TSecurityEventType = 'authentication' | 'access_control' | 'email_validation' | 'email_processing' | 'email_forwarding' | 'email_delivery' | 'dkim' | 'spf' | 'dmarc' | 'rate_limit' | 'rate_limiting' | 'spam' | 'malware' | 'connection' | 'data_exposure' | 'configuration' | 'ip_reputation' | 'rejected_connection';
39
- export interface ISecurityIncident {
40
- timestamp: number;
41
- level: TSecurityLogLevel;
42
- type: TSecurityEventType;
43
- message: string;
44
- details?: any;
45
- ipAddress?: string;
46
- userId?: string;
47
- sessionId?: string;
48
- emailId?: string;
49
- domain?: string;
50
- action?: string;
51
- result?: string;
52
- success?: boolean;
22
+ export interface IConnectionInfo {
23
+ sourceIp: string;
24
+ sourceHostname: string;
25
+ destinationIp: string;
26
+ destinationPort: number;
27
+ tlsVersion: string;
28
+ tlsCipher: string;
29
+ authenticated: boolean;
30
+ authMethod: string;
31
+ authUser: string;
53
32
  }
54
- export interface IReq_GetQueuedEmails extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_GetQueuedEmails> {
55
- method: 'getQueuedEmails';
56
- request: {
57
- identity?: authInterfaces.IIdentity;
58
- status?: TEmailQueueStatus;
59
- limit?: number;
60
- offset?: number;
61
- };
62
- response: {
63
- items: IEmailQueueItem[];
64
- total: number;
65
- };
33
+ export interface IAuthenticationResults {
34
+ spf: 'pass' | 'fail' | 'softfail' | 'neutral' | 'none';
35
+ spfDomain: string;
36
+ dkim: 'pass' | 'fail' | 'none';
37
+ dkimDomain: string;
38
+ dmarc: 'pass' | 'fail' | 'none';
39
+ dmarcPolicy: string;
40
+ }
41
+ export interface IEmailDetail extends IEmail {
42
+ toList: string[];
43
+ cc?: string[];
44
+ smtpLog: ISmtpLogEntry[];
45
+ connectionInfo: IConnectionInfo;
46
+ authenticationResults: IAuthenticationResults;
47
+ rejectionReason?: string;
48
+ bounceMessage?: string;
49
+ headers: Record<string, string>;
50
+ body: string;
66
51
  }
67
- export interface IReq_GetSentEmails extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_GetSentEmails> {
68
- method: 'getSentEmails';
52
+ export interface IReq_GetAllEmails extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_GetAllEmails> {
53
+ method: 'getAllEmails';
69
54
  request: {
70
55
  identity?: authInterfaces.IIdentity;
71
- limit?: number;
72
- offset?: number;
73
56
  };
74
57
  response: {
75
- items: IEmailQueueItem[];
76
- total: number;
58
+ emails: IEmail[];
77
59
  };
78
60
  }
79
- export interface IReq_GetFailedEmails extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_GetFailedEmails> {
80
- method: 'getFailedEmails';
61
+ export interface IReq_GetEmailDetail extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_GetEmailDetail> {
62
+ method: 'getEmailDetail';
81
63
  request: {
82
64
  identity?: authInterfaces.IIdentity;
83
- limit?: number;
84
- offset?: number;
65
+ emailId: string;
85
66
  };
86
67
  response: {
87
- items: IEmailQueueItem[];
88
- total: number;
68
+ email: IEmailDetail | null;
89
69
  };
90
70
  }
91
71
  export interface IReq_ResendEmail extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_ResendEmail> {
@@ -100,40 +80,3 @@ export interface IReq_ResendEmail extends plugins.typedrequestInterfaces.impleme
100
80
  error?: string;
101
81
  };
102
82
  }
103
- export interface IReq_GetSecurityIncidents extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_GetSecurityIncidents> {
104
- method: 'getSecurityIncidents';
105
- request: {
106
- identity?: authInterfaces.IIdentity;
107
- type?: TSecurityEventType;
108
- level?: TSecurityLogLevel;
109
- limit?: number;
110
- };
111
- response: {
112
- incidents: ISecurityIncident[];
113
- total: number;
114
- };
115
- }
116
- export interface IReq_GetBounceRecords extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_GetBounceRecords> {
117
- method: 'getBounceRecords';
118
- request: {
119
- identity?: authInterfaces.IIdentity;
120
- limit?: number;
121
- offset?: number;
122
- };
123
- response: {
124
- records: IBounceRecord[];
125
- suppressionList: string[];
126
- total: number;
127
- };
128
- }
129
- export interface IReq_RemoveFromSuppressionList extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_RemoveFromSuppressionList> {
130
- method: 'removeFromSuppressionList';
131
- request: {
132
- identity?: authInterfaces.IIdentity;
133
- email: string;
134
- };
135
- response: {
136
- success: boolean;
137
- error?: string;
138
- };
139
- }
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/dcrouter',
6
- version: '7.4.2',
6
+ version: '8.0.0',
7
7
  description: 'A multifaceted routing service handling mail and SMS delivery functions.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUsc0JBQXNCO0lBQzVCLE9BQU8sRUFBRSxPQUFPO0lBQ2hCLFdBQVcsRUFBRSwwRUFBMEU7Q0FDeEYsQ0FBQSJ9
@@ -82,14 +82,7 @@ export interface ICertificateState {
82
82
  lastUpdated: number;
83
83
  }
84
84
  export interface IEmailOpsState {
85
- currentView: 'queued' | 'sent' | 'failed' | 'received' | 'security';
86
- queuedEmails: interfaces.requests.IEmailQueueItem[];
87
- sentEmails: interfaces.requests.IEmailQueueItem[];
88
- failedEmails: interfaces.requests.IEmailQueueItem[];
89
- securityIncidents: interfaces.requests.ISecurityIncident[];
90
- bounceRecords: interfaces.requests.IBounceRecord[];
91
- suppressionList: string[];
92
- selectedEmailId: string | null;
85
+ emails: interfaces.requests.IEmail[];
93
86
  isLoading: boolean;
94
87
  error: string | null;
95
88
  lastUpdated: number;
@@ -127,14 +120,7 @@ export declare const fetchRecentLogsAction: plugins.deesElement.domtools.plugins
127
120
  export declare const toggleAutoRefreshAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IUiState, unknown>;
128
121
  export declare const setActiveViewAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IUiState, string>;
129
122
  export declare const fetchNetworkStatsAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<INetworkState, unknown>;
130
- export declare const setEmailOpsViewAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IEmailOpsState, "failed" | "security" | "queued" | "sent" | "received">;
131
- export declare const fetchQueuedEmailsAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IEmailOpsState, unknown>;
132
- export declare const fetchSentEmailsAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IEmailOpsState, unknown>;
133
- export declare const fetchFailedEmailsAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IEmailOpsState, unknown>;
134
- export declare const fetchSecurityIncidentsAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IEmailOpsState, unknown>;
135
- export declare const fetchBounceRecordsAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IEmailOpsState, unknown>;
136
- export declare const resendEmailAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IEmailOpsState, string>;
137
- export declare const removeFromSuppressionListAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IEmailOpsState, string>;
123
+ export declare const fetchAllEmailsAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IEmailOpsState, unknown>;
138
124
  export declare const fetchCertificateOverviewAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<ICertificateState, unknown>;
139
125
  export declare const reprovisionCertificateAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<ICertificateState, string>;
140
126
  export declare const deleteCertificateAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<ICertificateState, string>;