@bobfrankston/rmfmail 1.2.282 → 1.2.283

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,62 +1,17 @@
1
- Catch the spam that scores under the threshold
2
-
3
- A sextortion mail arrived that none of yesterday's checks caught ("yet this
4
- spam got through"). SpamAssassin scored it 2.7 against a 4.5 threshold and
5
- delivered it, so server-spam-verdict correctly stayed silent the server said
6
- no. Three independent proofs of forgery were sitting in the message anyway.
7
-
8
- spf=none now counts as "not authenticated" for self-claimed mail, not just
9
- fail. bobf.frankston.com publishes no SPF record, so nothing sent as that
10
- domain can ever FAIL only come back none. Treating none as neutral left the
11
- least-protected domain the least defended, which is backwards. Checked against
12
- the real store before changing it, 50,000 messages scanned:
13
-
14
- From at one of Bob's domains 10,338
15
- no Authentication-Results 10,034 <- his own mail, still ignored
16
- spf=pass 243 <- still ignored
17
- spf=fail / softfail 33
18
- spf=none 18 <- nearly all spam
19
-
20
- The 18 were "Settle your debt", "AAA Final notice", "McAfee Protection Plan
21
- Ended" and similar. Legitimate self-mail sits in the no-header group: it never
22
- crossed a trust boundary, so there is no Authentication-Results to read, and
23
- that case is untouched. An explicit spf/dkim/dmarc=pass still silences the
24
- check.
25
-
26
- relay-auth-mismatch — Bob's own catch: "note that the origin is different than
27
- the from domain in antiabuse and in source-auth".
28
-
29
- From: universe@bobf.frankston.com
30
- X-Source-Auth: admin@calebjross.com
31
- X-Source-Cap: (base64) calebjro;calebjro;box2202.bluehost.com
32
- Message-ID: <...@calebjross.com>
33
-
34
- A Bluehost cPanel account belonging to an unrelated domain authenticated and
35
- sent mail wearing his address. That stamp is written by the RELAY, downstream
36
- of whoever submitted the message, so a forger cannot remove or edit it — which
37
- makes the disagreement about as close to proof as mail headers get. Compared at
38
- the registrable-domain level, since a host legitimately sending for a domain
39
- authenticates as some account AT that domain and the local part varies for
40
- ordinary reasons. Covers the cPanel/Exim, Postfix and Communigate spellings.
41
-
42
- zero-width-obfuscation — the body had ~1380 zero-width characters stuffed
43
- between letters, so "i regret to inform you" reached every word-matching filter
44
- as gibberish while rendering as clean prose. SpamAssassin saw it
45
- (UNICODE_OBFU_ZW_MANY) and still totalled only 2.7. Counted only BETWEEN TWO
46
- LATIN LETTERS, which is what obfuscation looks like and what the legitimate
47
- uses are not: an emoji ZWJ joins pictographs, Arabic and Indic ZWNJ sit between
48
- their own scripts' letters. The occurrence count guards against a stray
49
- character surviving a copy-paste; it is a sanity bound, not a sensitivity dial.
50
-
51
- The score itself is now always visible — a chip above the body reading "spam
52
- score 2.7 of 4.5" ("should we have a flag ... with the spam assassin number and
53
- a color code?"). Separate from the findings on purpose: a finding is an
54
- accusation and fires only on evidence, this is a measurement. Colour is a
55
- PROPORTION of the server's own threshold — red once flagged, amber past halfway
56
- to its line, quiet below — so it follows if the server's threshold changes
57
- rather than hardcoding a number. Viewer only for now; the message-list row
58
- would need the score stored at sync time.
59
-
60
- tests/trust.test.ts covers all three, and the negative cases with them: spf=pass
61
- and no-header both silent, a relay identity at the same organisation, an emoji
62
- ZWJ family sequence, and a stray zero-width character from a paste.
1
+ Show the spam score only when it means something
2
+
3
+ "Only show the spam score if it is high and likely." The first cut put a chip on
4
+ every message that carried a score, which is nearly all of them — a badge that
5
+ is always there carries no information and turns into furniture the eye stops
6
+ reading, which is the same failure mode the findings themselves are built to
7
+ avoid.
8
+
9
+ The chip now renders only at or above halfway to the server's own threshold.
10
+ That floor is a proportion, not a constant, so it follows if the threshold
11
+ changes. Halfway is where "did not quite trip the wire" stops meaning the same
12
+ thing as "clean": the sextortion mail scored 2.7 against 4.5 and was delivered
13
+ unflagged, so showing only what the server flagged would miss precisely the
14
+ case worth showing. Two levels remain — flagged, and past halfway — because
15
+ anything quieter no longer renders.
16
+
17
+ Findings are unaffected: they never depended on the score.
@@ -3108,11 +3108,11 @@ async function showMessage(accountId, uid, folderId, specialUse, isRetry = false
3108
3108
  }
3109
3109
  bodyEl.innerHTML = "";
3110
3110
  const spam = msg.spamScore;
3111
- if (spam && Number.isFinite(spam.score)) {
3112
- const level = spam.flagged ? "high" : spam.score >= spam.threshold / 2 ? "mid" : "low";
3111
+ if (spam && Number.isFinite(spam.score) && (spam.flagged || spam.score >= spam.threshold / 2)) {
3112
+ const level = spam.flagged ? "high" : "mid";
3113
3113
  const chip = document.createElement("div");
3114
3114
  chip.className = `mv-spamscore mv-spamscore-${level}`;
3115
- chip.title = level === "high" ? "Your mail server scored this at or above its spam threshold and flagged it." : level === "mid" ? "Below your server's spam threshold, but more than halfway to it." : "Well below your mail server's spam threshold.";
3115
+ chip.title = level === "high" ? "Your mail server scored this at or above its spam threshold and flagged it." : "Below your server's spam threshold, but more than halfway to it.";
3116
3116
  chip.textContent = `spam score ${spam.score} of ${spam.threshold}`;
3117
3117
  bodyEl.appendChild(chip);
3118
3118
  }