@bobfrankston/rmfmail 1.2.291 → 1.2.293

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 (57) hide show
  1. package/.commitmsg +24 -27
  2. package/client/android-bootstrap.bundle.js +34 -2
  3. package/client/android-bootstrap.bundle.js.map +2 -2
  4. package/client/app.bundle.js +37 -1
  5. package/client/app.bundle.js.map +2 -2
  6. package/client/components/message-viewer.js +56 -1
  7. package/client/components/message-viewer.js.map +1 -1
  8. package/client/components/message-viewer.ts +54 -1
  9. package/client/compose/compose.bundle.js +5 -1
  10. package/client/compose/compose.bundle.js.map +2 -2
  11. package/client/lib/api-client.js +7 -1
  12. package/client/lib/api-client.js.map +1 -1
  13. package/client/lib/api-client.ts +9 -2
  14. package/client/lib/mailxapi.js +3 -0
  15. package/client/styles/components.css +25 -0
  16. package/npmchanges.md +66 -0
  17. package/package.json +6 -6
  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 +20 -0
  21. package/packages/mailx-service/index.d.ts.map +1 -1
  22. package/packages/mailx-service/index.js +37 -0
  23. package/packages/mailx-service/index.js.map +1 -1
  24. package/packages/mailx-service/index.ts +37 -1
  25. package/packages/mailx-service/jsonrpc.js +2 -0
  26. package/packages/mailx-service/jsonrpc.js.map +1 -1
  27. package/packages/mailx-service/jsonrpc.ts +2 -0
  28. package/packages/mailx-service/package.json +1 -1
  29. package/packages/mailx-settings/index.d.ts +19 -0
  30. package/packages/mailx-settings/index.d.ts.map +1 -1
  31. package/packages/mailx-settings/index.js +33 -10
  32. package/packages/mailx-settings/index.js.map +1 -1
  33. package/packages/mailx-settings/index.ts +33 -11
  34. package/packages/mailx-settings/package.json +1 -1
  35. package/packages/mailx-store/package.json +1 -1
  36. package/packages/mailx-store/store.d.ts.map +1 -1
  37. package/packages/mailx-store/store.js +17 -2
  38. package/packages/mailx-store/store.js.map +1 -1
  39. package/packages/mailx-store/store.ts +17 -2
  40. package/packages/mailx-store-web/android-bootstrap.js +3 -0
  41. package/packages/mailx-store-web/android-bootstrap.js.map +1 -1
  42. package/packages/mailx-store-web/android-bootstrap.ts +3 -0
  43. package/packages/mailx-store-web/package.json +1 -1
  44. package/packages/mailx-store-web/web-jsonrpc.js +2 -0
  45. package/packages/mailx-store-web/web-jsonrpc.js.map +1 -1
  46. package/packages/mailx-store-web/web-jsonrpc.ts +2 -0
  47. package/packages/mailx-store-web/web-service.d.ts +9 -0
  48. package/packages/mailx-store-web/web-service.d.ts.map +1 -1
  49. package/packages/mailx-store-web/web-service.js +28 -0
  50. package/packages/mailx-store-web/web-service.js.map +1 -1
  51. package/packages/mailx-store-web/web-service.ts +23 -1
  52. package/packages/mailx-store-web/web-settings.d.ts +2 -0
  53. package/packages/mailx-store-web/web-settings.d.ts.map +1 -1
  54. package/packages/mailx-store-web/web-settings.js +2 -0
  55. package/packages/mailx-store-web/web-settings.js.map +1 -1
  56. package/packages/mailx-store-web/web-settings.ts +2 -0
  57. /package/packages/mailx-imap/{node_modules.npmglobalize-stash-27960 → node_modules.npmglobalize-stash-29688}/.package-lock.json +0 -0
package/.commitmsg CHANGED
@@ -1,31 +1,28 @@
1
- An approved sender, proved, says nothing at all
1
+ The allowlist merge silently dropped any list it had not been taught
2
2
 
3
- Bob 2026-08-28, having just clicked "Always: *@icecer.com" on a conference call
4
- for papers that still showed a bulk-mail note: "I accepted the server so
5
- shouldn't this be considered safe?" Yes — and this is the half of C165 that was
6
- still open. `allowlist.jsonc` has been the approved-sender store all along, and
7
- nothing consulted it when computing trust.
3
+ Caught by driving the button from v1.2.292: pressing "Stop warning about
4
+ *@digital.conservativeintel.com" returned `{trusted: true}`, the banner
5
+ disappeared — and nothing was written. `trustedDomains` was empty on readback
6
+ and absent from allowlist.jsonc.
8
7
 
9
- `assessMessageTrust` and `spamScoreOf` now take `senderTrusted`, and store.ts
10
- fills it from the sender and domain lists the reader maintains. When the sender
11
- is approved AND proved AND nothing accuses it of forgery, the server-spam
12
- finding is not rendered at all and the score chip goes with it: the score
13
- answers "is this bulk", the reader has already answered "is it wanted", and
14
- repeating the first after the second is how a banner becomes furniture.
8
+ Cause: `saveAllowlist` merges the local copy with the cloud one so a second
9
+ machine's entries survive, and that merge rebuilt the result from a HARDCODED
10
+ list of the five fields it knew. The two lists added earlier the same day were
11
+ dropped on the way to disk, with a success return the whole way up. A merge
12
+ that must be taught each new field will keep losing the next one.
15
13
 
