@bobfrankston/rmfmail 1.2.314 → 1.2.316

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.
Files changed (47) hide show
  1. package/.commitmsg +29 -24
  2. package/.llm/trusted-lists.md +10 -0
  3. package/client/android-bootstrap.bundle.js +21 -1
  4. package/client/android-bootstrap.bundle.js.map +2 -2
  5. package/client/app.bundle.js +51 -3
  6. package/client/app.bundle.js.map +2 -2
  7. package/client/app.js +12 -0
  8. package/client/app.js.map +1 -1
  9. package/client/app.ts +11 -0
  10. package/client/components/calendar-sidebar.js +59 -3
  11. package/client/components/calendar-sidebar.js.map +1 -1
  12. package/client/components/calendar-sidebar.ts +50 -3
  13. package/client/compose/compose.bundle.js +4 -0
  14. package/client/compose/compose.bundle.js.map +2 -2
  15. package/client/lib/api-client.js +6 -0
  16. package/client/lib/api-client.js.map +1 -1
  17. package/client/lib/api-client.ts +6 -0
  18. package/client/lib/mailxapi.js +4 -1
  19. package/npmchanges.md +50 -0
  20. package/package.json +5 -5
  21. package/packages/mailx-imap/package-lock.json +2 -2
  22. package/packages/mailx-imap/package.json +1 -1
  23. package/packages/mailx-service/index.d.ts +14 -0
  24. package/packages/mailx-service/index.d.ts.map +1 -1
  25. package/packages/mailx-service/index.js +31 -0
  26. package/packages/mailx-service/index.js.map +1 -1
  27. package/packages/mailx-service/index.ts +29 -0
  28. package/packages/mailx-service/jsonrpc.js +2 -0
  29. package/packages/mailx-service/jsonrpc.js.map +1 -1
  30. package/packages/mailx-service/jsonrpc.ts +2 -0
  31. package/packages/mailx-service/package.json +1 -1
  32. package/packages/mailx-settings/docs/spam-false-positives.md +1 -1
  33. package/packages/mailx-settings/package.json +1 -1
  34. package/packages/mailx-store/package.json +1 -1
  35. package/packages/mailx-store-web/package.json +1 -1
  36. package/packages/mailx-store-web/web-service.d.ts +4 -0
  37. package/packages/mailx-store-web/web-service.d.ts.map +1 -1
  38. package/packages/mailx-store-web/web-service.js +1 -0
  39. package/packages/mailx-store-web/web-service.js.map +1 -1
  40. package/packages/mailx-store-web/web-service.ts +1 -0
  41. package/packages/mailx-types/mailx-api.d.ts +5 -0
  42. package/packages/mailx-types/mailx-api.d.ts.map +1 -1
  43. package/packages/mailx-types/mailx-api.ts +2 -0
  44. package/packages/mailx-types/package.json +1 -1
  45. package/packages/mailx-types/trust.d.ts.map +1 -1
  46. package/packages/mailx-types/trust.js +33 -1
  47. package/packages/mailx-types/trust.js.map +1 -1
package/.commitmsg CHANGED
@@ -1,27 +1,32 @@
1
- Self-spoof: a DMARC-proved From is not a spoof, whatever else failed
1
+ New event: spelling suggestions, the right Google account, and a prompt refresh
2
2
 
3
- Bob 2026-09-09, the ISOC Internet Policy list post, red banner "This
4
- message is not what it says it is — claims to be from your own address,
5
- internetpolicy@elists.isoc.org, but it did not come from your account.
6
- DKIM authentication failed". The list rewrote From to itself and signed
7
- it; iecc.com recorded dkim=pass d=elists.isoc.org and dmarc=pass
8
- header.from=elists.isoc.org — and dkim=fail for the original author's
9
- standardstrack.com signature the list had broken. Delivered-To was the
10
- list address, so it counted as one of Bob's own, and selfSpoof read every
11
- Authentication-Results and every signature and took the one failure as
12
- "did not come from your account". One broken signature on a message whose
13
- From domain passed DMARC aligned is not evidence about the From line; the
14
- pass is. selfSpoof now returns before the failure scan when dmarcProof
15
- passes for the actual From domain (a pass for some other domain still
16
- proves nothing — tested).
3
+ Three from Bob 2026-09-10 on the calendar sidebar's New event dialog.
17
4
 
18
- Measured over the last 120 days: 977 messages whose From is their own
19
- Delivered-To, 35 self-spoof findings before, 20 after; the 15 cleared are
20
- all ISOC list posts, the 20 that remain are the sextortion/phish/NDA-scam
21
- mail the check exists for.
5
+ "Spelling correct didn't work." The main window's right-click handler
6
+ replaced the native WebView2 menu with mailx's Cut/Copy/Paste block on
7
+ every surface and Chromium's spelling suggestions and "Add to
8
+ dictionary" exist only in the native menu, unreachable from JS. A word in
9
+ the New event box was underlined with no menu that could fix it. Plain
10
+ text controls (TEXTAREA, text-like INPUT) now keep the native menu, which
11
+ already carries Cut/Copy/Paste/Select all for a text field; everything
12
+ else is unchanged. (msger's compose items — Bold, Italic, View source —
13
+ also appear on those fields via its IsEditable gate and forward to the
14
+ compose frame, which is a no-op outside compose; cosmetic, noted.)
22
15
 
