@bobfrankston/rmfmail 1.2.321 → 1.2.322

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 (54) hide show
  1. package/.commitmsg +26 -9
  2. package/.llm/trusted-lists.md +2 -0
  3. package/client/android-bootstrap.bundle.js +35 -9
  4. package/client/android-bootstrap.bundle.js.map +2 -2
  5. package/client/app.bundle.js +27 -1
  6. package/client/app.bundle.js.map +2 -2
  7. package/client/components/message-viewer.js +33 -0
  8. package/client/components/message-viewer.js.map +1 -1
  9. package/client/components/message-viewer.ts +32 -1
  10. package/client/compose/compose.bundle.js +1 -1
  11. package/client/compose/compose.bundle.js.map +2 -2
  12. package/client/lib/api-client.js +1 -1
  13. package/client/lib/api-client.js.map +1 -1
  14. package/client/lib/api-client.ts +3 -3
  15. package/docs/allowlist.md +15 -1
  16. package/npmchanges.md +13 -0
  17. package/package.json +3 -3
  18. package/packages/mailx-imap/package-lock.json +2 -2
  19. package/packages/mailx-imap/package.json +1 -1
  20. package/packages/mailx-service/index.d.ts +1 -0
  21. package/packages/mailx-service/index.d.ts.map +1 -1
  22. package/packages/mailx-service/index.js +1 -0
  23. package/packages/mailx-service/index.js.map +1 -1
  24. package/packages/mailx-service/index.ts +2 -1
  25. package/packages/mailx-service/package.json +1 -1
  26. package/packages/mailx-settings/docs/allowlist.md +15 -1
  27. package/packages/mailx-settings/index.d.ts +1 -0
  28. package/packages/mailx-settings/index.d.ts.map +1 -1
  29. package/packages/mailx-settings/index.js +4 -0
  30. package/packages/mailx-settings/index.js.map +1 -1
  31. package/packages/mailx-settings/index.ts +4 -0
  32. package/packages/mailx-settings/package.json +1 -1
  33. package/packages/mailx-store/package.json +1 -1
  34. package/packages/mailx-store/store.d.ts.map +1 -1
  35. package/packages/mailx-store/store.js +2 -0
  36. package/packages/mailx-store/store.js.map +1 -1
  37. package/packages/mailx-store/store.ts +2 -0
  38. package/packages/mailx-store-web/package.json +1 -1
  39. package/packages/mailx-store-web/web-service.d.ts +1 -0
  40. package/packages/mailx-store-web/web-service.d.ts.map +1 -1
  41. package/packages/mailx-store-web/web-service.js +1 -0
  42. package/packages/mailx-store-web/web-service.js.map +1 -1
  43. package/packages/mailx-store-web/web-service.ts +2 -1
  44. package/packages/mailx-store-web/web-settings.d.ts +1 -0
  45. package/packages/mailx-store-web/web-settings.d.ts.map +1 -1
  46. package/packages/mailx-store-web/web-settings.js +1 -0
  47. package/packages/mailx-store-web/web-settings.js.map +1 -1
  48. package/packages/mailx-store-web/web-settings.ts +1 -0
  49. package/packages/mailx-types/package.json +1 -1
  50. package/packages/mailx-types/trust.d.ts +18 -0
  51. package/packages/mailx-types/trust.d.ts.map +1 -1
  52. package/packages/mailx-types/trust.js +42 -4
  53. package/packages/mailx-types/trust.js.map +1 -1
  54. package/packages/mailx-types/trust.ts +60 -4
@@ -1809,7 +1809,7 @@ export async function showMessage(accountId: string, uid: number, folderId?: num
1809
1809
  }
1810
1810
  }
1811
1811
 
1812
- const trust = ((msg as any).trust || []) as { id: string; severity: string; text: string; detail: string; via?: string; list?: string }[];
1812
+ const trust = ((msg as any).trust || []) as { id: string; severity: string; text: string; detail: string; via?: string; list?: string; senderVia?: string }[];
1813
1813
  if (trust.length) {
1814
1814
  // An `info` finding is not an accusation, so it gets neither the
1815
1815
  // headline nor the "do not open anything" footer — it renders as a
@@ -1933,6 +1933,37 @@ export async function showMessage(accountId: string, uid: number, folderId?: num
1933
1933
  }
1934
1934
  warn.appendChild(actions);
1935
1935
  }
1936
+ // "Trust ‹sender› via ‹relay›" (Bob 2026-09-10, Ground News: "another
1937
+ // valid site. How do I approve it?"). A finding carries senderVia
1938
+ // only when the reader already trusts the sender, nothing proves the
1939
+ // From line, and a relay DID sign the message; the entry it writes
1940
+ // counts only on mail from that sender that relay signs.
1941
+ const senderVias = worst === "danger" ? [] : Array.from(new Set(trust.map(f => f.senderVia).filter(Boolean)));
1942
+ if (senderVias.length) {
1943
+ const actions = document.createElement("div");
1944
+ actions.className = "mv-trust-actions";
1945
+ for (const pair of senderVias) {
1946
+ const b = document.createElement("button");
1947
+ b.className = "mv-trust-action";
1948
+ b.textContent = `Trust ${pair}`;
1949
+ b.title = `Adds "${pair}" to trustedSendersVia in allowlist.jsonc. Stops this note for mail from ${pair.split(" via ")[0]} that ${pair.split(" via ")[1]} signs; a message without that signature is still checked.`;
1950
+ b.addEventListener("click", async () => {
1951
+ b.disabled = true;
1952
+ try {
1953
+ const res = await trustSenderOrDomain("via", pair);
1954
+ if (!res?.trusted) throw new Error("the sender-via list did not save");
1955
+ warn.remove();
1956
+ document.querySelector(".mv-spamscore")?.remove();
1957
+ } catch (e: any) {
1958
+ // The reader pressed a button and must know whether it took.
1959
+ b.disabled = false;
1960
+ b.textContent = `Could not save: ${e?.message || e}`;
1961
+ }
1962
+ });
1963
+ actions.appendChild(b);
1964
+ }
1965
+ warn.appendChild(actions);
1966
+ }
1936
1967
  // "Trust ‹service› as an intermediary" (Bob 2026-09-08: "how do I
1937
1968
  // mark zoom and sites like that as trusted intermediaries?"). A
1938
1969
  // finding carries `via` only when a party PROVABLY handled the
@@ -1357,7 +1357,7 @@ function trustSenderOrDomain(type, value) {
1357
1357
  return ipc().trustSenderOrDomain?.(type, value) ?? Promise.resolve({ trusted: false });
1358
1358
  }
1359
1359
  function getAllowlist() {
1360
- return ipc().getAllowlist?.() ?? Promise.resolve({ senders: [], domains: [], recipients: [], flaggedSenders: [], flaggedDomains: [], trustedSenders: [], trustedDomains: [], trustedIntermediaries: [], trustedLists: [] });
1360
+ return ipc().getAllowlist?.() ?? Promise.resolve({ senders: [], domains: [], recipients: [], flaggedSenders: [], flaggedDomains: [], trustedSenders: [], trustedDomains: [], trustedIntermediaries: [], trustedLists: [], trustedSendersVia: [] });
1361
1361
  }
1362
1362
  function flagSenderOrDomain(type, value) {
1363
1363
  return ipc().flagSenderOrDomain?.(type, value) ?? Promise.resolve({ flagged: false });