@astralibx/email-account-manager 10.6.1 → 10.6.2
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/dist/index.cjs +53 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +53 -2
- package/dist/index.d.ts +53 -2
- package/dist/index.mjs +51 -17
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -229,6 +229,19 @@ var SES_NOTIFICATION_TYPE = {
|
|
|
229
229
|
Open: "Open",
|
|
230
230
|
Click: "Click"
|
|
231
231
|
};
|
|
232
|
+
var IMAP_SEARCH_SINCE = {
|
|
233
|
+
LastCheck: "last_check",
|
|
234
|
+
Last24h: "last_24h",
|
|
235
|
+
Last7d: "last_7d"
|
|
236
|
+
};
|
|
237
|
+
var APPROVAL_MODE = {
|
|
238
|
+
Manual: "manual",
|
|
239
|
+
Auto: "auto"
|
|
240
|
+
};
|
|
241
|
+
var SPREAD_STRATEGY = {
|
|
242
|
+
Random: "random",
|
|
243
|
+
Even: "even"
|
|
244
|
+
};
|
|
232
245
|
|
|
233
246
|
// src/schemas/email-account.schema.ts
|
|
234
247
|
function createEmailAccountSchema(options) {
|
|
@@ -400,7 +413,7 @@ function createEmailDailyStatsSchema(options) {
|
|
|
400
413
|
function createEmailIdentifierSchema(options) {
|
|
401
414
|
const schema = new mongoose.Schema(
|
|
402
415
|
{
|
|
403
|
-
email: { type: String, required: true, unique: true, lowercase: true },
|
|
416
|
+
email: { type: String, required: true, unique: true, lowercase: true, match: /^[^\s@]+@[^\s@]+\.[^\s@]+$/ },
|
|
404
417
|
status: {
|
|
405
418
|
type: String,
|
|
406
419
|
enum: Object.values(IDENTIFIER_STATUS),
|
|
@@ -434,7 +447,7 @@ function createEmailIdentifierSchema(options) {
|
|
|
434
447
|
bounceCount: 0
|
|
435
448
|
}
|
|
436
449
|
},
|
|
437
|
-
{ upsert: true, new: true }
|
|
450
|
+
{ upsert: true, new: true, runValidators: true }
|
|
438
451
|
);
|
|
439
452
|
return { identifier, created: true };
|
|
440
453
|
},
|
|
@@ -507,7 +520,16 @@ function createEmailDraftSchema(options) {
|
|
|
507
520
|
failureReason: String,
|
|
508
521
|
source: { type: String },
|
|
509
522
|
identifierId: { type: String },
|
|
510
|
-
metadata: { type: mongoose.Schema.Types.Mixed }
|
|
523
|
+
metadata: { type: mongoose.Schema.Types.Mixed },
|
|
524
|
+
attachments: {
|
|
525
|
+
type: [{
|
|
526
|
+
_id: false,
|
|
527
|
+
filename: { type: String, required: true },
|
|
528
|
+
url: { type: String, required: true },
|
|
529
|
+
contentType: { type: String, required: true }
|
|
530
|
+
}],
|
|
531
|
+
default: []
|
|
532
|
+
}
|
|
511
533
|
},
|
|
512
534
|
{
|
|
513
535
|
timestamps: true,
|
|
@@ -548,7 +570,7 @@ var DEFAULT_SETTINGS = {
|
|
|
548
570
|
imap: {
|
|
549
571
|
enabled: false,
|
|
550
572
|
pollIntervalMs: 3e5,
|
|
551
|
-
searchSince:
|
|
573
|
+
searchSince: IMAP_SEARCH_SINCE.LastCheck,
|
|
552
574
|
bounceSenders: ["mailer-daemon@googlemail.com"]
|
|
553
575
|
},
|
|
554
576
|
ses: {
|
|
@@ -558,14 +580,14 @@ var DEFAULT_SETTINGS = {
|
|
|
558
580
|
},
|
|
559
581
|
approval: {
|
|
560
582
|
enabled: false,
|
|
561
|
-
defaultMode:
|
|
583
|
+
defaultMode: APPROVAL_MODE.Manual,
|
|
562
584
|
autoApproveDelayMs: 0,
|
|
563
585
|
sendWindow: {
|
|
564
586
|
timezone: "UTC",
|
|
565
587
|
startHour: 9,
|
|
566
588
|
endHour: 21
|
|
567
589
|
},
|
|
568
|
-
spreadStrategy:
|
|
590
|
+
spreadStrategy: SPREAD_STRATEGY.Random,
|
|
569
591
|
maxSpreadMinutes: 120
|
|
570
592
|
},
|
|
571
593
|
unsubscribePage: {
|
|
@@ -599,7 +621,7 @@ function createGlobalSettingsSchema(options) {
|
|
|
599
621
|
type: {
|
|
600
622
|
enabled: { type: Boolean, default: false },
|
|
601
623
|
pollIntervalMs: { type: Number, default: 3e5 },
|
|
602
|
-
searchSince: { type: String, enum:
|
|
624
|
+
searchSince: { type: String, enum: Object.values(IMAP_SEARCH_SINCE), default: IMAP_SEARCH_SINCE.LastCheck },
|
|
603
625
|
bounceSenders: [{ type: String }]
|
|
604
626
|
},
|
|
605
627
|
default: () => ({ ...DEFAULT_SETTINGS.imap }),
|
|
@@ -617,7 +639,7 @@ function createGlobalSettingsSchema(options) {
|
|
|
617
639
|
approval: {
|
|
618
640
|
type: {
|
|
619
641
|
enabled: { type: Boolean, default: false },
|
|
620
|
-
defaultMode: { type: String, enum:
|
|
642
|
+
defaultMode: { type: String, enum: Object.values(APPROVAL_MODE), default: APPROVAL_MODE.Manual },
|
|
621
643
|
autoApproveDelayMs: { type: Number, default: 0 },
|
|
622
644
|
sendWindow: {
|
|
623
645
|
type: {
|
|
@@ -627,7 +649,7 @@ function createGlobalSettingsSchema(options) {
|
|
|
627
649
|
},
|
|
628
650
|
_id: false
|
|
629
651
|
},
|
|
630
|
-
spreadStrategy: { type: String, enum:
|
|
652
|
+
spreadStrategy: { type: String, enum: Object.values(SPREAD_STRATEGY), default: SPREAD_STRATEGY.Random },
|
|
631
653
|
maxSpreadMinutes: { type: Number, default: 120 }
|
|
632
654
|
},
|
|
633
655
|
default: () => ({ ...DEFAULT_SETTINGS.approval, sendWindow: { ...DEFAULT_SETTINGS.approval.sendWindow } }),
|
|
@@ -786,14 +808,18 @@ function flattenObject(obj, prefix = "") {
|
|
|
786
808
|
}
|
|
787
809
|
|
|
788
810
|
// src/services/identifier.service.ts
|
|
789
|
-
var IdentifierService = class {
|
|
811
|
+
var IdentifierService = class _IdentifierService {
|
|
790
812
|
constructor(EmailIdentifier, logger, hooks) {
|
|
791
813
|
this.EmailIdentifier = EmailIdentifier;
|
|
792
814
|
this.logger = logger;
|
|
793
815
|
this.hooks = hooks;
|
|
794
816
|
}
|
|
817
|
+
static EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
795
818
|
async findOrCreate(email) {
|
|
796
819
|
const normalized = email.toLowerCase().trim();
|
|
820
|
+
if (!_IdentifierService.EMAIL_REGEX.test(normalized)) {
|
|
821
|
+
throw new Error(`Invalid email format: "${normalized}"`);
|
|
822
|
+
}
|
|
797
823
|
const doc = await this.EmailIdentifier.findOneAndUpdate(
|
|
798
824
|
{ email: normalized },
|
|
799
825
|
{
|
|
@@ -1561,7 +1587,8 @@ var SmtpService = class {
|
|
|
1561
1587
|
html: params.html,
|
|
1562
1588
|
text: params.text || "",
|
|
1563
1589
|
unsubscribeUrl: unsubscribeUrl || void 0,
|
|
1564
|
-
metadata: params.metadata
|
|
1590
|
+
metadata: params.metadata,
|
|
1591
|
+
attachments: params.attachments || []
|
|
1565
1592
|
});
|
|
1566
1593
|
return { success: true, messageId: jobId };
|
|
1567
1594
|
}
|
|
@@ -1579,7 +1606,7 @@ var SmtpService = class {
|
|
|
1579
1606
|
return { success: false, error: message };
|
|
1580
1607
|
}
|
|
1581
1608
|
}
|
|
1582
|
-
async executeSend(accountId, to, subject, html, text2, unsubscribeUrl) {
|
|
1609
|
+
async executeSend(accountId, to, subject, html, text2, unsubscribeUrl, attachments) {
|
|
1583
1610
|
const account = await this.EmailAccount.findById(accountId);
|
|
1584
1611
|
if (!account) return { success: false, error: "Account not found" };
|
|
1585
1612
|
const acct = account;
|
|
@@ -1607,7 +1634,12 @@ var SmtpService = class {
|
|
|
1607
1634
|
subject,
|
|
1608
1635
|
text: text2,
|
|
1609
1636
|
html,
|
|
1610
|
-
headers
|
|
1637
|
+
headers,
|
|
1638
|
+
attachments: attachments?.map((a) => ({
|
|
1639
|
+
filename: a.filename,
|
|
1640
|
+
path: a.url,
|
|
1641
|
+
contentType: a.contentType
|
|
1642
|
+
})) || []
|
|
1611
1643
|
};
|
|
1612
1644
|
const info = await transporter.sendMail(mailOptions);
|
|
1613
1645
|
const messageId = info.messageId?.replace(/[<>]/g, "");
|
|
@@ -1765,6 +1797,7 @@ var ApprovalService = class {
|
|
|
1765
1797
|
if (content.subject !== void 0) updates.subject = content.subject;
|
|
1766
1798
|
if (content.htmlBody !== void 0) updates.htmlBody = content.htmlBody;
|
|
1767
1799
|
if (content.textBody !== void 0) updates.textBody = content.textBody;
|
|
1800
|
+
if (content.attachments !== void 0) updates.attachments = content.attachments;
|
|
1768
1801
|
const draft = await this.EmailDraft.findByIdAndUpdate(
|
|
1769
1802
|
draftId,
|
|
1770
1803
|
{ $set: updates },
|
|
@@ -2205,9 +2238,9 @@ var SesWebhookHandler = class {
|
|
|
2205
2238
|
// src/queues/send.queue.ts
|
|
2206
2239
|
function createSendProcessor(smtpService, logger) {
|
|
2207
2240
|
return async (job) => {
|
|
2208
|
-
const { accountId, to, subject, html, text: text2, unsubscribeUrl } = job.data;
|
|
2241
|
+
const { accountId, to, subject, html, text: text2, unsubscribeUrl, attachments } = job.data;
|
|
2209
2242
|
logger.info("Processing send job", { jobId: job.id, accountId, to });
|
|
2210
|
-
const result = await smtpService.executeSend(accountId, to, subject, html, text2, unsubscribeUrl);
|
|
2243
|
+
const result = await smtpService.executeSend(accountId, to, subject, html, text2, unsubscribeUrl, attachments);
|
|
2211
2244
|
if (!result.success) {
|
|
2212
2245
|
throw new Error(result.error || "Send failed");
|
|
2213
2246
|
}
|
|
@@ -2237,7 +2270,8 @@ function createApprovalProcessor(EmailDraft, smtpService, queueService, logger,
|
|
|
2237
2270
|
to: d.to,
|
|
2238
2271
|
subject: d.subject,
|
|
2239
2272
|
html: d.htmlBody,
|
|
2240
|
-
text: d.textBody || ""
|
|
2273
|
+
text: d.textBody || "",
|
|
2274
|
+
attachments: d.attachments || []
|
|
2241
2275
|
});
|
|
2242
2276
|
if (d.identifierId && identifierService) {
|
|
2243
2277
|
await identifierService.incrementSentCount(d.to);
|
|
@@ -3060,6 +3094,7 @@ function createEmailAccountManager(config) {
|
|
|
3060
3094
|
|
|
3061
3095
|
exports.ACCOUNT_PROVIDER = ACCOUNT_PROVIDER;
|
|
3062
3096
|
exports.ACCOUNT_STATUS = ACCOUNT_STATUS;
|
|
3097
|
+
exports.APPROVAL_MODE = APPROVAL_MODE;
|
|
3063
3098
|
exports.AccountDisabledError = AccountDisabledError;
|
|
3064
3099
|
exports.AccountNotFoundError = AccountNotFoundError;
|
|
3065
3100
|
exports.AlxAccountError = AlxAccountError;
|
|
@@ -3072,6 +3107,7 @@ exports.DraftNotFoundError = DraftNotFoundError;
|
|
|
3072
3107
|
exports.EMAIL_EVENT_TYPE = EMAIL_EVENT_TYPE;
|
|
3073
3108
|
exports.HealthTracker = HealthTracker;
|
|
3074
3109
|
exports.IDENTIFIER_STATUS = IDENTIFIER_STATUS;
|
|
3110
|
+
exports.IMAP_SEARCH_SINCE = IMAP_SEARCH_SINCE;
|
|
3075
3111
|
exports.IdentifierService = IdentifierService;
|
|
3076
3112
|
exports.ImapBounceChecker = ImapBounceChecker;
|
|
3077
3113
|
exports.InvalidTokenError = InvalidTokenError;
|
|
@@ -3082,6 +3118,7 @@ exports.SES_BOUNCE_TYPE = SES_BOUNCE_TYPE;
|
|
|
3082
3118
|
exports.SES_COMPLAINT_TYPE = SES_COMPLAINT_TYPE;
|
|
3083
3119
|
exports.SES_NOTIFICATION_TYPE = SES_NOTIFICATION_TYPE;
|
|
3084
3120
|
exports.SNS_MESSAGE_TYPE = SNS_MESSAGE_TYPE;
|
|
3121
|
+
exports.SPREAD_STRATEGY = SPREAD_STRATEGY;
|
|
3085
3122
|
exports.SesWebhookHandler = SesWebhookHandler;
|
|
3086
3123
|
exports.SettingsService = SettingsService;
|
|
3087
3124
|
exports.SmtpConnectionError = SmtpConnectionError;
|