@novacraft-engineering/mailbox 0.4.19 → 0.4.20

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.
Files changed (2) hide show
  1. package/lib/mailbox.ts +16 -1
  2. package/package.json +1 -1
package/lib/mailbox.ts CHANGED
@@ -573,6 +573,17 @@ const listFrom = (raw: string | undefined, fallback: Iterable<string>): Set<stri
573
573
  // Read per call, so a deployment can change any of them without a release.
574
574
  const freeProviders = () => listFrom(process.env.MAIL_FREE_PROVIDERS, FREE_MAIL_DEFAULT)
575
575
  const throwawayTlds = () => listFrom(process.env.MAIL_THROWAWAY_TLDS, THROWAWAY_TLDS_DEFAULT)
576
+
577
+ // Bulk senders put their own bounce domain in From and the real correspondent in Reply-To.
578
+ // That is how the campaign gets replies, not an attempt to redirect them somewhere unexpected.
579
+ const BULK_SENDERS_DEFAULT = new Set([
580
+ 'mailchimpapp.com', 'mcsv.net', 'rsgsv.net', 'mailchimp.com',
581
+ 'sendgrid.net', 'sendgrid.com', 'sparkpostmail.com', 'amazonses.com',
582
+ 'mailgun.org', 'mandrillapp.com', 'postmarkapp.com', 'sendinblue.com',
583
+ 'brevo.com', 'constantcontact.com', 'cmail19.com', 'createsend.com',
584
+ 'hubspotemail.net', 'mailerlite.com', 'klaviyomail.com', 'salesforce.com',
585
+ ])
586
+ const bulkSenders = () => listFrom(process.env.MAIL_BULK_SENDERS, BULK_SENDERS_DEFAULT)
576
587
  const scamPhrases = () => [...listFrom(process.env.MAIL_SCAM_PHRASES, SCAM_PHRASES_DEFAULT)]
577
588
 
578
589
  /** Weight at which a message stops being labelled and is held out of the inbox instead. */
@@ -635,7 +646,11 @@ export function judgeMessage(signals: RiskSignals, standing: SenderStanding): Ri
635
646
  .filter(entry => entry && entry !== fromDomain)
636
647
  const free = freeProviders()
637
648
  const freeReply = replyDomains.find(entry => free.has(entry))
638
- if (freeReply && fromDomain && !free.has(fromDomain)) {
649
+ const bulk = bulkSenders().has(fromDomain)
650
+ if (bulk) {
651
+ // Nothing to say: a campaign's replies are meant to land somewhere other than the
652
+ // sending platform, and treating that as misdirection buries ordinary bulk mail.
653
+ } else if (freeReply && fromDomain && !free.has(fromDomain)) {
639
654
  add(4, `Replies to this message go to ${freeReply}, not to ${fromDomain}`, true)
640
655
  } else if (replyDomains.length) {
641
656
  add(1, `Replies go to ${replyDomains[0]} rather than ${fromDomain || 'the sender'}`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@novacraft-engineering/mailbox",
3
- "version": "0.4.19",
3
+ "version": "0.4.20",
4
4
  "description": "A shared webmail app: one codebase, one deployment per mailbox. Threads, a rich composer with signatures, attachments on S3-compatible storage, sharing links, full-text search, web push and PWA install.",
5
5
  "keywords": [
6
6
  "webmail",