@bobfrankston/rmfmail 1.2.308 → 1.2.310

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/.commitmsg CHANGED
@@ -1,25 +1,13 @@
1
- Trusted intermediaries: services that relay mail on other people's behalf
1
+ Redirector warning: a link that ends at the proved sender hides nothing
2
2
 
3
- "How do I mark zoom and sites like that as trusted intermediaries?" (Bob
4
- 2026-09-08, on a Google Calendar invitation From the organizer, signed
5
- d=google.com, every link wrapped as google.com/url?q=us02web.zoom.us). Two
6
- cautions fired the server's spam verdict (GOOG_REDIR/KAM_GOOGLE_REDIR) and
7
- "a link hides where it goes" and nothing in the app could answer either:
8
- the sender is not DMARC-proved, so "stop warning about this sender" was not
9
- offered, and the redirector rule's escape covers only the proved From.
10
-
11
- New allowlist.jsonc field `trustedIntermediaries` (e.g. google.com, zoom.us).
12
- An entry counts only on a message the service PROVABLY handled a verified
13
- DKIM signature for its domain in the topmost Authentication-Results, or a
14
- DMARC pass when it is the From. Then its own redirector is routing, not
15
- laundering, and the bulk/association spam note is quieted exactly as a
16
- proved trusted sender quiets it. A message that merely links through
17
- google.com/url proves nothing and stays flagged; forgery evidence is never
18
- silenced. Findings now carry `via` (the signer behind the redirector, or the
19
- signed Sender: domain) and the viewer offers "Trust ‹domain› as an
20
- intermediary" under the banner; trustSenderOrDomain takes type
21
- "intermediary" (desktop + Android mirror), getAllowlist returns the list.
22
- docs/allowlist.md documents trustedSenders/trustedDomains (were missing) and
23
- the new list. Packages: mailx-types 0.1.83, mailx-store 0.1.115,
24
- mailx-settings 0.1.77, mailx-service 0.1.34, mailx-store-web 0.1.107,
25
- client 1.0.46.
3
+ "Another safe message flagged" (Bob 2026-09-08): Microsoft 365 Message
4
+ center, dmarc=pass header.from=microsoft.com policy reject, every link
5
+ through Microsoft's click-tracker nam.safelink.emails.azure.net ending at
6
+ admin.microsoft.com. The three existing escapes all miss azure.net and
7
+ microsoft.com are different organisations by hostname, nobody signed for
8
+ azure.net, and the redirector is not the sender. Rule 4: when the link ENDS
9
+ at the party that provably sent the mail, the reader lands exactly where a
10
+ plain link would have taken them; the hop hides nothing from them. Requires
11
+ proof (DMARC pass, or DKIM_VALID_AU / ALL_TRUSTED per the existing proof
12
+ logic); an unproved message with the same links stays flagged. mailx-types
13
+ 0.1.87.
@@ -2392,6 +2392,7 @@ function serverSpamVerdict(input) {
2392
2392
  const senderDomain = (bare(header(input.headerLines, "sender")).split("@")[1] || "").toLowerCase();
2393
2393
  const relay = senderDomain ? a.signers.find((s) => sameOrg(s, senderDomain)) : "";
2394
2394
  const via = relay && !a.proved ? { via: relay } : {};
2395
+ const relayNote = relay && !a.proved ? `. Sent on the author's behalf by ${relay}, which signed it; "Trust ${relay} as an intermediary" stops this note for mail ${relay} signs.` : "";
2395
2396
  const numbers = Number.isFinite(a.score) && Number.isFinite(a.threshold) ? `SpamAssassin score ${a.score} of ${a.threshold}` : "flagged by SpamAssassin";
2396
2397
  const why = a.reasons.length ? ` \u2014 ${a.reasons.join("; ")}` : "";
2397
2398
  const bayes = a.bayesHam ? "; your own trained filter puts it at 0-1% spam (BAYES_00)" : "";
@@ -2428,7 +2429,7 @@ function serverSpamVerdict(input) {
2428
2429
  id: "server-spam-verdict",
2429
2430
  severity: "caution",
2430
2431
  text: "Your mail server classified this as spam before delivering it.",
2431
- detail: `${proof}${numbers}${why}${bayes}`,
2432
+ detail: `${proof}${numbers}${why}${bayes}${relayNote}`,
2432
2433
  ...via
2433
2434
  };
2434
2435
  }
@@ -2532,12 +2533,15 @@ function redirectorLink(input) {
2532
2533
  continue;
2533
2534
  if (sameOrg(target.hostname, url.hostname))
2534
2535
  continue;
2536
+ if (senderDomain && sameOrg(target.hostname, senderDomain))
2537
+ continue;
2535
2538
  const signer = signers.find((s) => sameOrg(s, url.hostname));
2539
+ const how = signer ? ` ${signer} signed this message; "Trust ${signer} as an intermediary" stops this warning for links through ${signer} in mail it signs.` : ` Nobody signed this message for ${url.hostname}, so there is no intermediary to trust; only the sender could vouch for the link.`;
2536
2540
  return {
2537
2541
  id: "redirector-link",
2538
2542
  severity: "caution",
2539
2543
  text: `A link hides where it goes: it passes through ${url.hostname} and ends at ${target.hostname}.`,
2540
- detail: `${url.hostname} -> ${target.hostname}`,
2544
+ detail: `${url.hostname} -> ${target.hostname}.${how}`,
2541
2545
  ...signer ? { via: signer } : {}
2542
2546
  };
2543
2547
  }