@bobfrankston/rmfmail 1.2.321 → 1.2.323
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 +16 -9
- package/.llm/trusted-lists.md +3 -0
- package/client/android-bootstrap.bundle.js +35 -9
- package/client/android-bootstrap.bundle.js.map +2 -2
- package/client/app.bundle.js +33 -3
- package/client/app.bundle.js.map +2 -2
- package/client/components/calendar-sidebar.js +14 -2
- package/client/components/calendar-sidebar.js.map +1 -1
- package/client/components/calendar-sidebar.ts +17 -2
- package/client/components/message-viewer.js +33 -0
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +32 -1
- package/client/compose/compose.bundle.js +1 -1
- package/client/compose/compose.bundle.js.map +2 -2
- package/client/lib/api-client.js +1 -1
- package/client/lib/api-client.js.map +1 -1
- package/client/lib/api-client.ts +3 -3
- package/docs/allowlist.md +15 -1
- package/npmchanges.md +43 -0
- package/package.json +7 -7
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-service/index.d.ts +1 -0
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +9 -2
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +10 -3
- package/packages/mailx-service/package.json +1 -1
- package/packages/mailx-settings/docs/allowlist.md +15 -1
- package/packages/mailx-settings/index.d.ts +1 -0
- package/packages/mailx-settings/index.d.ts.map +1 -1
- package/packages/mailx-settings/index.js +4 -0
- package/packages/mailx-settings/index.js.map +1 -1
- package/packages/mailx-settings/index.ts +4 -0
- package/packages/mailx-settings/package.json +1 -1
- package/packages/mailx-store/package.json +1 -1
- package/packages/mailx-store/store.d.ts.map +1 -1
- package/packages/mailx-store/store.js +2 -0
- package/packages/mailx-store/store.js.map +1 -1
- package/packages/mailx-store/store.ts +2 -0
- package/packages/mailx-store-web/package.json +1 -1
- package/packages/mailx-store-web/web-service.d.ts +1 -0
- package/packages/mailx-store-web/web-service.d.ts.map +1 -1
- package/packages/mailx-store-web/web-service.js +1 -0
- package/packages/mailx-store-web/web-service.js.map +1 -1
- package/packages/mailx-store-web/web-service.ts +2 -1
- package/packages/mailx-store-web/web-settings.d.ts +1 -0
- package/packages/mailx-store-web/web-settings.d.ts.map +1 -1
- package/packages/mailx-store-web/web-settings.js +1 -0
- package/packages/mailx-store-web/web-settings.js.map +1 -1
- package/packages/mailx-store-web/web-settings.ts +1 -0
- package/packages/mailx-types/mailx-api.d.ts +1 -0
- package/packages/mailx-types/mailx-api.d.ts.map +1 -1
- package/packages/mailx-types/mailx-api.ts +1 -1
- package/packages/mailx-types/package.json +1 -1
- package/packages/mailx-types/trust.d.ts +18 -0
- package/packages/mailx-types/trust.d.ts.map +1 -1
- package/packages/mailx-types/trust.js +42 -4
- package/packages/mailx-types/trust.js.map +1 -1
- package/packages/mailx-types/trust.ts +60 -4
package/.commitmsg
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
New event: the calendar picker is always there, and lists every calendar you can write to
|
|
2
2
|
|
|
3
|
-
Bob 2026-09-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
Bob 2026-09-11: "the add appointment box should give me a choice of
|
|
4
|
+
calendars." v1.2.318 hid the picker whenever Google reported fewer than
|
|
5
|
+
two writable calendars — and his four are one owned calendar plus two
|
|
6
|
+
holiday feeds and a shared one, so the row never appeared and read as a
|
|
7
|
+
missing feature.
|
|
8
|
+
|
|
9
|
+
The row is now always shown. With one writable calendar the dropdown is
|
|
10
|
+
disabled and its tooltip says that this is the only calendar Google lets
|
|
11
|
+
you add events to, that the others are read-only, and where to change
|
|
12
|
+
that (Google Calendar, then Refresh). getCalendars returns EVERY
|
|
13
|
+
calendar with `selected` as a flag instead of a filter: the sidebar
|
|
14
|
+
still lists the selected ones, but a calendar the reader owns and has
|
|
15
|
+
unticked in Google is still one a new event can go to. The daemon logs
|
|
16
|
+
each calendar's role and selection at enumeration so "why only one" can
|
|
17
|
+
be answered from the log. mailx-types 0.1.98, mailx-service 0.1.39.
|
package/.llm/trusted-lists.md
CHANGED
|
@@ -66,3 +66,6 @@ tests/trust.test.ts, .commitmsg, TODO.md C165, root version 1.2.311. Then rebuil
|
|
|
66
66
|
- v1.2.319: TinyMCE smart-paste left the caret INSIDE the pasted <a>; stepCaretOutOfPastedLink in client/compose/editor.ts moves it after the anchor one tick after paste. Quill path has the same shape (insertText link + setSelection) — untouched, Bob uses TinyMCE.
|
|
67
67
|
- v1.2.320: Quill counterpart — placeCaretAfterLink(index) = setSelection + format("link", false) at 5 paste sites + 2 Edit-link dialog sites. Untested; Bob will switch editor to test.
|
|
68
68
|
- v1.2.321: signature block uses a 3cm <hr> instead of '-- ' (compose.ts sigBlock).
|
|
69
|
+
- Bob confirmed 2026-09-10: 'quill worked' (v1.2.320 placeCaretAfterLink).
|
|
70
|
+
- v1.2.322: trustedSendersVia ('sender via relay' pairs) — Ground News via amazonses.com. Banner offers 'Trust ‹sender› via ‹relay›' on the trusted-but-unproved caution; counts only when the relay DKIM-signed. 45/45 trust tests.
|
|
71
|
+
- v1.2.323: New event picker always shown (disabled + explanatory tooltip when only one writable calendar); getCalendars returns all calendars with selected flag; daemon logs roles.
|
|
@@ -2297,6 +2297,23 @@ function provedIntermediary(input) {
|
|
|
2297
2297
|
return entry;
|
|
2298
2298
|
return "";
|
|
2299
2299
|
}
|
|
2300
|
+
function parseSenderVia(entry) {
|
|
2301
|
+
const m = (entry || "").trim().toLowerCase().match(/^(\S+)\s+via\s+(\S+)$/);
|
|
2302
|
+
return m ? { domain: m[1], signer: m[2] } : null;
|
|
2303
|
+
}
|
|
2304
|
+
function provedSenderVia(input) {
|
|
2305
|
+
const entries = (input.trustedSendersVia || []).map(parseSenderVia).filter(Boolean);
|
|
2306
|
+
if (!entries.length)
|
|
2307
|
+
return "";
|
|
2308
|
+
const fromDomain = (bare(input.fromAddress).split("@")[1] || "").toLowerCase();
|
|
2309
|
+
if (!fromDomain)
|
|
2310
|
+
return "";
|
|
2311
|
+
const signers = dkimSigners(input);
|
|
2312
|
+
for (const e of entries)
|
|
2313
|
+
if (sameOrg(fromDomain, e.domain) && signers.some((s) => sameOrg(s, e.signer)))
|
|
2314
|
+
return `${e.domain} via ${e.signer}`;
|
|
2315
|
+
return "";
|
|
2316
|
+
}
|
|
2300
2317
|
function listProof(input) {
|
|
2301
2318
|
const none = { id: "", proved: false, host: "" };
|
|
2302
2319
|
const raw = header(input.headerLines, "list-id");
|
|
@@ -2420,7 +2437,8 @@ function analyzeServerSpam(input) {
|
|
|
2420
2437
|
reasons,
|
|
2421
2438
|
intermediary: provedIntermediary(input),
|
|
2422
2439
|
signers: dkimSigners(input),
|
|
2423
|
-
list
|
|
2440
|
+
list,
|
|
2441
|
+
senderVia: provedSenderVia(input)
|
|
2424
2442
|
};
|
|
2425
2443
|
}
|
|
2426
2444
|
function provedNote(a) {
|
|
@@ -2439,7 +2457,7 @@ function serverSpamVerdict(input) {
|
|
|
2439
2457
|
const a = analyzeServerSpam(input);
|
|
2440
2458
|
if (!a || !a.flagged)
|
|
2441
2459
|
return null;
|
|
2442
|
-
const trustedAndProved = input.senderTrusted && a.proved || !!a.intermediary || a.list.trusted;
|
|
2460
|
+
const trustedAndProved = input.senderTrusted && a.proved || !!a.intermediary || a.list.trusted || !!a.senderVia;
|
|
2443
2461
|
if (trustedAndProved && a.kind !== "forgery" && !a.authFailures.length)
|
|
2444
2462
|
return null;
|
|
2445
2463
|
const senderDomain = (bare(header(input.headerLines, "sender")).split("@")[1] || "").toLowerCase();
|
|
@@ -2473,14 +2491,19 @@ function serverSpamVerdict(input) {
|
|
|
2473
2491
|
detail: `${numbers}${why}${bayes}`
|
|
2474
2492
|
};
|
|
2475
2493
|
const proof = a.proved ? `${provedNote(a)} ` : "";
|
|
2476
|
-
if (input.senderTrusted && !a.proved)
|
|
2494
|
+
if (input.senderTrusted && !a.proved) {
|
|
2495
|
+
const fromDomain = (bare(input.fromAddress).split("@")[1] || "").toLowerCase();
|
|
2496
|
+
const relaySigner = a.signers.find((s) => !sameOrg(s, fromDomain)) || "";
|
|
2497
|
+
const senderViaNote = relaySigner ? `. ${relaySigner} signed this message on the sender's behalf; "Trust ${fromDomain} via ${relaySigner}" stops this note for mail from ${fromDomain} that ${relaySigner} signs.` : "";
|
|
2477
2498
|
return {
|
|
2478
2499
|
id: "server-spam-verdict",
|
|
2479
2500
|
severity: "caution",
|
|
2480
2501
|
text: "This claims to be a sender you trust, but nothing proves it is.",
|
|
2481
|
-
detail: `No DMARC pass, no valid signature from the sending domain, and it passed through hosts your server does not trust. ${numbers}${why}${listNote}`,
|
|
2482
|
-
...viaList
|
|
2502
|
+
detail: `No DMARC pass, no valid signature from the sending domain, and it passed through hosts your server does not trust. ${numbers}${why}${listNote}${senderViaNote}`,
|
|
2503
|
+
...viaList,
|
|
2504
|
+
...relaySigner ? { senderVia: `${fromDomain} via ${relaySigner}` } : {}
|
|
2483
2505
|
};
|
|
2506
|
+
}
|
|
2484
2507
|
return {
|
|
2485
2508
|
id: "server-spam-verdict",
|
|
2486
2509
|
severity: "caution",
|
|
@@ -2664,7 +2687,7 @@ function spamScoreOf(input) {
|
|
|
2664
2687
|
proved: a.proved,
|
|
2665
2688
|
provedBy: a.provedBy,
|
|
2666
2689
|
bulkOnly: a.bulkOnly,
|
|
2667
|
-
trusted: (!!input.senderTrusted && a.proved || !!a.intermediary || a.list.trusted) && a.kind !== "forgery" && !a.authFailures.length,
|
|
2690
|
+
trusted: (!!input.senderTrusted && a.proved || !!a.intermediary || a.list.trusted || !!a.senderVia) && a.kind !== "forgery" && !a.authFailures.length,
|
|
2668
2691
|
reasons: a.reasons,
|
|
2669
2692
|
listId: a.list.id,
|
|
2670
2693
|
listProved: a.list.proved,
|
|
@@ -2679,7 +2702,8 @@ var init_trust = __esm({
|
|
|
2679
2702
|
sender: "trustedSenders",
|
|
2680
2703
|
domain: "trustedDomains",
|
|
2681
2704
|
intermediary: "trustedIntermediaries",
|
|
2682
|
-
list: "trustedLists"
|
|
2705
|
+
list: "trustedLists",
|
|
2706
|
+
via: "trustedSendersVia"
|
|
2683
2707
|
};
|
|
2684
2708
|
FORGERY_RULES = [
|
|
2685
2709
|
/^SPF_(HELO_)?(FAIL|SOFTFAIL)$/,
|
|
@@ -4291,7 +4315,8 @@ var init_web_settings = __esm({
|
|
|
4291
4315
|
trustedSenders: [],
|
|
4292
4316
|
trustedDomains: [],
|
|
4293
4317
|
// Mailing lists by List-Id — mirrors mailx-settings DEFAULT_ALLOWLIST (2026-09-09).
|
|
4294
|
-
trustedLists: []
|
|
4318
|
+
trustedLists: [],
|
|
4319
|
+
trustedSendersVia: []
|
|
4295
4320
|
};
|
|
4296
4321
|
PREV_KEEP = 5;
|
|
4297
4322
|
SHARED_REFRESH_MS = 5 * 6e4;
|
|
@@ -7256,7 +7281,8 @@ var WebMailxService = class _WebMailxService {
|
|
|
7256
7281
|
trustedSenders: list.trustedSenders || [],
|
|
7257
7282
|
trustedDomains: list.trustedDomains || [],
|
|
7258
7283
|
trustedIntermediaries: list.trustedIntermediaries || [],
|
|
7259
|
-
trustedLists: list.trustedLists || []
|
|
7284
|
+
trustedLists: list.trustedLists || [],
|
|
7285
|
+
trustedSendersVia: list.trustedSendersVia || []
|
|
7260
7286
|
};
|
|
7261
7287
|
}
|
|
7262
7288
|
async allowRemoteContent(type, value) {
|