23
- Also: a danger banner on a proved-list post now says which list delivered
24
- it and that trusting the list (right-click the From address) would not
25
- clear the finding a red banner with no way forward sends the reader
26
- hunting (Bob: "right mouse on the From that's not obvious to the normal
27
- user"). mailx-types 0.1.90.
16
+ "I just used the add event but don't see them on Google calendar." The
17
+ dialog opens Google Calendar's create page in the browser, which signs in
18
+ as the browser's DEFAULT Google account, not necessarily the one mailx's
19
+ calendar reads. The URL now carries authuser=<primary calendar account
20
+ email> so the event lands where the sidebar looks.
21
+
22
+ "Creating an event should trigger an immediate update for the calendar
23
+ view." The reader saves the event in the browser; mailx only learned of
24
+ it at the next 5-minute throttled refresh. New refreshCalendarNow IPC
25
+ (service, jsonrpc, mailxapi.js, api-client, MailxApi, Android stub that
26
+ says ok:false) rewinds the throttle once and goes through
27
+ getCalendarEvents, so the in-flight dedup and the calendarUpdated emit
28
+ stay in one place; a 20 s floor of its own keeps it from reopening the
29
+ quota hole the throttle closed. The sidebar arms it after a create: on
30
+ the next window focus, and at 45 s / 2 min / 5 min in case the browser
31
+ sits on another monitor. mailx-types 0.1.93, mailx-service 0.1.36,
32
+ mailx-store-web 0.1.114.
@@ -40,6 +40,10 @@ tests/trust.test.ts, .commitmsg, TODO.md C165, root version 1.2.311. Then rebuil
40
40
  ## Follow-up 2026-09-09 evening
41
41
  - Button beside the chip ("Trust the ‹List-Id› list"), From-menu item now toggles (Stop trusting…), docs reworded re editing allowlist.jsonc. Danger banners keep no list button: 123/123 proved-list danger cases in 120 days were URL phish/malware listings.
42
42
 
43
+ ## Self-spoof false positive (found from Bob's screenshot, 2026-09-09 late)
44
+ - ISOC + berglist posts red as "claims to be from your own address": Delivered-To = list address = From, and selfSpoof took ANY dkim=fail in ANY Authentication-Results as proof of forgery. v1.2.314: DMARC-aligned pass vetoes. Next (v1.2.315): alignedPass() — From domain's own SPF pass or DKIM pass vetoes (relaxed alignment for domains with no DMARC policy). Store: 35 → 20 → 15 findings; the 15 are real phish.
45
+ - Danger banner on a proved-list post now names the list and says right-click From / that trust would not clear it.
46
+
43
47
  ## Status
44
48
  - [x] trust.ts
45
49
  - [x] settings/store/service/web
@@ -47,3 +51,9 @@ tests/trust.test.ts, .commitmsg, TODO.md C165, root version 1.2.311. Then rebuil
47
51
  - [x] tests pass (tests/trust.test.ts 40/40)
48
52
  - [x] docs/TODO/.commitmsg/versions (v1.2.312)
49
53
  - [x] rebuild.cmd — v1.2.312 (feature) + v1.2.313 (chip button + undo toggle) published, APKs built. Restart the app to pick up.
54
+
55
+ ## 2026-09-10 — New event dialog (three items, publishing as one version)
56
+ - Spelling: main-window contextmenu handler (client/app.ts) now leaves the native menu on TEXTAREA / text INPUT — Chromium spelling suggestions live only there.
57
+ - Google account: buildGoogleEventUrl adds authuser=<primary calendar email> (getPrimaryAccount("calendar")).
58
+ - Immediate update: refreshCalendarNow IPC (6 edits) + armPostCreateRefresh() in calendar-sidebar.ts (focus + 45s/2m/5m). Service floor 20s.
59
+ - Status: compiled, bundles built, rebuild.cmd next, then restart.
@@ -2267,6 +2267,23 @@ function dkimSigners(input) {
2267
2267
  }
2268
2268
  return out;
2269
2269
  }
2270
+ function alignedPass(input) {
2271
+ const fromDomain = (bare(input.fromAddress).split("@")[1] || "").toLowerCase();
2272
+ if (!fromDomain)
2273
+ return "";
2274
+ if (dkimSigners(input).some((d) => sameOrg(d, fromDomain)))
2275
+ return "dkim";
2276
+ const auth = headerAll(input.headerLines, "authentication-results")[0] || "";
2277
+ for (const part of auth.split(";")) {
2278
+ if (!/\bspf=pass\b/i.test(part))
2279
+ continue;
2280
+ const mailfrom = (part.match(/(?:spf|smtp)\.mailfrom=([^\s;,]+)/i)?.[1] || "").toLowerCase();
2281
+ const domain = mailfrom.includes("@") ? mailfrom.split("@")[1] : mailfrom;
2282
+ if (domain && sameOrg(domain, fromDomain))
2283
+ return "spf";
2284
+ }
2285
+ return "";
2286
+ }
2270
2287
  function provedIntermediary(input) {
2271
2288
  const list = (input.trustedIntermediaries || []).map((d) => (d || "").trim().toLowerCase()).filter(Boolean);
2272
2289
  if (!list.length)
@@ -2483,7 +2500,7 @@ function selfSpoof(input) {
2483
2500
  const auth = headerAll(input.headerLines, "authentication-results").join(" ; ");
2484
2501
  if (!auth)
2485
2502
  return null;
2486
- if (dmarcProof(input).pass)
2503
+ if (dmarcProof(input).pass || alignedPass(input))
2487
2504
  return null;
2488
2505
  const failed = [
2489
2506
  /\bspf=(fail|softfail)\b/i.test(auth) ? "SPF" : "",
@@ -7802,6 +7819,9 @@ var WebMailxService = class _WebMailxService {
7802
7819
  async getCalendarEvents(_fromMs, _toMs) {
7803
7820
  return [];
7804
7821
  }
7822
+ async refreshCalendarNow() {
7823
+ return { ok: false, reason: "no calendar on Android" };
7824
+ }
7805
7825
  async getCalendars() {
7806
7826
  return [];
7807
7827
  }