@bernierllc/email-sender-manager 1.0.1
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/LICENSE +5 -0
- package/README.md +466 -0
- package/dist/__tests__/manager.test.d.ts +2 -0
- package/dist/__tests__/manager.test.d.ts.map +1 -0
- package/dist/__tests__/manager.test.js +344 -0
- package/dist/__tests__/manager.test.js.map +1 -0
- package/dist/__tests__/mocks/mock-database.d.ts +15 -0
- package/dist/__tests__/mocks/mock-database.d.ts.map +1 -0
- package/dist/__tests__/mocks/mock-database.js +219 -0
- package/dist/__tests__/mocks/mock-database.js.map +1 -0
- package/dist/__tests__/selection/selector.test.d.ts +2 -0
- package/dist/__tests__/selection/selector.test.d.ts.map +1 -0
- package/dist/__tests__/selection/selector.test.js +351 -0
- package/dist/__tests__/selection/selector.test.js.map +1 -0
- package/dist/__tests__/utils/domain-utils.test.d.ts +2 -0
- package/dist/__tests__/utils/domain-utils.test.d.ts.map +1 -0
- package/dist/__tests__/utils/domain-utils.test.js +91 -0
- package/dist/__tests__/utils/domain-utils.test.js.map +1 -0
- package/dist/__tests__/utils/validation-utils.test.d.ts +2 -0
- package/dist/__tests__/utils/validation-utils.test.d.ts.map +1 -0
- package/dist/__tests__/utils/validation-utils.test.js +117 -0
- package/dist/__tests__/utils/validation-utils.test.js.map +1 -0
- package/dist/database/bootstrap.d.ts +35 -0
- package/dist/database/bootstrap.d.ts.map +1 -0
- package/dist/database/bootstrap.js +183 -0
- package/dist/database/bootstrap.js.map +1 -0
- package/dist/database/schema.d.ts +13 -0
- package/dist/database/schema.d.ts.map +1 -0
- package/dist/database/schema.js +72 -0
- package/dist/database/schema.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/manager.d.ts +85 -0
- package/dist/manager.d.ts.map +1 -0
- package/dist/manager.js +469 -0
- package/dist/manager.js.map +1 -0
- package/dist/selection/selector.d.ts +27 -0
- package/dist/selection/selector.d.ts.map +1 -0
- package/dist/selection/selector.js +107 -0
- package/dist/selection/selector.js.map +1 -0
- package/dist/types.d.ts +257 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/domain-utils.d.ts +21 -0
- package/dist/utils/domain-utils.d.ts.map +1 -0
- package/dist/utils/domain-utils.js +65 -0
- package/dist/utils/domain-utils.js.map +1 -0
- package/dist/utils/validation-utils.d.ts +23 -0
- package/dist/utils/validation-utils.d.ts.map +1 -0
- package/dist/utils/validation-utils.js +148 -0
- package/dist/utils/validation-utils.js.map +1 -0
- package/package.json +49 -0
package/dist/manager.js
ADDED
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2025 Bernier LLC
|
|
3
|
+
|
|
4
|
+
This file is licensed to the client under a limited-use license.
|
|
5
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
6
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
7
|
+
*/
|
|
8
|
+
import { SenderBootstrap } from './database/bootstrap.js';
|
|
9
|
+
import { SenderSelector } from './selection/selector.js';
|
|
10
|
+
import { extractDomain } from './utils/domain-utils.js';
|
|
11
|
+
import { validateCreateSenderRequest, validateSenderConfiguration, } from './utils/validation-utils.js';
|
|
12
|
+
export class EmailSenderManager {
|
|
13
|
+
database;
|
|
14
|
+
providers = new Map();
|
|
15
|
+
bootstrap;
|
|
16
|
+
selector;
|
|
17
|
+
bootstrapConfig;
|
|
18
|
+
// @ts-expect-error - Reserved for future validation features
|
|
19
|
+
validationConfig;
|
|
20
|
+
selectionConfig;
|
|
21
|
+
systemUser;
|
|
22
|
+
constructor(config) {
|
|
23
|
+
this.database = config.database;
|
|
24
|
+
this.systemUser = config.systemUser ?? 'system';
|
|
25
|
+
// Initialize configurations with defaults
|
|
26
|
+
this.bootstrapConfig = {
|
|
27
|
+
enabled: false,
|
|
28
|
+
createTables: false,
|
|
29
|
+
seedDefaultSenders: false,
|
|
30
|
+
defaultSenders: [],
|
|
31
|
+
environment: 'production',
|
|
32
|
+
...config.bootstrap,
|
|
33
|
+
};
|
|
34
|
+
this.validationConfig = {
|
|
35
|
+
requireVerification: false,
|
|
36
|
+
allowUnverifiedSenders: true,
|
|
37
|
+
validateDomainOwnership: false,
|
|
38
|
+
...config.validation,
|
|
39
|
+
};
|
|
40
|
+
this.selectionConfig = {
|
|
41
|
+
strategy: 'priority',
|
|
42
|
+
fallbackToDefault: true,
|
|
43
|
+
domainMatchingRules: [],
|
|
44
|
+
...config.selection,
|
|
45
|
+
};
|
|
46
|
+
// Initialize bootstrap system
|
|
47
|
+
this.bootstrap = new SenderBootstrap(this.database, this.bootstrapConfig);
|
|
48
|
+
// Initialize selector
|
|
49
|
+
this.selector = new SenderSelector(this.selectionConfig);
|
|
50
|
+
// Register providers
|
|
51
|
+
if (config.providers) {
|
|
52
|
+
for (const provider of config.providers) {
|
|
53
|
+
this.providers.set(provider.providerId, provider);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Bootstrap database and seed default senders
|
|
59
|
+
*/
|
|
60
|
+
async bootstrapDatabase() {
|
|
61
|
+
if (!this.bootstrapConfig.enabled) {
|
|
62
|
+
return {
|
|
63
|
+
success: false,
|
|
64
|
+
tablesCreated: false,
|
|
65
|
+
seedersRun: 0,
|
|
66
|
+
message: 'Bootstrap is not enabled in configuration',
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return await this.bootstrap.bootstrap();
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create a new sender configuration
|
|
73
|
+
*/
|
|
74
|
+
async createSender(request) {
|
|
75
|
+
// Validate request
|
|
76
|
+
const validation = validateCreateSenderRequest(request);
|
|
77
|
+
if (validation.errors.length > 0) {
|
|
78
|
+
throw new Error(`Validation failed: ${validation.errors.map((e) => e.message).join(', ')}`);
|
|
79
|
+
}
|
|
80
|
+
// Validate domain configuration
|
|
81
|
+
const domainValidation = validateSenderConfiguration(request.fromEmail, request.allowedDomains);
|
|
82
|
+
if (!domainValidation.valid) {
|
|
83
|
+
throw new Error(`Domain validation failed: ${domainValidation.errors.map((e) => e.message).join(', ')}`);
|
|
84
|
+
}
|
|
85
|
+
const id = this.generateId();
|
|
86
|
+
const domain = extractDomain(request.fromEmail);
|
|
87
|
+
const now = new Date();
|
|
88
|
+
const sender = {
|
|
89
|
+
id,
|
|
90
|
+
name: request.name,
|
|
91
|
+
...(request.description !== undefined && { description: request.description }),
|
|
92
|
+
fromEmail: request.fromEmail,
|
|
93
|
+
fromName: request.fromName,
|
|
94
|
+
...(request.replyToEmail !== undefined && { replyToEmail: request.replyToEmail }),
|
|
95
|
+
...(request.replyToName !== undefined && { replyToName: request.replyToName }),
|
|
96
|
+
provider: request.provider,
|
|
97
|
+
...(request.providerSenderId !== undefined && { providerSenderId: request.providerSenderId }),
|
|
98
|
+
...(request.providerMetadata !== undefined && { providerMetadata: request.providerMetadata }),
|
|
99
|
+
isVerified: false,
|
|
100
|
+
verificationStatus: 'pending',
|
|
101
|
+
isDefault: false,
|
|
102
|
+
isActive: true,
|
|
103
|
+
priority: request.priority ?? 100,
|
|
104
|
+
...(request.allowedDomains !== undefined && { allowedDomains: request.allowedDomains }),
|
|
105
|
+
domain,
|
|
106
|
+
createdAt: now,
|
|
107
|
+
updatedAt: now,
|
|
108
|
+
createdBy: request.createdBy,
|
|
109
|
+
lastModifiedBy: request.createdBy,
|
|
110
|
+
};
|
|
111
|
+
await this.database.execute(`INSERT INTO email_senders (
|
|
112
|
+
id, name, description, from_email, from_name, reply_to_email, reply_to_name,
|
|
113
|
+
provider, provider_sender_id, provider_metadata,
|
|
114
|
+
is_verified, verification_status, is_default, is_active, priority,
|
|
115
|
+
allowed_domains, domain, created_at, updated_at, created_by, last_modified_by
|
|
116
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
117
|
+
sender.id,
|
|
118
|
+
sender.name,
|
|
119
|
+
sender.description ?? null,
|
|
120
|
+
sender.fromEmail,
|
|
121
|
+
sender.fromName,
|
|
122
|
+
sender.replyToEmail ?? null,
|
|
123
|
+
sender.replyToName ?? null,
|
|
124
|
+
sender.provider,
|
|
125
|
+
sender.providerSenderId ?? null,
|
|
126
|
+
sender.providerMetadata ? JSON.stringify(sender.providerMetadata) : null,
|
|
127
|
+
sender.isVerified,
|
|
128
|
+
sender.verificationStatus,
|
|
129
|
+
sender.isDefault,
|
|
130
|
+
sender.isActive,
|
|
131
|
+
sender.priority,
|
|
132
|
+
sender.allowedDomains ? JSON.stringify(sender.allowedDomains) : null,
|
|
133
|
+
sender.domain,
|
|
134
|
+
sender.createdAt,
|
|
135
|
+
sender.updatedAt,
|
|
136
|
+
sender.createdBy,
|
|
137
|
+
sender.lastModifiedBy,
|
|
138
|
+
]);
|
|
139
|
+
return sender;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Update an existing sender
|
|
143
|
+
*/
|
|
144
|
+
async updateSender(id, updates) {
|
|
145
|
+
const existing = await this.getSender(id);
|
|
146
|
+
if (!existing) {
|
|
147
|
+
throw new Error(`Sender not found: ${id}`);
|
|
148
|
+
}
|
|
149
|
+
const now = new Date();
|
|
150
|
+
const updatedSender = {
|
|
151
|
+
...existing,
|
|
152
|
+
...updates,
|
|
153
|
+
updatedAt: now,
|
|
154
|
+
};
|
|
155
|
+
await this.database.execute(`UPDATE email_senders SET
|
|
156
|
+
name = ?, description = ?, from_name = ?, reply_to_email = ?, reply_to_name = ?,
|
|
157
|
+
provider_sender_id = ?, provider_metadata = ?,
|
|
158
|
+
is_verified = ?, verification_status = ?, last_verified_at = ?, verification_error = ?,
|
|
159
|
+
is_default = ?, is_active = ?, priority = ?, allowed_domains = ?,
|
|
160
|
+
updated_at = ?, last_modified_by = ?
|
|
161
|
+
WHERE id = ?`, [
|
|
162
|
+
updatedSender.name,
|
|
163
|
+
updatedSender.description ?? null,
|
|
164
|
+
updatedSender.fromName,
|
|
165
|
+
updatedSender.replyToEmail ?? null,
|
|
166
|
+
updatedSender.replyToName ?? null,
|
|
167
|
+
updatedSender.providerSenderId ?? null,
|
|
168
|
+
updatedSender.providerMetadata ? JSON.stringify(updatedSender.providerMetadata) : null,
|
|
169
|
+
updatedSender.isVerified,
|
|
170
|
+
updatedSender.verificationStatus,
|
|
171
|
+
updatedSender.lastVerifiedAt ?? null,
|
|
172
|
+
updatedSender.verificationError ?? null,
|
|
173
|
+
updatedSender.isDefault,
|
|
174
|
+
updatedSender.isActive,
|
|
175
|
+
updatedSender.priority,
|
|
176
|
+
updatedSender.allowedDomains ? JSON.stringify(updatedSender.allowedDomains) : null,
|
|
177
|
+
updatedSender.updatedAt,
|
|
178
|
+
updates.lastModifiedBy,
|
|
179
|
+
id,
|
|
180
|
+
]);
|
|
181
|
+
return updatedSender;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Delete a sender
|
|
185
|
+
*/
|
|
186
|
+
async deleteSender(id) {
|
|
187
|
+
await this.database.execute('DELETE FROM email_senders WHERE id = ?', [id]);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Get a single sender by ID
|
|
191
|
+
*/
|
|
192
|
+
async getSender(id) {
|
|
193
|
+
const row = await this.database.queryOne('SELECT * FROM email_senders WHERE id = ?', [id]);
|
|
194
|
+
return row ? this.mapRowToSender(row) : null;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* List senders with pagination and filtering
|
|
198
|
+
*/
|
|
199
|
+
async listSenders(options = {}) {
|
|
200
|
+
const { provider, isActive, isVerified, domain, offset = 0, limit = 50, orderBy = 'priority', orderDirection = 'asc', } = options;
|
|
201
|
+
const conditions = [];
|
|
202
|
+
const params = [];
|
|
203
|
+
if (provider) {
|
|
204
|
+
conditions.push('provider = ?');
|
|
205
|
+
params.push(provider);
|
|
206
|
+
}
|
|
207
|
+
if (isActive !== undefined) {
|
|
208
|
+
conditions.push('is_active = ?');
|
|
209
|
+
params.push(isActive);
|
|
210
|
+
}
|
|
211
|
+
if (isVerified !== undefined) {
|
|
212
|
+
conditions.push('is_verified = ?');
|
|
213
|
+
params.push(isVerified);
|
|
214
|
+
}
|
|
215
|
+
if (domain) {
|
|
216
|
+
conditions.push('domain = ?');
|
|
217
|
+
params.push(domain);
|
|
218
|
+
}
|
|
219
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
220
|
+
const orderClause = `ORDER BY ${orderBy} ${orderDirection.toUpperCase()}`;
|
|
221
|
+
// Get total count
|
|
222
|
+
const countResult = await this.database.queryOne(`SELECT COUNT(*) as count FROM email_senders ${whereClause}`, params);
|
|
223
|
+
const total = countResult?.count ?? 0;
|
|
224
|
+
// Get paginated results
|
|
225
|
+
const rows = await this.database.query(`SELECT * FROM email_senders ${whereClause} ${orderClause} LIMIT ? OFFSET ?`, [...params, limit, offset]);
|
|
226
|
+
const items = rows.map((row) => this.mapRowToSender(row));
|
|
227
|
+
return {
|
|
228
|
+
items,
|
|
229
|
+
total,
|
|
230
|
+
offset,
|
|
231
|
+
limit,
|
|
232
|
+
hasMore: offset + items.length < total,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Validate a sender configuration
|
|
237
|
+
*/
|
|
238
|
+
async validateSender(id) {
|
|
239
|
+
const sender = await this.getSender(id);
|
|
240
|
+
if (!sender) {
|
|
241
|
+
return {
|
|
242
|
+
isValid: false,
|
|
243
|
+
errors: [{ field: 'id', message: 'Sender not found', code: 'NOT_FOUND' }],
|
|
244
|
+
warnings: [],
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
const validation = validateSenderConfiguration(sender.fromEmail, sender.allowedDomains);
|
|
248
|
+
return {
|
|
249
|
+
isValid: validation.valid,
|
|
250
|
+
errors: validation.errors,
|
|
251
|
+
warnings: [],
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Verify sender with provider
|
|
256
|
+
*/
|
|
257
|
+
async verifySender(id, providerId) {
|
|
258
|
+
const sender = await this.getSender(id);
|
|
259
|
+
if (!sender) {
|
|
260
|
+
return {
|
|
261
|
+
success: false,
|
|
262
|
+
isVerified: false,
|
|
263
|
+
verificationStatus: 'not_found',
|
|
264
|
+
error: 'Sender not found',
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
const provId = providerId ?? sender.provider;
|
|
268
|
+
const provider = this.providers.get(provId);
|
|
269
|
+
if (!provider) {
|
|
270
|
+
return {
|
|
271
|
+
success: false,
|
|
272
|
+
isVerified: false,
|
|
273
|
+
verificationStatus: 'provider_not_found',
|
|
274
|
+
error: `Provider not found: ${provId}`,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
try {
|
|
278
|
+
const validation = await provider.validateSender(sender.fromEmail);
|
|
279
|
+
await this.updateSender(id, {
|
|
280
|
+
isVerified: validation.isVerified,
|
|
281
|
+
verificationStatus: validation.verificationStatus,
|
|
282
|
+
lastVerifiedAt: validation.lastChecked,
|
|
283
|
+
lastModifiedBy: this.systemUser,
|
|
284
|
+
});
|
|
285
|
+
return {
|
|
286
|
+
success: true,
|
|
287
|
+
isVerified: validation.isVerified,
|
|
288
|
+
verificationStatus: validation.verificationStatus,
|
|
289
|
+
message: validation.isVerified ? 'Sender verified successfully' : 'Sender verification failed',
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
return {
|
|
294
|
+
success: false,
|
|
295
|
+
isVerified: false,
|
|
296
|
+
verificationStatus: 'error',
|
|
297
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Refresh verification status from provider
|
|
303
|
+
*/
|
|
304
|
+
async refreshVerificationStatus(id) {
|
|
305
|
+
const verification = await this.verifySender(id);
|
|
306
|
+
if (!verification.success) {
|
|
307
|
+
throw new Error(`Failed to refresh verification: ${verification.error}`);
|
|
308
|
+
}
|
|
309
|
+
const sender = await this.getSender(id);
|
|
310
|
+
if (!sender) {
|
|
311
|
+
throw new Error(`Sender not found: ${id}`);
|
|
312
|
+
}
|
|
313
|
+
return sender;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Select best sender for an email address
|
|
317
|
+
*/
|
|
318
|
+
async selectBestSender(fromEmail, options = {}) {
|
|
319
|
+
const domain = extractDomain(fromEmail);
|
|
320
|
+
// Get all active senders
|
|
321
|
+
const result = await this.listSenders({
|
|
322
|
+
isActive: true,
|
|
323
|
+
limit: 1000,
|
|
324
|
+
});
|
|
325
|
+
let candidates = result.items;
|
|
326
|
+
// Apply filters
|
|
327
|
+
candidates = this.selector.filterCandidates(candidates, options);
|
|
328
|
+
if (candidates.length === 0) {
|
|
329
|
+
return this.selectionConfig.fallbackToDefault ? await this.getDefaultSender() : null;
|
|
330
|
+
}
|
|
331
|
+
return this.selector.selectBestSender(candidates, domain, options);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Get the default sender
|
|
335
|
+
*/
|
|
336
|
+
async getDefaultSender(provider) {
|
|
337
|
+
const conditions = ['is_default = TRUE', 'is_active = TRUE'];
|
|
338
|
+
const params = [];
|
|
339
|
+
if (provider) {
|
|
340
|
+
conditions.push('provider = ?');
|
|
341
|
+
params.push(provider);
|
|
342
|
+
}
|
|
343
|
+
const row = await this.database.queryOne(`SELECT * FROM email_senders WHERE ${conditions.join(' AND ')} LIMIT 1`, params);
|
|
344
|
+
return row ? this.mapRowToSender(row) : null;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Get senders by domain
|
|
348
|
+
*/
|
|
349
|
+
async getSendersByDomain(domain) {
|
|
350
|
+
const result = await this.listSenders({ domain, limit: 1000 });
|
|
351
|
+
return result.items;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Register a provider plugin
|
|
355
|
+
*/
|
|
356
|
+
async registerProvider(provider) {
|
|
357
|
+
this.providers.set(provider.providerId, provider);
|
|
358
|
+
// Sync existing senders with this provider
|
|
359
|
+
const result = await this.listSenders({ provider: provider.providerId, limit: 1000 });
|
|
360
|
+
for (const sender of result.items) {
|
|
361
|
+
await this.refreshVerificationStatus(sender.id);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Get provider senders
|
|
366
|
+
*/
|
|
367
|
+
async getProviderSenders(providerId) {
|
|
368
|
+
const provider = this.providers.get(providerId);
|
|
369
|
+
if (!provider) {
|
|
370
|
+
throw new Error(`Provider not found: ${providerId}`);
|
|
371
|
+
}
|
|
372
|
+
return await provider.getVerifiedSenders();
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Sync with all providers
|
|
376
|
+
*/
|
|
377
|
+
async syncWithProviders() {
|
|
378
|
+
const results = [];
|
|
379
|
+
for (const [providerId, provider] of this.providers) {
|
|
380
|
+
const senders = await this.listSenders({ provider: providerId, limit: 1000 });
|
|
381
|
+
for (const sender of senders.items) {
|
|
382
|
+
try {
|
|
383
|
+
const syncResult = await provider.syncSender(sender);
|
|
384
|
+
results.push(syncResult);
|
|
385
|
+
}
|
|
386
|
+
catch (error) {
|
|
387
|
+
results.push({
|
|
388
|
+
success: false,
|
|
389
|
+
senderId: sender.id,
|
|
390
|
+
synced: false,
|
|
391
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return results;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Clean up inactive senders
|
|
400
|
+
*/
|
|
401
|
+
async cleanupInactiveSenders() {
|
|
402
|
+
const result = await this.database.query('SELECT id FROM email_senders WHERE is_active = FALSE');
|
|
403
|
+
let deletedCount = 0;
|
|
404
|
+
for (const row of result) {
|
|
405
|
+
await this.deleteSender(row.id);
|
|
406
|
+
deletedCount++;
|
|
407
|
+
}
|
|
408
|
+
return {
|
|
409
|
+
success: true,
|
|
410
|
+
deletedCount,
|
|
411
|
+
message: `Cleaned up ${deletedCount} inactive sender(s)`,
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Map database row to SenderConfiguration
|
|
416
|
+
*/
|
|
417
|
+
mapRowToSender(row) {
|
|
418
|
+
const sender = {
|
|
419
|
+
id: row.id,
|
|
420
|
+
name: row.name,
|
|
421
|
+
fromEmail: row.from_email,
|
|
422
|
+
fromName: row.from_name,
|
|
423
|
+
provider: row.provider,
|
|
424
|
+
isVerified: Boolean(row.is_verified),
|
|
425
|
+
verificationStatus: row.verification_status,
|
|
426
|
+
isDefault: Boolean(row.is_default),
|
|
427
|
+
isActive: Boolean(row.is_active),
|
|
428
|
+
priority: row.priority,
|
|
429
|
+
domain: row.domain,
|
|
430
|
+
createdAt: new Date(row.created_at),
|
|
431
|
+
updatedAt: new Date(row.updated_at),
|
|
432
|
+
createdBy: row.created_by,
|
|
433
|
+
lastModifiedBy: row.last_modified_by,
|
|
434
|
+
};
|
|
435
|
+
// Add optional properties only if they exist
|
|
436
|
+
if (row.description !== null && row.description !== undefined) {
|
|
437
|
+
sender.description = row.description;
|
|
438
|
+
}
|
|
439
|
+
if (row.reply_to_email !== null && row.reply_to_email !== undefined) {
|
|
440
|
+
sender.replyToEmail = row.reply_to_email;
|
|
441
|
+
}
|
|
442
|
+
if (row.reply_to_name !== null && row.reply_to_name !== undefined) {
|
|
443
|
+
sender.replyToName = row.reply_to_name;
|
|
444
|
+
}
|
|
445
|
+
if (row.provider_sender_id !== null && row.provider_sender_id !== undefined) {
|
|
446
|
+
sender.providerSenderId = row.provider_sender_id;
|
|
447
|
+
}
|
|
448
|
+
if (row.provider_metadata !== null && row.provider_metadata !== undefined) {
|
|
449
|
+
sender.providerMetadata = JSON.parse(row.provider_metadata);
|
|
450
|
+
}
|
|
451
|
+
if (row.last_verified_at !== null && row.last_verified_at !== undefined) {
|
|
452
|
+
sender.lastVerifiedAt = new Date(row.last_verified_at);
|
|
453
|
+
}
|
|
454
|
+
if (row.verification_error !== null && row.verification_error !== undefined) {
|
|
455
|
+
sender.verificationError = row.verification_error;
|
|
456
|
+
}
|
|
457
|
+
if (row.allowed_domains !== null && row.allowed_domains !== undefined) {
|
|
458
|
+
sender.allowedDomains = JSON.parse(row.allowed_domains);
|
|
459
|
+
}
|
|
460
|
+
return sender;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Generate unique sender ID
|
|
464
|
+
*/
|
|
465
|
+
generateId() {
|
|
466
|
+
return `sender_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { SenderConfiguration, SelectionOptions, SelectionConfig } from '../types.js';
|
|
2
|
+
export declare class SenderSelector {
|
|
3
|
+
private config;
|
|
4
|
+
private roundRobinCounters;
|
|
5
|
+
constructor(config: SelectionConfig);
|
|
6
|
+
/**
|
|
7
|
+
* Select best sender from candidates
|
|
8
|
+
*/
|
|
9
|
+
selectBestSender(candidates: SenderConfiguration[], domain: string, options?: SelectionOptions): SenderConfiguration | null;
|
|
10
|
+
/**
|
|
11
|
+
* Select sender by domain matching
|
|
12
|
+
*/
|
|
13
|
+
private selectByDomainMatch;
|
|
14
|
+
/**
|
|
15
|
+
* Select sender by priority
|
|
16
|
+
*/
|
|
17
|
+
private selectByPriority;
|
|
18
|
+
/**
|
|
19
|
+
* Select sender using round-robin
|
|
20
|
+
*/
|
|
21
|
+
private selectRoundRobin;
|
|
22
|
+
/**
|
|
23
|
+
* Filter candidates by selection options
|
|
24
|
+
*/
|
|
25
|
+
filterCandidates(candidates: SenderConfiguration[], options: SelectionOptions): SenderConfiguration[];
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=selector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector.d.ts","sourceRoot":"","sources":["../../src/selection/selector.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG1F,qBAAa,cAAc;IAGb,OAAO,CAAC,MAAM;IAF1B,OAAO,CAAC,kBAAkB,CAAkC;gBAExC,MAAM,EAAE,eAAe;IAE3C;;OAEG;IACH,gBAAgB,CACd,UAAU,EAAE,mBAAmB,EAAE,EACjC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,gBAAqB,GAC7B,mBAAmB,GAAG,IAAI;IAmB7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA+B3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAsBxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;OAEG;IACH,gBAAgB,CACd,UAAU,EAAE,mBAAmB,EAAE,EACjC,OAAO,EAAE,gBAAgB,GACxB,mBAAmB,EAAE;CAoBzB"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2025 Bernier LLC
|
|
3
|
+
|
|
4
|
+
This file is licensed to the client under a limited-use license.
|
|
5
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
6
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
7
|
+
*/
|
|
8
|
+
import { isDomainMatch } from '../utils/domain-utils.js';
|
|
9
|
+
export class SenderSelector {
|
|
10
|
+
config;
|
|
11
|
+
roundRobinCounters = new Map();
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Select best sender from candidates
|
|
17
|
+
*/
|
|
18
|
+
selectBestSender(candidates, domain, options = {}) {
|
|
19
|
+
if (candidates.length === 0) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const strategy = options.strategy || this.config.strategy;
|
|
23
|
+
switch (strategy) {
|
|
24
|
+
case 'domain_match':
|
|
25
|
+
return this.selectByDomainMatch(candidates, domain);
|
|
26
|
+
case 'priority':
|
|
27
|
+
return this.selectByPriority(candidates);
|
|
28
|
+
case 'round_robin':
|
|
29
|
+
return this.selectRoundRobin(candidates, domain);
|
|
30
|
+
default:
|
|
31
|
+
return candidates[0];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Select sender by domain matching
|
|
36
|
+
*/
|
|
37
|
+
selectByDomainMatch(candidates, domain) {
|
|
38
|
+
// 1. Exact domain match
|
|
39
|
+
const exactMatches = candidates.filter((sender) => sender.domain === domain);
|
|
40
|
+
if (exactMatches.length > 0) {
|
|
41
|
+
return this.selectByPriority(exactMatches);
|
|
42
|
+
}
|
|
43
|
+
// 2. Parent/subdomain match
|
|
44
|
+
const relatedMatches = candidates.filter((sender) => domain.endsWith(`.${sender.domain}`) || sender.domain.endsWith(`.${domain}`));
|
|
45
|
+
if (relatedMatches.length > 0) {
|
|
46
|
+
return this.selectByPriority(relatedMatches);
|
|
47
|
+
}
|
|
48
|
+
// 3. Allowed domains match
|
|
49
|
+
const allowedMatches = candidates.filter((sender) => sender.allowedDomains?.some((allowed) => isDomainMatch(domain, allowed)));
|
|
50
|
+
if (allowedMatches.length > 0) {
|
|
51
|
+
return this.selectByPriority(allowedMatches);
|
|
52
|
+
}
|
|
53
|
+
// 4. Fallback to priority
|
|
54
|
+
return this.selectByPriority(candidates);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Select sender by priority
|
|
58
|
+
*/
|
|
59
|
+
selectByPriority(candidates) {
|
|
60
|
+
return candidates.sort((a, b) => {
|
|
61
|
+
// Lower priority number = higher priority
|
|
62
|
+
if (a.priority !== b.priority) {
|
|
63
|
+
return a.priority - b.priority;
|
|
64
|
+
}
|
|
65
|
+
// Verified senders preferred
|
|
66
|
+
if (a.isVerified !== b.isVerified) {
|
|
67
|
+
return b.isVerified ? 1 : -1;
|
|
68
|
+
}
|
|
69
|
+
// More recently verified preferred
|
|
70
|
+
if (a.lastVerifiedAt && b.lastVerifiedAt) {
|
|
71
|
+
return b.lastVerifiedAt.getTime() - a.lastVerifiedAt.getTime();
|
|
72
|
+
}
|
|
73
|
+
// Fallback to creation order
|
|
74
|
+
return a.createdAt.getTime() - b.createdAt.getTime();
|
|
75
|
+
})[0];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Select sender using round-robin
|
|
79
|
+
*/
|
|
80
|
+
selectRoundRobin(candidates, domain) {
|
|
81
|
+
const key = `rr_${domain}`;
|
|
82
|
+
const currentIndex = this.roundRobinCounters.get(key) ?? 0;
|
|
83
|
+
const nextIndex = (currentIndex + 1) % candidates.length;
|
|
84
|
+
this.roundRobinCounters.set(key, nextIndex);
|
|
85
|
+
return candidates[currentIndex];
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Filter candidates by selection options
|
|
89
|
+
*/
|
|
90
|
+
filterCandidates(candidates, options) {
|
|
91
|
+
let filtered = [...candidates];
|
|
92
|
+
// Filter by verification status
|
|
93
|
+
if (!options.allowUnverified) {
|
|
94
|
+
filtered = filtered.filter((sender) => sender.isVerified);
|
|
95
|
+
}
|
|
96
|
+
// Filter by provider
|
|
97
|
+
if (options.provider) {
|
|
98
|
+
filtered = filtered.filter((sender) => sender.provider === options.provider);
|
|
99
|
+
}
|
|
100
|
+
// Exclude specific senders
|
|
101
|
+
if (options.excludeIds && options.excludeIds.length > 0) {
|
|
102
|
+
filtered = filtered.filter((sender) => !options.excludeIds.includes(sender.id));
|
|
103
|
+
}
|
|
104
|
+
return filtered;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=selector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector.js","sourceRoot":"","sources":["../../src/selection/selector.ts"],"names":[],"mappings":"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"}
|