@bobfrankston/mailx-types 0.1.90 → 0.1.92

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/package.json +1 -1
  2. package/trust.js +45 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/mailx-types",
3
- "version": "0.1.90",
3
+ "version": "0.1.92",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
package/trust.js CHANGED
@@ -216,6 +216,30 @@ function dkimSigners(input) {
216
216
  }
217
217
  return out;
218
218
  }
219
+ /** Did the From domain's OWN organisation pass authentication at the
220
+ * receiving server — a verified signature for the From domain, or an SPF
221
+ * pass for an envelope at the From domain? This is DMARC's relaxed
222
+ * alignment computed locally, for domains that publish no DMARC policy and
223
+ * so never get a dmarc= verdict. Only the From domain's own servers can pass
224
+ * SPF as that domain or sign as it, so a forger's pass for their own domain
225
+ * does not count. Returns which proof, or "". (2026-09-09) */
226
+ function alignedPass(input) {
227
+ const fromDomain = (bare(input.fromAddress).split("@")[1] || "").toLowerCase();
228
+ if (!fromDomain)
229
+ return "";
230
+ if (dkimSigners(input).some(d => sameOrg(d, fromDomain)))
231
+ return "dkim";
232
+ const auth = headerAll(input.headerLines, "authentication-results")[0] || "";
233
+ for (const part of auth.split(";")) {
234
+ if (!/\bspf=pass\b/i.test(part))
235
+ continue;
236
+ const mailfrom = (part.match(/(?:spf|smtp)\.mailfrom=([^\s;,]+)/i)?.[1] || "").toLowerCase();
237
+ const domain = mailfrom.includes("@") ? mailfrom.split("@")[1] : mailfrom;
238
+ if (domain && sameOrg(domain, fromDomain))
239
+ return "spf";
240
+ }
241
+ return "";
242
+ }
219
243
  /** The entry in `trustedIntermediaries` that provably handled this message,
220
244
  * or "" — proof being a verified signature from its domain, or a DMARC pass
221
245
  * when it is the author. The list alone proves nothing. (2026-09-08) */
@@ -633,6 +657,27 @@ function selfSpoof(input) {
633
657
  const auth = headerAll(input.headerLines, "authentication-results").join(" ; ");
634
658
  if (!auth)
635
659
  return null;
660
+ // The From domain passed DMARC, aligned, at the receiving server: the
661
+ // message provably came from that domain, which is the opposite of a
662
+ // spoof. Checked BEFORE the failure scan because the scan reads every
663
+ // Authentication-Results and every signature — an ISOC list post
664
+ // (2026-09-09) carried dkim=pass d=elists.isoc.org, dmarc=pass
665
+ // header.from=elists.isoc.org, AND dkim=fail for the original author's
666
+ // standardstrack.com signature the list had broken, and that one fail
667
+ // painted the whole message red as "did not come from your account"
668
+ // (the list address was the Delivered-To, so it counted as Bob's own).
669
+ // One failed signature on a message with an aligned pass is not
670
+ // evidence about the From line; the pass is.
671
+ //
672
+ // The same proof without the dmarc= verdict: a From domain that publishes
673
+ // no DMARC policy gets no dmarc=pass, but its own SPF pass or its own
674
+ // verified signature is the very evidence DMARC would have aligned on.
675
+ // The AMW list (berglist.com, 2026-09-09): spf=pass for
676
+ // amw-bounces@berglist.com, dkim=pass d=berglist.com, and dkim=fail for
677
+ // the gmail.com author signature the list broke — flagged as a spoof of
678
+ // the list's own address.
679
+ if (dmarcProof(input).pass || alignedPass(input))
680
+ return null;
636
681
  const failed = [
637
682
  /\bspf=(fail|softfail)\b/i.test(auth) ? "SPF" : "",
638
683
  /\bdkim=(fail|permerror)\b/i.test(auth) ? "DKIM" : "",