@bobfrankston/rmfmail 1.1.136 → 1.1.138

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/npmchanges.md CHANGED
@@ -451,3 +451,53 @@ feat: elapsed-time wait indicator + autocomplete + invalid-addr UX
451
451
  Message text bumped to "Invalid address: '...' — Send blocked" so
452
452
  the user knows it's the gating condition, not a transient note.
453
453
 
454
+ ## v1.1.136 — 2026-05-24
455
+
456
+ feat: periodic Sent sweep + body-fetch wallclock timeout
457
+
458
+ - Periodic Sent sweep (`ImapManager.startSentSweep()`): for every IMAP-
459
+ path account, every 5 minutes, walks local Sent rows cached in the
460
+ last hour and reconciles against the server's actual Sent folder by
461
+ Message-ID:
462
+ - Found at same UID → no-op.
463
+ - Found at a different UID → rebind the local row's uid in place
464
+ (mailx-store new `updateMessageUid` helper).
465
+ - Not on server + .eml on disk → IMAP APPEND from disk (no SMTP).
466
+ - Not on server + no .eml → leave; set-diff GC handles it.
467
+ Gmail accounts skipped (Sent is API-driven, no optimistic-UID race).
468
+ Fixes the "I do not see the message in sent" silent loss when the
469
+ Outbox-drain sieve appends at a different UID than mailx predicted.
470
+
471
+ - Body-fetch wallclock timeout in the reconciler. 90 s Promise.race
472
+ around fetchMessageBody so a wedged fetch (TCP half-open, parser
473
+ stuck on an incomplete literal, server stalled mid-FETCH) can't
474
+ pin inFlightFetches forever. Without this, one stuck UID drained
475
+ the concurrency budget and every subsequent click sat behind it
476
+ for the lifetime of the daemon. On timeout, the existing transient-
477
+ error path requeues with attempt budget (3 tries) so the user's
478
+ fetch eventually completes or surfaces as bodyFetchError. Pairs
479
+ with the elapsed-time wait indicator (1.1.135) — the indicator
480
+ surfaces a wedge, the timeout breaks one.
481
+
482
+ ## v1.1.137 — 2026-05-24
483
+
484
+ fix: defensive IMAP-command-leak detection at body-store boundary
485
+
486
+ When iflow-direct's response parser desyncs on a literal byte count, the
487
+ "body" it returns can begin with one of mailx's own pipelined IMAP
488
+ commands (e.g. `A24624 UID FETCH 52 (UID FLAGS ENVELOPE ...)`). Until
489
+ now those bytes were silently written to disk as the message body and
490
+ rendered as broken (the a39…eml corruption from 2026-05-23).
491
+
492
+ mailx-store/file-store.putMessage now sniffs the first ≤512 bytes for a
493
+ tag+UPPERCASE-command pattern and throws rather than persist. The
494
+ reconciler treats the rejection as transient so the next fetch (on a
495
+ freshly-acquired connection) re-attempts cleanly, within the 3-attempt
496
+ body-fetch budget.
497
+
498
+ This doesn't FIX the iflow desync itself — it catches the leak at the
499
+ disk boundary so corrupt bodies never persist and the wedged message
500
+ gets retried instead of staying broken until the next -repair. Pairs
501
+ with the elapsed-time wait indicator (1.1.135) which surfaces the
502
+ in-progress retry to the user.
503
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/rmfmail",
3
- "version": "1.1.136",
3
+ "version": "1.1.138",
4
4
  "description": "Local-first email client with IMAP sync and standalone native app",
5
5
  "type": "module",
6
6
  "main": "bin/mailx.js",