16
- Three boundaries, deliberate:
14
+ - `mergeAllowlists(local, cloud)` — extracted, exported, and tested — unions
15
+ every field present in either copy, discovering names at runtime. Arrays
16
+ union; anything else prefers the local side, since the caller is the one
17
+ making a change; no key either side has is ever dropped. That last property
18
+ is what keeps a second machine's entries alive and what saved this file in
19
+ the 2026-07-23 wipe.
20
+ - `DEFAULT_ALLOWLIST` names trustedSenders/trustedDomains on both the desktop
21
+ and Android sides, so a fresh file has them.
22
+ - The banner button no longer trusts a bare resolve: it only ever ADDS, so
23
+ anything but `trusted: true` is a failed write, and it says so on the button
24
+ instead of removing a banner that will come back. That check is what would
25
+ have caught this bug at the UI instead of at a grep of the JSON.
17
26
 
18
- - **Trust never silences forgery evidence.** SPF_FAIL, a DMARC failure, a
19
- FORGED_* rule, self-spoof, relay-auth mismatch — all still render, at full
20
- severity, on a trusted sender.
21
- - **Trust counts only where the sender is PROVED** (DMARC, DKIM_VALID_AU, or
22
- ALL_TRUSTED). Otherwise the approved-sender list would be a switch a forger
23
- flips by typing a trusted address into From. A trusted address that cannot be
24
- proved now gets a SHARPER warning than an untrusted one: "This claims to be a
25
- sender you trust, but nothing proves it is."
26
- - **senderTrusted is narrower than allowRemote.** The recipient-alias list says
27
- mail reached an address of the reader's, which permits images; it is not a
28
- statement about who sent it, and the trust banner asks about the sender.
29
-
30
- The measurement is unchanged — spamScoreOf still reports the score, kind and
31
- reasons, with `trusted: true` alongside. Only the display goes.
27
+ tests/allowlist-merge.test.ts covers the shape that loses data, including a
28
+ field named nowhere in the code.
@@ -4122,7 +4122,9 @@ var init_web_settings = __esm({
4122
4122
  domains: [],
4123
4123
  recipients: [],
4124
4124
  flaggedSenders: [],
4125
- flaggedDomains: []
4125
+ flaggedDomains: [],
4126
+ trustedSenders: [],
4127
+ trustedDomains: []
4126
4128
  };
4127
4129
  PREV_KEEP = 5;
4128
4130
  SHARED_REFRESH_MS = 5 * 6e4;
@@ -7013,6 +7015,31 @@ var WebMailxService = class _WebMailxService {
7013
7015
  });
7014
7016
  return { flagged };
7015
7017
  }
7018
+ /** Trust (or untrust) a sender / domain for the spam banner ONLY — no
7019
+ * remote content. Mirrors MailxService.trustSenderOrDomain; the desktop
7020
+ * and Android halves must answer "is this sender trusted" the same way or
7021
+ * the same message reads differently on the phone. */
7022
+ async trustSenderOrDomain(type, value) {
7023
+ const v = (value || "").trim().toLowerCase();
7024
+ if (!v)
7025
+ return { trusted: false };
7026
+ let trusted = false;
7027
+ await updateAllowlist((list) => {
7028
+ const key = type === "sender" ? "trustedSenders" : "trustedDomains";
7029
+ const arr = Array.isArray(list[key]) ? list[key] : [];
7030
+ const idx = arr.findIndex((x) => (x || "").toLowerCase() === v);
7031
+ if (idx >= 0) {
7032
+ arr.splice(idx, 1);
7033
+ trusted = false;
7034
+ } else {
7035
+ arr.push(v);
7036
+ trusted = true;
7037
+ }
7038
+ list[key] = arr;
7039
+ return list;
7040
+ });
7041
+ return { trusted };
7042
+ }
7016
7043
  async updateFlags(accountId, uid, flags) {
7017
7044
  const envelope = this.db.getMessageByUid(accountId, uid);
7018
7045
  await this.syncManager.updateFlagsLocal(accountId, uid, envelope?.folderId || 0, flags);
@@ -7029,7 +7056,9 @@ var WebMailxService = class _WebMailxService {
7029
7056
  domains: list.domains || [],
7030
7057
  recipients: list.recipients || [],
7031
7058
  flaggedSenders: list.flaggedSenders || [],
7032
- flaggedDomains: list.flaggedDomains || []
7059
+ flaggedDomains: list.flaggedDomains || [],
7060
+ trustedSenders: list.trustedSenders || [],
7061
+ trustedDomains: list.trustedDomains || []
7033
7062
  };
7034
7063
  }
7035
7064
  async allowRemoteContent(type, value) {
@@ -12498,6 +12527,9 @@ function installBridge() {
12498
12527
  return { ok: true };
12499
12528
  },
12500
12529
  getAllowlist: () => service.getAllowlist(),
12530
+ trustSenderOrDomain: async (type, value) => {
12531
+ return await service.trustSenderOrDomain(type, value);
12532
+ },
12501
12533
  flagSenderOrDomain: async (type, value) => {
12502
12534
  return await service.flagSenderOrDomain(type, value);
12503
12535
  },