@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 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: "last_check",
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: "manual",
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: "random",
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: ["last_check", "last_24h", "last_7d"], default: "last_check" },
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: ["manual", "auto"], default: "manual" },
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: ["random", "even"], default: "random" },
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;