@@ -38,7 +38,7 @@
38
38
  "dependencies": {
39
39
  "@bobfrankston/iflow-direct": "^0.1.50",
40
40
  "@bobfrankston/mailx-host": "^0.1.13",
41
- "@bobfrankston/mailx-imap": "^0.1.58",
41
+ "@bobfrankston/mailx-imap": "^0.1.59",
42
42
  "@bobfrankston/mailx-store-web": "^0.1.22",
43
43
  "@bobfrankston/mailx-sync": "^0.1.19",
44
44
  "@bobfrankston/miscinfo": "^1.0.12",
@@ -118,7 +118,7 @@
118
118
  "dependencies": {
119
119
  "@bobfrankston/iflow-direct": "^0.1.50",
120
120
  "@bobfrankston/mailx-host": "^0.1.13",
121
- "@bobfrankston/mailx-imap": "^0.1.58",
121
+ "@bobfrankston/mailx-imap": "^0.1.59",
122
122
  "@bobfrankston/mailx-store-web": "^0.1.22",
123
123
  "@bobfrankston/mailx-sync": "^0.1.19",
124
124
  "@bobfrankston/miscinfo": "^1.0.12",
@@ -1 +1 @@
1
- {"version":3,"file":"reconciler.d.ts","sourceRoot":"","sources":["reconciler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IAC9B;;sDAEkD;IAClD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,qEAAqE;IACrE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;8DAC0D;IAC1D,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;0EACsE;IACtE,6BAA6B,CAAC,EAAE,MAAM,CAAC;IACvC,mEAAmE;IACnE,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;yCACqC;IACrC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACnC;AAYD,qBAAa,UAAU;IAcf,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,KAAK;IAfjB,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAA+C;IAClE,OAAO,CAAC,aAAa,CAA+C;IACpE,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,eAAe,CAAK;IAC5B;;;wEAGoE;IACpE,OAAO,CAAC,UAAU,CAAgE;gBAGtE,EAAE,EAAE,OAAO,EACX,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,SAAS,EACxB,IAAI,GAAE,iBAAsB;IAKhC,KAAK,IAAI,IAAI;IAyCb,IAAI,IAAI,IAAI;IAOZ;oDACgD;IAChD,OAAO,CAAC,iBAAiB;IAMzB;;;gDAG4C;IAC5C,OAAO,CAAC,eAAe;IAoBvB;oEACgE;IAChE,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAOjC;;2DAEuD;IACvD,OAAO,CAAC,eAAe;IA0GvB,yEAAyE;IACzE,IAAI,IAAI,IAAI;CAGf"}
1
+ {"version":3,"file":"reconciler.d.ts","sourceRoot":"","sources":["reconciler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IAC9B;;sDAEkD;IAClD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,qEAAqE;IACrE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;8DAC0D;IAC1D,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;0EACsE;IACtE,6BAA6B,CAAC,EAAE,MAAM,CAAC;IACvC,mEAAmE;IACnE,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;yCACqC;IACrC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACnC;AAYD,qBAAa,UAAU;IAcf,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,KAAK;IAfjB,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAA+C;IAClE,OAAO,CAAC,aAAa,CAA+C;IACpE,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,eAAe,CAAK;IAC5B;;;wEAGoE;IACpE,OAAO,CAAC,UAAU,CAAgE;gBAGtE,EAAE,EAAE,OAAO,EACX,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,SAAS,EACxB,IAAI,GAAE,iBAAsB;IAKhC,KAAK,IAAI,IAAI;IAyCb,IAAI,IAAI,IAAI;IAOZ;oDACgD;IAChD,OAAO,CAAC,iBAAiB;IAMzB;;;gDAG4C;IAC5C,OAAO,CAAC,eAAe;IAoBvB;oEACgE;IAChE,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAOjC;;2DAEuD;IACvD,OAAO,CAAC,eAAe;IA8GvB,yEAAyE;IACzE,IAAI,IAAI,IAAI;CAGf"}
@@ -229,7 +229,11 @@ export class Reconciler {
229
229
  }
230
230
  else {
231
231
  const msg = err?.message || "body fetch failed";
232
- const transient = /connection|Too many|UNAVAILABLE|rate|429|5\d\d|timeout|ENOTFOUND|ECONNRESET|ETIMEDOUT/i.test(msg);
232
+ // `IMAP command leaked into response stream` is the
233
+ // file-store's defensive rejection of a desync'd
234
+ // body. Treat as transient: the next fetch on a
235
+ // fresh client will likely produce a clean payload.
236
+ const transient = /connection|Too many|UNAVAILABLE|rate|429|5\d\d|timeout|ENOTFOUND|ECONNRESET|ETIMEDOUT|IMAP command leaked/i.test(msg);
233
237
  // Transient: re-enqueue (budget=3) so the next pump
234
238
  // tick retries. Surface the error only when the
235
239
  // budget is exhausted — otherwise we'd flash banners
@@ -1 +1 @@
1
- {"version":3,"file":"reconciler.js","sourceRoot":"","sources":["reconciler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reconciler.js","sourceRoot":"","sources":["reconciler.ts"],"names":[],"mappings":"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"}
@@ -255,7 +255,11 @@ export class Reconciler {
255
255
  } catch { /* */ }
256
256
  } else {
257
257
  const msg = err?.message || "body fetch failed";
258
- const transient = /connection|Too many|UNAVAILABLE|rate|429|5\d\d|timeout|ENOTFOUND|ECONNRESET|ETIMEDOUT/i.test(msg);
258
+ // `IMAP command leaked into response stream` is the
259
+ // file-store's defensive rejection of a desync'd
260
+ // body. Treat as transient: the next fetch on a
261
+ // fresh client will likely produce a clean payload.
262
+ const transient = /connection|Too many|UNAVAILABLE|rate|429|5\d\d|timeout|ENOTFOUND|ECONNRESET|ETIMEDOUT|IMAP command leaked/i.test(msg);
259
263
  // Transient: re-enqueue (budget=3) so the next pump
260
264
  // tick retries. Surface the error only when the
261
265
  // budget is exhausted — otherwise we'd flash banners
@@ -26,7 +26,16 @@ export declare class FileMessageStore implements MessageStore {
26
26
  private resolveStored;
27
27
  /** Write a new body. Returns a path RELATIVE to basePath; caller stores
28
28
  * it in `body_path`. The (folderId, uid) args are kept for interface
29
- * compatibility; they do NOT affect the filename. */
29
+ * compatibility; they do NOT affect the filename.
30
+ *
31
+ * Defensive content check: if the FIRST line of the would-be .eml
32
+ * matches an IMAP client-command pattern (`<tag> <UPPERCASE_CMD> ...`),
33
+ * the upstream IMAP parser desynced and wrote one of mailx's own
34
+ * outbound commands into the response stream — see the
35
+ * a39a84e1853441bcac09e1b3e1463e8d.eml corruption (2026-05-23). Refuse
36
+ * the write rather than persist garbage that the message-viewer will
37
+ * later render as broken. The caller's exception path treats this the
38
+ * same as any other transient fetch error; the reconciler re-enqueues. */
30
39
  putMessage(accountId: string, _folderId: number, _uid: number, raw: Buffer): Promise<string>;
31
40
  /** Resolve a stored body_path (relative or absolute) to an absolute
32
41
  * filesystem path. Returns "" if the input doesn't resolve to a file
@@ -1 +1 @@
1
- {"version":3,"file":"file-store.d.ts","sourceRoot":"","sources":["file-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,qBAAa,gBAAiB,YAAW,YAAY;IACrC,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;IAIpC;;;sCAGkC;IAClC,OAAO,CAAC,eAAe;IAMvB;;;gDAG4C;IAC5C,OAAO,CAAC,aAAa;IAQrB;;0DAEsD;IAChD,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQlG;;;;2CAIuC;IACvC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIpC,kDAAkD;IAC5C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAM3C,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK3C,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjD;;;;;;;;;uDASmD;IACnD,yBAAyB,CAAC,IAAI,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,EAC7C,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM;IA6BjF,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAGrE,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAGhF,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAGjF,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG1F"}
1
+ {"version":3,"file":"file-store.d.ts","sourceRoot":"","sources":["file-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,qBAAa,gBAAiB,YAAW,YAAY;IACrC,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;IAIpC;;;sCAGkC;IAClC,OAAO,CAAC,eAAe;IAMvB;;;gDAG4C;IAC5C,OAAO,CAAC,aAAa;IAQrB;;;;;;;;;;;+EAW2E;IACrE,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAwBlG;;;;2CAIuC;IACvC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIpC,kDAAkD;IAC5C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAM3C,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK3C,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjD;;;;;;;;;uDASmD;IACnD,yBAAyB,CAAC,IAAI,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,EAC7C,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM;IA6BjF,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAGrE,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAGhF,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAGjF,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG1F"}
@@ -43,8 +43,33 @@ export class FileMessageStore {
43
43
  }
44
44
  /** Write a new body. Returns a path RELATIVE to basePath; caller stores
45
45
  * it in `body_path`. The (folderId, uid) args are kept for interface
46
- * compatibility; they do NOT affect the filename. */
46
+ * compatibility; they do NOT affect the filename.
47
+ *
48
+ * Defensive content check: if the FIRST line of the would-be .eml
49
+ * matches an IMAP client-command pattern (`<tag> <UPPERCASE_CMD> ...`),
50
+ * the upstream IMAP parser desynced and wrote one of mailx's own
51
+ * outbound commands into the response stream — see the
52
+ * a39a84e1853441bcac09e1b3e1463e8d.eml corruption (2026-05-23). Refuse
53
+ * the write rather than persist garbage that the message-viewer will
54
+ * later render as broken. The caller's exception path treats this the
55
+ * same as any other transient fetch error; the reconciler re-enqueues. */
47
56
  async putMessage(accountId, _folderId, _uid, raw) {
57
+ if (raw.length >= 6) {
58
+ // Look at the first ≤512 bytes to spot a leaked IMAP command.
59
+ // Pattern: optional CRLFs, then `<tag> <CMD> ...` where tag
60
+ // starts with a letter+digits (iflow tags are like `A123`,
61
+ // `B47`) and CMD is all-caps with at least 4 chars.
62
+ const sniff = raw.subarray(0, Math.min(512, raw.length)).toString("ascii");
63
+ const firstNonBlank = sniff.replace(/^\s+/, "");
64
+ // Strict: tag is letter + digits, then a space, then an
65
+ // all-caps IMAP command keyword. Real RFC822 headers can't
66
+ // match because they require a `Name: value` shape (colon),
67
+ // and `Return-Path:`, `Received:`, `Subject:` etc. are
68
+ // capitalized but include a colon and mixed case in tokens.
69
+ if (/^[A-Z]+\d+ (UID )?(FETCH|SEARCH|STORE|COPY|MOVE|EXPUNGE|SELECT|EXAMINE|APPEND|LIST|LSUB|STATUS|NOOP|IDLE|DONE|LOGIN|LOGOUT|CAPABILITY|AUTHENTICATE)\b/.test(firstNonBlank)) {
70
+ throw new Error(`putMessage: refusing to write corrupt body — IMAP command leaked into response stream (first line: ${firstNonBlank.split(/\r?\n/)[0].substring(0, 100)})`);
71
+ }
72
+ }
48
73
  const rel = this.newRelativePath(accountId);
49
74
  const abs = path.join(this.basePath, rel);
50
75
  fs.mkdirSync(path.dirname(abs), { recursive: true });
@@ -1 +1 @@
1
- {"version":3,"file":"file-store.js","sourceRoot":"","sources":["file-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"file-store.js","sourceRoot":"","sources":["file-store.ts"],"names":[],"mappings":"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"}
@@ -45,8 +45,33 @@ export class FileMessageStore implements MessageStore {
45
45
 
46
46
  /** Write a new body. Returns a path RELATIVE to basePath; caller stores
47
47
  * it in `body_path`. The (folderId, uid) args are kept for interface
48
- * compatibility; they do NOT affect the filename. */
48
+ * compatibility; they do NOT affect the filename.
49
+ *
50
+ * Defensive content check: if the FIRST line of the would-be .eml
51
+ * matches an IMAP client-command pattern (`<tag> <UPPERCASE_CMD> ...`),
52
+ * the upstream IMAP parser desynced and wrote one of mailx's own
53
+ * outbound commands into the response stream — see the
54
+ * a39a84e1853441bcac09e1b3e1463e8d.eml corruption (2026-05-23). Refuse
55
+ * the write rather than persist garbage that the message-viewer will
56
+ * later render as broken. The caller's exception path treats this the
57
+ * same as any other transient fetch error; the reconciler re-enqueues. */
49
58
  async putMessage(accountId: string, _folderId: number, _uid: number, raw: Buffer): Promise<string> {
59
+ if (raw.length >= 6) {
60
+ // Look at the first ≤512 bytes to spot a leaked IMAP command.
61
+ // Pattern: optional CRLFs, then `<tag> <CMD> ...` where tag
62
+ // starts with a letter+digits (iflow tags are like `A123`,
63
+ // `B47`) and CMD is all-caps with at least 4 chars.
64
+ const sniff = raw.subarray(0, Math.min(512, raw.length)).toString("ascii");
65
+ const firstNonBlank = sniff.replace(/^\s+/, "");
66
+ // Strict: tag is letter + digits, then a space, then an
67
+ // all-caps IMAP command keyword. Real RFC822 headers can't
68
+ // match because they require a `Name: value` shape (colon),
69
+ // and `Return-Path:`, `Received:`, `Subject:` etc. are
70
+ // capitalized but include a colon and mixed case in tokens.
71
+ if (/^[A-Z]+\d+ (UID )?(FETCH|SEARCH|STORE|COPY|MOVE|EXPUNGE|SELECT|EXAMINE|APPEND|LIST|LSUB|STATUS|NOOP|IDLE|DONE|LOGIN|LOGOUT|CAPABILITY|AUTHENTICATE)\b/.test(firstNonBlank)) {
72
+ throw new Error(`putMessage: refusing to write corrupt body — IMAP command leaked into response stream (first line: ${firstNonBlank.split(/\r?\n/)[0].substring(0, 100)})`);
73
+ }
74
+ }
50
75
  const rel = this.newRelativePath(accountId);
51
76
  const abs = path.join(this.basePath, rel);
52
77
  fs.mkdirSync(path.dirname(abs), { recursive: true });
package/.commitmsg DELETED
@@ -1,25 +0,0 @@
1
- feat: periodic Sent sweep + body-fetch wallclock timeout
2
-
3
- - Periodic Sent sweep (`ImapManager.startSentSweep()`): for every IMAP-
4
- path account, every 5 minutes, walks local Sent rows cached in the
5
- last hour and reconciles against the server's actual Sent folder by
6
- Message-ID:
7
- - Found at same UID → no-op.
8
- - Found at a different UID → rebind the local row's uid in place
9
- (mailx-store new `updateMessageUid` helper).
10
- - Not on server + .eml on disk → IMAP APPEND from disk (no SMTP).
11
- - Not on server + no .eml → leave; set-diff GC handles it.
12
- Gmail accounts skipped (Sent is API-driven, no optimistic-UID race).
13
- Fixes the "I do not see the message in sent" silent loss when the
14
- Outbox-drain sieve appends at a different UID than mailx predicted.
15
-
16
- - Body-fetch wallclock timeout in the reconciler. 90 s Promise.race
17
- around fetchMessageBody so a wedged fetch (TCP half-open, parser
18
- stuck on an incomplete literal, server stalled mid-FETCH) can't
19
- pin inFlightFetches forever. Without this, one stuck UID drained
20
- the concurrency budget and every subsequent click sat behind it
21
- for the lifetime of the daemon. On timeout, the existing transient-
22
- error path requeues with attempt budget (3 tries) so the user's
23
- fetch eventually completes or surfaces as bodyFetchError. Pairs
24
- with the elapsed-time wait indicator (1.1.135) — the indicator
25
- surfaces a wedge, the timeout breaks one.