@bobfrankston/rmfmail 1.2.299 → 1.2.301
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 +29 -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/client/compose/compose.bundle.js +3 -3
- package/client/compose/compose.bundle.js.map +2 -2
- package/client/compose/compose.js +24 -6
- package/client/compose/compose.js.map +1 -1
- package/client/compose/compose.ts +22 -4
- package/npmchanges.md +100 -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-69280}/.package-lock.json +0 -0
package/.commitmsg
CHANGED
|
@@ -1,53 +1,29 @@
|
|
|
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
|
-
Authentication-Results header alone is enough, so this works on Gmail-API mail
|
|
31
|
-
with no SpamAssassin headers — and falls back to the DKIM_VALID_AU /
|
|
32
|
-
ALL_TRUSTED proofs SpamAssassin states in its own rule list. It reads the
|
|
33
|
-
topmost Authentication-Results only, which the sender cannot write. No proof
|
|
34
|
-
means the check stays on: an escape a forger could open by typing a domain
|
|
35
|
-
into From would be worse than no check.
|
|
36
|
-
|
|
37
|
-
The mirror rule is NOT safe and is deliberately absent. "The link ENDS at the
|
|
38
|
-
proved sender" would clear `legit-bank.com/r?u=https://evil.com` sent from a
|
|
39
|
-
DMARC-proved evil.com, which is the laundering case in its purest form — the
|
|
40
|
-
reader sees the bank's hostname. Only the visible host may be the sender's.
|
|
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
|
+
Placing the caret in the body is the same act as taking focus
|
|
2
|
+
|
|
3
|
+
Ctrl+N opens compose with the cursor in the message body instead of the To
|
|
4
|
+
field (Bob 2026-09-03: "^n (and forward?) still start me in the body rather
|
|
5
|
+
than the to field" — and yes, forward too).
|
|
6
|
+
|
|
7
|
+
applyInit made the decision twice. First it seeded the body and called
|
|
8
|
+
`editor.setCursor(0)`; twenty lines later it picked the first empty field and
|
|
9
|
+
focused it. Reading top to bottom the second one wins, and it does not:
|
|
10
|
+
`setCursor` is not a caret-placement call, it is a focus call. rmf-tiny's
|
|
11
|
+
implementation ends with `editor.focus()` and then re-runs the whole placement
|
|
12
|
+
inside `requestAnimationFrame` — deliberately, to survive the nested-iframe
|
|
13
|
+
focus race that produced the old "have to click in and try again" symptom — so
|
|
14
|
+
it lands after anything applyInit does synchronously afterwards. Quill's
|
|
15
|
+
`setSelection` focuses as well. Whatever order the two lines were written in,
|
|
16
|
+
the editor was always going to win.
|
|
17
|
+
|
|
18
|
+
So the two are now one decision, made once and up front: `focusTarget` is the
|
|
19
|
+
first field the user still has to fill, To → Subject → body, and `setCursor` is
|
|
20
|
+
asked for only when the answer is the body. On a reply that is still the body —
|
|
21
|
+
To and Subject are filled, and the call also scrolls the quote out of view so
|
|
22
|
+
the empty line is what's on screen, which is the behaviour it exists for. On a
|
|
23
|
+
forward and on new mail it is the To field, untouched.
|
|
24
|
+
|
|
25
|
+
Forward has been doing this since it grew a quoted body. Ctrl+N joined it in
|
|
26
|
+
v1.2.298, three hours ago: before the account signature reached compose,
|
|
27
|
+
`bodyToRender` was empty for new mail and the branch holding `setCursor` never
|
|
28
|
+
ran at all. The first message anyone composed with a signature was also the
|
|
29
|
+
first one that opened with the cursor in the wrong place.
|
|
@@ -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
|
};
|