@bobfrankston/rmfmail 1.2.299 → 1.2.300
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 +41 -53
- package/client/android-bootstrap.bundle.js +4 -1
- package/client/android-bootstrap.bundle.js.map +2 -2
- package/client/app.bundle.js +1 -1
- package/client/app.bundle.js.map +2 -2
- package/client/components/message-viewer.js +14 -2
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +16 -3
- package/npmchanges.md +56 -0
- package/package.json +5 -5
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-settings/package.json +1 -1
- package/packages/mailx-store/package.json +1 -1
- package/packages/mailx-store-web/package.json +1 -1
- package/packages/mailx-types/package.json +1 -1
- package/packages/mailx-types/trust.d.ts +4 -0
- package/packages/mailx-types/trust.d.ts.map +1 -1
- package/packages/mailx-types/trust.js +21 -2
- package/packages/mailx-types/trust.js.map +1 -1
- package/packages/mailx-types/trust.ts +31 -2
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-67432 → node_modules.npmglobalize-stash-63828}/.package-lock.json +0 -0
package/.commitmsg
CHANGED
|
@@ -1,53 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
Measured over the 800 most recent messages in the store: redirector-link fires
|
|
43
|
-
15 times before, 4 after. Cleared: Substack's own link wrapper on Substack
|
|
44
|
-
mail (6), Google's alert, Microsoft Teams, dev.to. Still flagged, correctly by
|
|
45
|
-
this rule's terms: Microsoft's Safe Links wrapper (nam.safelink.emails.azure.net
|
|
46
|
-
-> admin.microsoft.com, 3) and a donation platform bouncing back to the charity
|
|
47
|
-
that mailed. Those are third-party hostnames in front of the reader, and no
|
|
48
|
-
hostname allowlist is going in to quiet them.
|
|
49
|
-
|
|
50
|
-
Four tests: the sibling-subdomain case, the Google alert with its proof and
|
|
51
|
-
again with the proof removed, and a forged accounts.google.com whose server
|
|
52
|
-
recorded the DMARC failure — still flagged, as the escape is the server's
|
|
53
|
-
verdict and never the From line's say-so.
|
|
1
|
+
The chip claimed every rule was a bulk-mail test without looking at them
|
|
2
|
+
|
|
3
|
+
Altis Hotels' welcome mail (Bob 2026-09-03: "marked as spam but is valid",
|
|
4
|
+
`mailxstore/bobma/90/90fd2404….eml`). The banner on it is already right —
|
|
5
|
+
`info`, no headline, "Your mail server scored this as spam, but altishotels.com
|
|
6
|
+
proved it sent this", and the "Stop warning about marketing@altishotels.com"
|
|
7
|
+
button underneath. What was wrong sat one element above: the score chip's
|
|
8
|
+
tooltip read "Scored by bulk-mail or blocklist rules; the sending domain passed
|
|
9
|
+
DMARC, so the sender is proved" — and then listed, on the next line of the same
|
|
10
|
+
tooltip, `3.2 KAM_ACCOUNTPHISH (Spam that tries to get account information)`,
|
|
11
|
+
which is 3.2 of the message's 8.3 and is neither a bulk-mail nor a blocklist
|
|
12
|
+
rule. A reader who reads both lines has been told two different things about
|
|
13
|
+
the same message by the same tooltip, and the app is the one that is wrong.
|
|
14
|
+
|
|
15
|
+
The claim was never checked. `benign = proved || kind === "bulk"` picked the
|
|
16
|
+
neutral chip — correctly, that part is about the sender — and the tooltip then
|
|
17
|
+
described the RULES from that same flag. `proved` is a fact about the headers
|
|
18
|
+
and says nothing about any rule; `kind` is the WORST class present and says
|
|
19
|
+
nothing about the rest. Neither one can support a sentence beginning "every
|
|
20
|
+
rule that scored".
|
|
21
|
+
|
|
22
|
+
`analyzeServerSpam` now computes `bulkOnly` — every rule that scored is `bulk`
|
|
23
|
+
or `neutral` — and `spamScoreOf` carries it to the chip. The bulk-only sentence
|
|
24
|
+
is said only when it is true. Otherwise the tooltip says what IS established
|
|
25
|
+
and nothing more: the proof, by name, plus "not every rule that scored is a
|
|
26
|
+
bulk-mail test — they are listed below", or for an unproved sender "no forgery
|
|
27
|
+
rule scored", which `kind === "bulk"` does establish. The `info` banner for a
|
|
28
|
+
bulk verdict loses its "— nothing that scored tests who sent it" clause on the
|
|
29
|
+
same condition, since it was making the same unchecked claim.
|
|
30
|
+
|
|
31
|
+
Measured over the 800 newest messages in the store: 138 raise the neutral chip,
|
|
32
|
+
and 132 of those were being told the score was bulk-mail rules only. Most are
|
|
33
|
+
unflagged mail scoring above half the threshold, which carries no
|
|
34
|
+
X-Spam-Report at all — there the individual scores are unknown, which is
|
|
35
|
+
precisely when a claim about all of them cannot be made.
|
|
36
|
+
|
|
37
|
+
Not changed, on purpose: KAM_ACCOUNTPHISH stays unclassified. Its description
|
|
38
|
+
says it tests what the message asks for, not who sent it, but "other" is the
|
|
39
|
+
honest answer for a rule this file has no basis to classify, and the cautious
|
|
40
|
+
default is what "other" is for. The fix is to stop asserting past it, not to
|
|
41
|
+
guess at it.
|
|
@@ -2318,6 +2318,7 @@ function analyzeServerSpam(input) {
|
|
|
2318
2318
|
const unknown = rules.filter((r) => r.cls === "other" && scored(r));
|
|
2319
2319
|
const unknownWeight = unknown.reduce((sum, r) => sum + r.score, 0);
|
|
2320
2320
|
const unknownCouldFlagAlone = !unknown.length ? false : !Number.isFinite(unknownWeight) || !Number.isFinite(threshold) ? true : unknownWeight >= threshold;
|
|
2321
|
+
const bulkOnly = rules.every((r) => !scored(r) || r.cls === "bulk" || r.cls === "neutral");
|
|
2321
2322
|
const kind = dmarc.authFailures.length || present("forgery") ? "forgery" : present("association") ? "association" : unknownCouldFlagAlone ? "unclassified" : rules.length ? "bulk" : "unclassified";
|
|
2322
2323
|
const has = (name) => rules.some((r) => r.name === name);
|
|
2323
2324
|
const provedBy = dmarc.pass ? "dmarc" : has("DKIM_VALID_AU") ? "dkim" : has("ALL_TRUSTED") ? "trusted" : "";
|
|
@@ -2334,6 +2335,7 @@ function analyzeServerSpam(input) {
|
|
|
2334
2335
|
kind,
|
|
2335
2336
|
proved: !!provedBy,
|
|
2336
2337
|
provedBy,
|
|
2338
|
+
bulkOnly,
|
|
2337
2339
|
provedDomain: dmarc.domain || fromDomain,
|
|
2338
2340
|
provedPolicy: dmarc.policy,
|
|
2339
2341
|
bayesHam: rules.some((r) => r.name === "BAYES_00" || r.name === "BAYES_01"),
|
|
@@ -2381,7 +2383,7 @@ function serverSpamVerdict(input) {
|
|
|
2381
2383
|
return {
|
|
2382
2384
|
id: "server-spam-verdict",
|
|
2383
2385
|
severity: "info",
|
|
2384
|
-
text: "Your mail server rates this bulk mail \u2014 nothing that scored tests who sent it.",
|
|
2386
|
+
text: a.bulkOnly ? "Your mail server rates this bulk mail \u2014 nothing that scored tests who sent it." : "Your mail server rates this bulk mail.",
|
|
2385
2387
|
detail: `${numbers}${why}${bayes}`
|
|
2386
2388
|
};
|
|
2387
2389
|
const proof = a.proved ? `${provedNote(a)} ` : "";
|
|
@@ -2561,6 +2563,7 @@ function spamScoreOf(input) {
|
|
|
2561
2563
|
kind: a.kind,
|
|
2562
2564
|
proved: a.proved,
|
|
2563
2565
|
provedBy: a.provedBy,
|
|
2566
|
+
bulkOnly: a.bulkOnly,
|
|
2564
2567
|
trusted: !!input.senderTrusted && a.proved && a.kind !== "forgery" && !a.authFailures.length,
|
|
2565
2568
|
reasons: a.reasons
|
|
2566
2569
|
};
|