@bobfrankston/mailx-types 0.1.84 → 0.1.88
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/package.json +1 -1
- package/trust.js +27 -2
package/package.json
CHANGED
package/trust.js
CHANGED
|
@@ -432,6 +432,13 @@ function serverSpamVerdict(input) {
|
|
|
432
432
|
const senderDomain = (bare(header(input.headerLines, "sender")).split("@")[1] || "").toLowerCase();
|
|
433
433
|
const relay = senderDomain ? a.signers.find(s => sameOrg(s, senderDomain)) : "";
|
|
434
434
|
const via = relay && !a.proved ? { via: relay } : {};
|
|
435
|
+
// Say WHICH party and HOW, in the finding itself (Bob 2026-09-08: "the
|
|
436
|
+
// banner should tell which and how"). The action's label is quoted so
|
|
437
|
+
// the reader can match it to the button — and to the allowlist.jsonc
|
|
438
|
+
// entry it writes, `trustedIntermediaries`.
|
|
439
|
+
const relayNote = relay && !a.proved
|
|
440
|
+
? `. Sent on the author's behalf by ${relay}, which signed it; "Trust ${relay} as an intermediary" stops this note for mail ${relay} signs.`
|
|
441
|
+
: "";
|
|
435
442
|
const numbers = Number.isFinite(a.score) && Number.isFinite(a.threshold)
|
|
436
443
|
? `SpamAssassin score ${a.score} of ${a.threshold}`
|
|
437
444
|
: "flagged by SpamAssassin";
|
|
@@ -482,7 +489,7 @@ function serverSpamVerdict(input) {
|
|
|
482
489
|
id: "server-spam-verdict",
|
|
483
490
|
severity: "caution",
|
|
484
491
|
text: "Your mail server classified this as spam before delivering it.",
|
|
485
|
-
detail: `${proof}${numbers}${why}${bayes}`,
|
|
492
|
+
detail: `${proof}${numbers}${why}${bayes}${relayNote}`,
|
|
486
493
|
...via,
|
|
487
494
|
};
|
|
488
495
|
}
|
|
@@ -624,6 +631,18 @@ function provedSenderDomain(input) {
|
|
|
624
631
|
*
|
|
625
632
|
* 1. The redirector and the destination are the same organisation. A site
|
|
626
633
|
* bouncing through its own hostnames is routing, not hiding.
|
|
634
|
+
* 4. The link ENDS at the proved sender (2026-09-08). Microsoft 365's
|
|
635
|
+
* Message center mail, dmarc=pass header.from=microsoft.com with
|
|
636
|
+
* policy reject, links through its click-tracker
|
|
637
|
+
* `nam.safelink.emails.azure.net` to `admin.microsoft.com`: two
|
|
638
|
+
* organisations by hostname, nobody signed for azure.net, and the
|
|
639
|
+
* sender is not the redirector — rules 1 to 3 all miss (Bob: "another
|
|
640
|
+
* safe message flagged"). But the reader lands on the site of the party
|
|
641
|
+
* that provably sent the mail, which is exactly where a plain link
|
|
642
|
+
* would have taken them; the hop hides nothing from the reader. The
|
|
643
|
+
* redirector's reputation may be borrowed, but that is the
|
|
644
|
+
* redirector's problem, not this reader's — and the sender who chose
|
|
645
|
+
* the route is the proved sender, who could have linked openly.
|
|
627
646
|
* 2. The redirector IS the proved sender. Google's account-security notice
|
|
628
647
|
* (2026-09-02, Bob: "this is valid") links through
|
|
629
648
|
* `accounts.google.com/AccountChooser?continue=https://myaccount.google.com/…`
|
|
@@ -675,16 +694,22 @@ function redirectorLink(input) {
|
|
|
675
694
|
continue;
|
|
676
695
|
if (sameOrg(target.hostname, url.hostname))
|
|
677
696
|
continue; // same site, not laundering
|
|
697
|
+
if (senderDomain && sameOrg(target.hostname, senderDomain))
|
|
698
|
+
continue; // ends at the proved sender (rule 4)
|
|
678
699
|
// Name the signer behind this redirector, if there is one, so the
|
|
679
700
|
// viewer can offer "trust google.com as an intermediary" — and
|
|
680
701
|
// only then: a redirector nobody signed for has no party to vouch
|
|
681
702
|
// for, and a list entry could not clear it anyway.
|
|
682
703
|
const signer = signers.find(s => sameOrg(s, url.hostname));
|
|
704
|
+
// Which party, and how — or why there is no party (Bob 2026-09-08).
|
|
705
|
+
const how = signer
|
|
706
|
+
? ` ${signer} signed this message; "Trust ${signer} as an intermediary" stops this warning for links through ${signer} in mail it signs.`
|
|
707
|
+
: ` Nobody signed this message for ${url.hostname}, so there is no intermediary to trust; only the sender could vouch for the link.`;
|
|
683
708
|
return {
|
|
684
709
|
id: "redirector-link",
|
|
685
710
|
severity: "caution",
|
|
686
711
|
text: `A link hides where it goes: it passes through ${url.hostname} and ends at ${target.hostname}.`,
|
|
687
|
-
detail: `${url.hostname} -> ${target.hostname}`,
|
|
712
|
+
detail: `${url.hostname} -> ${target.hostname}.${how}`,
|
|
688
713
|
...(signer ? { via: signer } : {}),
|
|
689
714
|
};
|
|
690
715
|
}
|