@ni-c/imap-mcp 0.2.0 → 0.4.0

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 (67) hide show
  1. package/README.md +142 -35
  2. package/dist/analyze.d.ts +54 -6
  3. package/dist/analyze.js +295 -27
  4. package/dist/analyze.js.map +1 -1
  5. package/dist/attachments.d.ts +36 -0
  6. package/dist/attachments.js +21 -3
  7. package/dist/attachments.js.map +1 -1
  8. package/dist/audit.d.ts +7 -0
  9. package/dist/audit.js +11 -3
  10. package/dist/audit.js.map +1 -1
  11. package/dist/config.d.ts +32 -0
  12. package/dist/config.js +65 -6
  13. package/dist/config.js.map +1 -1
  14. package/dist/errors.js.map +1 -1
  15. package/dist/extract/child.d.ts +1 -0
  16. package/dist/extract/child.js +83 -0
  17. package/dist/extract/child.js.map +1 -0
  18. package/dist/extract/index.d.ts +41 -0
  19. package/dist/extract/index.js +183 -0
  20. package/dist/extract/index.js.map +1 -0
  21. package/dist/extract/ooxml.d.ts +35 -0
  22. package/dist/extract/ooxml.js +627 -0
  23. package/dist/extract/ooxml.js.map +1 -0
  24. package/dist/extract/pdf.d.ts +62 -0
  25. package/dist/extract/pdf.js +539 -0
  26. package/dist/extract/pdf.js.map +1 -0
  27. package/dist/extract/types.d.ts +56 -0
  28. package/dist/extract/types.js +13 -0
  29. package/dist/extract/types.js.map +1 -0
  30. package/dist/imap.js.map +1 -1
  31. package/dist/index.js +32 -5
  32. package/dist/index.js.map +1 -1
  33. package/dist/output-schema.d.ts +63 -0
  34. package/dist/output-schema.js +87 -0
  35. package/dist/output-schema.js.map +1 -0
  36. package/dist/resources.d.ts +1 -1
  37. package/dist/resources.js +5 -2
  38. package/dist/resources.js.map +1 -1
  39. package/dist/result.d.ts +39 -6
  40. package/dist/result.js +142 -29
  41. package/dist/result.js.map +1 -1
  42. package/dist/schema.d.ts +13 -1
  43. package/dist/schema.js +20 -2
  44. package/dist/schema.js.map +1 -1
  45. package/dist/server.d.ts +1 -1
  46. package/dist/server.js +30 -5
  47. package/dist/server.js.map +1 -1
  48. package/dist/tools/annotations.d.ts +32 -0
  49. package/dist/tools/annotations.js +33 -0
  50. package/dist/tools/annotations.js.map +1 -0
  51. package/dist/tools/catalogue.d.ts +2 -2
  52. package/dist/tools/read.d.ts +1 -1
  53. package/dist/tools/read.js +743 -87
  54. package/dist/tools/read.js.map +1 -1
  55. package/dist/tools/write.d.ts +3 -3
  56. package/dist/tools/write.js +174 -39
  57. package/dist/tools/write.js.map +1 -1
  58. package/package.json +17 -11
  59. package/dist/approval.d.ts +0 -45
  60. package/dist/approval.js +0 -69
  61. package/dist/approval.js.map +0 -1
  62. package/dist/confirm.d.ts +0 -59
  63. package/dist/confirm.js +0 -92
  64. package/dist/confirm.js.map +0 -1
  65. package/dist/tool-filter.d.ts +0 -45
  66. package/dist/tool-filter.js +0 -171
  67. package/dist/tool-filter.js.map +0 -1
package/dist/analyze.js CHANGED
@@ -45,9 +45,18 @@ const INJECTION_PATTERNS = [
45
45
  'role-injection',
46
46
  /(?:^|[-\u2014|>\])]\s{0,3})(system|assistant|developer)\s*:/im,
47
47
  ],
48
+ // Anchored at the start of the run. Without the lookbehind, `-{3,}` was
49
+ // tried from every position inside a run and backtracked once per possible
50
+ // length each time, which is quadratic on text that is nothing but hyphens:
51
+ // 40 000 of them took 1.5 s, and the million characters an extracted
52
+ // document may carry would have held this process — the whole server, its
53
+ // transport is stdio — for a quarter of an hour. A few kilobytes on the
54
+ // wire. With it, a run is one attempt from its first character and the
55
+ // positions inside it fail in constant time: a million hyphens in 5 ms,
56
+ // and a delimiter of any length is still found.
48
57
  [
49
58
  'fake-delimiter',
50
- /(-{3,}|={3,}|#{3,})\s*(begin|end|system|instruction|prompt)/i,
59
+ /(?<![-=#])(-{3,}|={3,}|#{3,})\s*(begin|end|system|instruction|prompt)/i,
51
60
  ],
52
61
  [
53
62
  'tool-coercion',
@@ -86,46 +95,282 @@ const INJECTION_PATTERNS = [
86
95
  ],
87
96
  ];
88
97
  /**
89
- * Cap on the HTML handed to the removal regexes, and on the span a single one
90
- * of them may swallow. Both exist for the same reason: an unbounded `[\s\S]*?`
91
- * scanning for a closing tag that never comes is quadratic, and a crafted
92
- * 2 MB body full of unclosed tags turns that into minutes of CPU. Bounding the
93
- * scan makes the worst case a nuisance instead of a hang, at the cost that a
94
- * hidden element larger than the bound is no longer removed which is why
95
- * this pass is best effort and the fencing in {@link wrapUntrusted} is what
96
- * actually carries the weight.
98
+ * Cap on the HTML this pass looks at, and on the span a single element may
99
+ * swallow.
100
+ *
101
+ * Neither of these is what keeps the pass cheap, and the previous version of
102
+ * this comment claimed otherwise. Removing an element means scanning forward
103
+ * for a closing token, and a bound on *that* scan bounds one factor of a
104
+ * product whose other factor is the number of scans an input can start. A body
105
+ * of `'<style '` repeated 73 000 times is 512 000 legal bytes that start 73 000
106
+ * bounded scans and finish none of them: the removal regexes this used to be
107
+ * built from took 33 seconds on it, on a single-threaded process whose
108
+ * transport is stdio. The scan below is a single left-to-right walk instead, so
109
+ * the number of start tokens no longer multiplies anything.
97
110
  */
98
111
  const MAX_HTML_CHARS = 512_000;
99
112
  const MAX_REMOVED_BLOCK_CHARS = 50_000;
100
113
  const MAX_HIDDEN_ELEMENT_CHARS = 10_000;
101
- const HTML_COMMENT = new RegExp(`<!--[\\s\\S]{0,${MAX_REMOVED_BLOCK_CHARS}}?-->`, 'g');
102
- const NON_CONTENT_ELEMENT = new RegExp(`<(script|style|head|title|noscript|template)\\b[\\s\\S]{0,${MAX_REMOVED_BLOCK_CHARS}}?<\\/\\1>`, 'gi');
103
- const HIDDEN_ELEMENT = new RegExp(`<([a-z0-9]+)\\b[^>]*style\\s*=\\s*("|')[^"']*(display\\s*:\\s*none|visibility\\s*:\\s*hidden|opacity\\s*:\\s*0|font-size\\s*:\\s*0)[^"']*\\2[^>]*>[\\s\\S]{0,${MAX_HIDDEN_ELEMENT_CHARS}}?<\\/\\1>`, 'gi');
104
114
  /**
105
- * Extracts readable text from HTML.
115
+ * Total characters the walk may spend looking for closing tags, across the
116
+ * whole document.
117
+ *
118
+ * This is the cap on the product. Each successful removal costs the length of
119
+ * what it removed, and removals do not overlap, so an honest document never
120
+ * comes close; only an input that starts removals it never closes can exhaust
121
+ * it. Once it is gone the remaining elements are stripped as ordinary tags and
122
+ * their content stays visible — best effort degrading to less effort, never to
123
+ * a stalled server.
124
+ */
125
+ const CLOSER_SCAN_BUDGET_FACTOR = 4;
126
+ const CLOSER_SCAN_BUDGET_FLOOR = 100_000;
127
+ /**
128
+ * Elements whose content the recipient never reads.
129
+ *
130
+ * The `w:`-prefixed names are WordprocessingML, not HTML: this walk is also how
131
+ * the text of a .docx attachment is read. A Word field code
132
+ * (`INCLUDEPICTURE "http://…"`, a DDE command) is markup the reader never sees
133
+ * for exactly the same reason a `<script>` body is, and `w:delText` is text a
134
+ * tracked change deleted — shown struck through at most, and not at all in the
135
+ * view a document is read in.
136
+ */
137
+ const NON_CONTENT_TAGS = new Set([
138
+ 'script',
139
+ 'style',
140
+ 'head',
141
+ 'title',
142
+ 'noscript',
143
+ 'template',
144
+ 'w:instrtext',
145
+ 'w:deltext',
146
+ ]);
147
+ /**
148
+ * Closing tags that end a visual block, and so earn a line break.
149
+ *
150
+ * The namespaced names are the OOXML and OpenDocument paragraph, heading and
151
+ * row elements. Without them a whole .docx comes back as one line, because
152
+ * nothing else in a document part ever closes a block.
153
+ */
154
+ const BLOCK_TAGS = new Set([
155
+ 'p',
156
+ 'div',
157
+ 'tr',
158
+ 'li',
159
+ 'h1',
160
+ 'h2',
161
+ 'h3',
162
+ 'h4',
163
+ 'h5',
164
+ 'h6',
165
+ 'w:p',
166
+ 'w:tr',
167
+ 'a:p',
168
+ 'text:p',
169
+ 'text:h',
170
+ 'table:table-row',
171
+ ]);
172
+ // The name may carry a namespace prefix and a hyphen: `</w:p>`, `</text:h>`,
173
+ // `</table:table-row>`. Without the colon and the hyphen this matched `w` for
174
+ // `</w:p>`, so every namespaced entry in the sets above would be dead code.
175
+ // HTML is unaffected — no HTML element name contains either character, and a
176
+ // custom element (`<my-widget>`) is in none of the sets under either reading.
177
+ const TAG_NAME = /^<\/?([A-Za-z][A-Za-z0-9:_.-]*)/;
178
+ const BR_TAG = /^<br\s*\/?$/i;
179
+ const STYLE_ATTRIBUTE = /style\s*=\s*("|')/gi;
180
+ const HIDDEN_VALUE = /display\s*:\s*none|visibility\s*:\s*hidden|opacity\s*:\s*0|font-size\s*:\s*0/i;
181
+ /**
182
+ * Whether a start tag carries an inline style that hides it.
183
+ *
184
+ * Written as "find the attribute, then look inside its value" rather than as
185
+ * one pattern spanning both, because the one-pattern form has to guess where
186
+ * the value ends and backtrack when it guesses wrong. Here each style value is
187
+ * inspected once and the walk over the tag never turns around.
188
+ */
189
+ function hasHiddenStyle(tag) {
190
+ STYLE_ATTRIBUTE.lastIndex = 0;
191
+ for (let match = STYLE_ATTRIBUTE.exec(tag); match !== null; match = STYLE_ATTRIBUTE.exec(tag)) {
192
+ const quote = match[1];
193
+ const start = match.index + match[0].length;
194
+ const end = tag.indexOf(quote, start);
195
+ if (end < 0)
196
+ return false;
197
+ if (HIDDEN_VALUE.test(tag.slice(start, end)))
198
+ return true;
199
+ STYLE_ATTRIBUTE.lastIndex = end;
200
+ }
201
+ return false;
202
+ }
203
+ /**
204
+ * Extracts readable text from HTML — and from the XML inside an OOXML or
205
+ * OpenDocument attachment, which is the same problem with different tag names.
206
+ *
207
+ * Reused there rather than reimplemented, and that is a security decision, not
208
+ * a tidiness one. The obvious `document.xml` reader is
209
+ * `/<w:t[^>]*>([\s\S]*?)<\/w:t>/g` — which is the exact shape of the bug
210
+ * recorded above this function: *n* start tokens each paying for a scan that
211
+ * never finds its end. A `document.xml` of `'<w:t '` repeated 200 000 times is
212
+ * a tiny, deflate-friendly ZIP entry. This walk is immune for the reason it was
213
+ * written, so the second parser is the one not to write.
214
+ *
215
+ * It is also why nothing here parses XML properly. A real parser resolves
216
+ * entities, and would hand a mail attachment billion-laughs expansion and an
217
+ * `<!ENTITY … SYSTEM "file:///etc/passwd">` that reads a file. Those are not
218
+ * defended against below; they are simply not implemented. `&lol9;` comes out
219
+ * as six literal characters, and it must stay that way — reaching for
220
+ * `fast-xml-parser` here would reintroduce all three at once.
106
221
  *
107
222
  * Deliberately not `mailparser`'s own `text` fallback: that keeps content the
108
223
  * recipient never sees. Anything hidden by inline CSS is a place to park an
109
224
  * instruction meant only for the model, so those elements are dropped before
110
- * the tags are stripped. Best effort, not a guarantee: nested same-name tags
111
- * end the non-greedy match early, and elements hidden via a stylesheet class
112
- * are not recognised at all.
225
+ * the tags are stripped.
226
+ *
227
+ * `maxChars` overrides the input slice. The default suits a mail body; a
228
+ * document part needs more, because OOXML spends most of its bytes on
229
+ * formatting and the readable text is a small fraction of it.
230
+ *
231
+ * This is one pass over the input. The cursors below only ever move forward,
232
+ * which is the property that makes the whole function linear no matter what the
233
+ * sender writes: a start token that is never closed is answered once and then
234
+ * never looked for again, instead of restarting a bounded scan at every
235
+ * occurrence. Removal itself stays best effort — nested same-name tags end a
236
+ * block early, elements hidden via a stylesheet class are not recognised at
237
+ * all, and anything past the scan budget is left in place. That is acceptable
238
+ * for the same reason it always was: nothing downstream trusts the stripping,
239
+ * and the fencing in {@link wrapUntrusted} is what carries the weight.
113
240
  */
114
- export function htmlToText(html) {
115
- return html
116
- .slice(0, MAX_HTML_CHARS)
117
- .replace(HTML_COMMENT, ' ')
118
- .replace(NON_CONTENT_ELEMENT, ' ')
119
- .replace(HIDDEN_ELEMENT, ' ')
120
- .replace(/<br\s*\/?>/gi, '\n')
121
- .replace(/<\/(p|div|tr|li|h[1-6])>/gi, '\n')
122
- .replace(/<[^>]+>/g, ' ')
241
+ export function htmlToText(html, maxChars = MAX_HTML_CHARS) {
242
+ const source = html.slice(0, maxChars);
243
+ const out = [];
244
+ // Forward-only cursors. Each call may advance them, never rewind them, so
245
+ // across the whole document each scans the input at most once — the same
246
+ // reason a `-->` that does not exist costs one pass rather than one per
247
+ // `<!--`.
248
+ let nextGt = source.indexOf('>');
249
+ let nextCommentEnd = source.indexOf('-->');
250
+ const gtFrom = (from) => {
251
+ while (nextGt >= 0 && nextGt < from)
252
+ nextGt = source.indexOf('>', nextGt + 1);
253
+ return nextGt;
254
+ };
255
+ const commentEndFrom = (from) => {
256
+ while (nextCommentEnd >= 0 && nextCommentEnd < from) {
257
+ nextCommentEnd = source.indexOf('-->', nextCommentEnd + 1);
258
+ }
259
+ return nextCommentEnd;
260
+ };
261
+ let budget = source.length * CLOSER_SCAN_BUDGET_FACTOR + CLOSER_SCAN_BUDGET_FLOOR;
262
+ /** Where `</name>` starts, or -1 when nothing closes this element in time. */
263
+ const closingTagFrom = (name, from, window) => {
264
+ if (budget <= 0)
265
+ return -1;
266
+ const stop = Math.min(source.length, from + window);
267
+ const needle = `</${name}>`;
268
+ let at = source.indexOf('</', from);
269
+ while (at >= 0 && at + needle.length <= stop) {
270
+ if (source.slice(at, at + needle.length).toLowerCase() === needle) {
271
+ budget -= at - from;
272
+ return at;
273
+ }
274
+ at = source.indexOf('</', at + 2);
275
+ }
276
+ // Charged against how far the search actually looked, not against the
277
+ // window: a document with no `</` at all sends every one of these to the
278
+ // end of the input, and a budget that only counted the window would let an
279
+ // attacker buy those scans at a fiftieth of their price.
280
+ budget -= (at < 0 ? source.length : Math.min(at, stop)) - from;
281
+ return -1;
282
+ };
283
+ let i = 0;
284
+ while (i < source.length) {
285
+ const lt = source.indexOf('<', i);
286
+ if (lt < 0) {
287
+ out.push(source.slice(i));
288
+ break;
289
+ }
290
+ if (lt > i)
291
+ out.push(source.slice(i, lt));
292
+ if (source.startsWith('<!--', lt)) {
293
+ const end = commentEndFrom(lt + 4);
294
+ if (end >= 0 && end - lt <= MAX_REMOVED_BLOCK_CHARS) {
295
+ out.push(' ');
296
+ i = end + 3;
297
+ }
298
+ else {
299
+ // Nothing closes it anywhere ahead, so it is text that looks like
300
+ // markup rather than markup. Emitting it keeps the reader honest.
301
+ out.push('<');
302
+ i = lt + 1;
303
+ }
304
+ continue;
305
+ }
306
+ const gt = gtFrom(lt + 1);
307
+ if (gt < 0) {
308
+ // No `>` in the rest of the document: everything from here is text.
309
+ out.push(source.slice(lt));
310
+ break;
311
+ }
312
+ const tag = source.slice(lt, gt);
313
+ const name = TAG_NAME.exec(tag)?.[1]?.toLowerCase();
314
+ const closing = tag.startsWith('</');
315
+ if (name !== undefined && !closing) {
316
+ const window = NON_CONTENT_TAGS.has(name)
317
+ ? MAX_REMOVED_BLOCK_CHARS
318
+ : hasHiddenStyle(tag)
319
+ ? MAX_HIDDEN_ELEMENT_CHARS
320
+ : 0;
321
+ if (window > 0) {
322
+ const end = closingTagFrom(name, gt + 1, window);
323
+ if (end >= 0) {
324
+ out.push(' ');
325
+ i = end + name.length + 3;
326
+ continue;
327
+ }
328
+ }
329
+ }
330
+ if (BR_TAG.test(tag)) {
331
+ out.push('\n');
332
+ }
333
+ else if (closing && name !== undefined && BLOCK_TAGS.has(name)) {
334
+ out.push('\n');
335
+ }
336
+ else {
337
+ out.push(' ');
338
+ }
339
+ i = gt + 1;
340
+ }
341
+ return (out
342
+ .join('')
123
343
  .replace(/&nbsp;/gi, ' ')
124
344
  .replace(/&lt;/gi, '<')
125
345
  .replace(/&gt;/gi, '>')
126
346
  .replace(/&quot;/gi, '"')
127
347
  .replace(/&#39;/g, "'")
128
- .replace(/&amp;/gi, '&');
348
+ // Numeric character references. Common in HTML mail (`&#8217;` for a
349
+ // curly apostrophe) and near-universal in OOXML, where a German document
350
+ // may write every umlaut this way — without this they arrive as literal
351
+ // `&#228;`. Bounded digit counts so the pattern cannot be made to scan,
352
+ // and out-of-range values produce nothing rather than a guess.
353
+ .replace(/&#x([0-9a-f]{1,6});/gi, (match, hex) => fromCodePoint(parseInt(hex, 16), match))
354
+ .replace(/&#(\d{1,7});/g, (match, digits) => fromCodePoint(Number(digits), match))
355
+ // Last, so a decoded `&amp;lt;` does not turn into a `<` the caller never
356
+ // received.
357
+ .replace(/&amp;/gi, '&'));
358
+ }
359
+ /**
360
+ * One character from a numeric reference, or the reference itself.
361
+ *
362
+ * Returning the original text for anything out of range is the conservative
363
+ * half: a reference nobody can render is better left visible than turned into a
364
+ * replacement character that reads as content. Surrogates are excluded because
365
+ * a lone one is not a character and only makes the string harder to handle
366
+ * downstream.
367
+ */
368
+ function fromCodePoint(value, original) {
369
+ if (!Number.isInteger(value) || value < 1 || value > 0x10ffff)
370
+ return original;
371
+ if (value >= 0xd800 && value <= 0xdfff)
372
+ return original;
373
+ return String.fromCodePoint(value);
129
374
  }
130
375
  /**
131
376
  * Removes the characters a human reader cannot see but the model can.
@@ -136,6 +381,20 @@ export function htmlToText(html) {
136
381
  export function stripInvisible(input) {
137
382
  return input.replace(INVISIBLE_CHARS, '').replace(CONTROL_CHARS, '');
138
383
  }
384
+ /**
385
+ * The same characters, written out as escapes instead of removed.
386
+ *
387
+ * For the places where a string has to stay recognisable as the exact thing
388
+ * that was asked for — a confirmation dialog, an audit line. Stripping alone
389
+ * says "this is not what it looked like" and then shows something that looks
390
+ * like an ordinary name; this shows which characters were in it, so a person
391
+ * deciding whether to move mail into `Archive<U+202E>` can see that the folder is
392
+ * not the `Archive` they know.
393
+ */
394
+ export function escapeInvisible(input) {
395
+ const escape = (match) => `\\u${match.codePointAt(0).toString(16).padStart(4, '0')}`;
396
+ return input.replace(INVISIBLE_CHARS, escape).replace(CONTROL_CHARS, escape);
397
+ }
139
398
  /**
140
399
  * Normalises text before it reaches the model: Unicode-folded, stripped of the
141
400
  * characters a human reader cannot see, auto-fetch markup defused, and
@@ -159,7 +418,16 @@ export function sanitizeText(input, maxChars = MAX_BODY_CHARS) {
159
418
  ? `${normalized.slice(0, maxChars)}\n… (truncated at ${maxChars} characters)`
160
419
  : normalized;
161
420
  }
162
- /** Names of the injection shapes present in `text`. */
421
+ /**
422
+ * Names of the injection shapes present in `text`.
423
+ *
424
+ * Runs in this process on text the sender wrote, up to a million characters
425
+ * of it for an extracted document — after the parser child has exited, so no
426
+ * timeout covers it. Every pattern above therefore has to be linear on a
427
+ * hostile repetition of its own trigger, and `analyze.test.ts` times each one
428
+ * on such input. A new pattern gets a line in that test before it gets a line
429
+ * in the list.
430
+ */
163
431
  export function detectSuspicious(text) {
164
432
  return INJECTION_PATTERNS.filter(([, pattern]) => pattern.test(text)).map(([name]) => name);
165
433
  }
@@ -1 +1 @@
1
- {"version":3,"file":"analyze.js","sourceRoot":"","sources":["../src/analyze.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analyze.js","sourceRoot":"","sources":["../src/analyze.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,15 @@
1
1
  import type { MessageStructureObject } from 'imapflow';
2
+ /**
3
+ * Extensions that are executable somewhere. The list is long on purpose: this
4
+ * is a refusal list applied on top of the content-type allowlist, and the cost
5
+ * of an extra entry is one unusual attachment that has to be fetched by other
6
+ * means.
7
+ *
8
+ * Exported so a test can walk it. An entry {@link extensionOf} cannot produce
9
+ * is not a stricter list, it is a longer one that refuses less — and nothing
10
+ * about reading the two declarations side by side says which is which.
11
+ */
12
+ export declare const EXECUTABLE_EXTENSIONS: Set<string>;
2
13
  export interface AttachmentCandidate {
3
14
  partId: string;
4
15
  filename: string;
@@ -13,7 +24,18 @@ export interface AttachmentCandidate {
13
24
  }
14
25
  export interface AttachmentPolicy {
15
26
  allowedTypes: string[];
27
+ /**
28
+ * Size ceiling for the destination this check is for.
29
+ *
30
+ * Per destination, because there are three of them and they answer different
31
+ * questions: what may enter the model's context, what may be written to disk,
32
+ * what a parser may be handed. The caller picks the number; naming it here
33
+ * keeps the refusal pointing at the variable an operator would actually
34
+ * change.
35
+ */
16
36
  maxBytes: number;
37
+ /** Environment variable behind {@link maxBytes}, for the refusal text. */
38
+ maxBytesName: string;
17
39
  }
18
40
  /**
19
41
  * Strips a filename down to something safe to print and to reason about.
@@ -23,6 +45,20 @@ export interface AttachmentPolicy {
23
45
  * separators is trying to be read as something it is not.
24
46
  */
25
47
  export declare function sanitizeFilename(raw: string | undefined): string;
48
+ /**
49
+ * The trailing extension of a filename, lowercased, or `''`.
50
+ *
51
+ * The character class and the length have to cover every entry of
52
+ * {@link EXECUTABLE_EXTENSIONS}, or the blocklist has entries that can never be
53
+ * read out of a name. Both used to be too narrow: `appref-ms` carries a hyphen
54
+ * and `application` is eleven characters, so both returned `''` — and an empty
55
+ * extension makes {@link checkPolicy} skip the executable check entirely rather
56
+ * than fail it. `Rechnung-2026.appref-ms` declared as `application/xml` (which
57
+ * is in the default type allowlist, and which a ClickOnce manifest genuinely
58
+ * is) therefore reached the download directory under its own name with no note
59
+ * against it. The property test over the whole set is what keeps the two in
60
+ * step from here on.
61
+ */
26
62
  export declare function extensionOf(filename: string): string;
27
63
  /**
28
64
  * Walks the MIME tree and returns every part that is an attachment.
@@ -9,8 +9,12 @@ const MAX_FILENAME_LENGTH = 120;
9
9
  * is a refusal list applied on top of the content-type allowlist, and the cost
10
10
  * of an extra entry is one unusual attachment that has to be fetched by other
11
11
  * means.
12
+ *
13
+ * Exported so a test can walk it. An entry {@link extensionOf} cannot produce
14
+ * is not a stricter list, it is a longer one that refuses less — and nothing
15
+ * about reading the two declarations side by side says which is which.
12
16
  */
13
- const EXECUTABLE_EXTENSIONS = new Set([
17
+ export const EXECUTABLE_EXTENSIONS = new Set([
14
18
  'ade',
15
19
  'adp',
16
20
  'app',
@@ -133,8 +137,22 @@ export function sanitizeFilename(raw) {
133
137
  ? `${cleaned.slice(0, MAX_FILENAME_LENGTH)}…`
134
138
  : cleaned;
135
139
  }
140
+ /**
141
+ * The trailing extension of a filename, lowercased, or `''`.
142
+ *
143
+ * The character class and the length have to cover every entry of
144
+ * {@link EXECUTABLE_EXTENSIONS}, or the blocklist has entries that can never be
145
+ * read out of a name. Both used to be too narrow: `appref-ms` carries a hyphen
146
+ * and `application` is eleven characters, so both returned `''` — and an empty
147
+ * extension makes {@link checkPolicy} skip the executable check entirely rather
148
+ * than fail it. `Rechnung-2026.appref-ms` declared as `application/xml` (which
149
+ * is in the default type allowlist, and which a ClickOnce manifest genuinely
150
+ * is) therefore reached the download directory under its own name with no note
151
+ * against it. The property test over the whole set is what keeps the two in
152
+ * step from here on.
153
+ */
136
154
  export function extensionOf(filename) {
137
- const match = /\.([A-Za-z0-9]{1,10})$/.exec(filename);
155
+ const match = /\.([A-Za-z0-9-]{1,16})$/.exec(filename);
138
156
  return match?.[1]?.toLowerCase() ?? '';
139
157
  }
140
158
  /**
@@ -207,7 +225,7 @@ export function checkPolicy(candidate, policy) {
207
225
  }
208
226
  if (candidate.size !== undefined && candidate.size > policy.maxBytes) {
209
227
  allowed = false;
210
- notes.push(`refused: declared size ${candidate.size} exceeds IMAP_MAX_ATTACHMENT_BYTES (${policy.maxBytes})`);
228
+ notes.push(`refused: declared size ${candidate.size} exceeds ${policy.maxBytesName} (${policy.maxBytes})`);
211
229
  }
212
230
  return { ...candidate, allowed, notes };
213
231
  }
@@ -1 +1 @@
1
- {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../src/attachments.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../src/attachments.ts"],"names":[],"mappings":"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"}
package/dist/audit.d.ts CHANGED
@@ -13,5 +13,12 @@
13
13
  * by the sender, but it has been through sanitizeFilename — no control or
14
14
  * invisible characters, no separators — and without it the line could not say
15
15
  * which file to go and delete.
16
+ *
17
+ * That reasoning had a hole: folder names go in these lines too, and on a
18
+ * shared account they are chosen by whoever created the folder. `to=Archive`
19
+ * for a destination of `Archive<U+202E>…` is a log entry that reads as the wrong
20
+ * folder, and a CR in a name rewrites the line a human is looking at. So every
21
+ * string value is escaped on the way out — see {@link escapeInvisible}. What
22
+ * cannot be seen must not be written here.
16
23
  */
17
24
  export declare function audit(operation: string, details: Record<string, unknown>): void;
package/dist/audit.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { escapeInvisible } from './analyze.js';
1
2
  /**
2
3
  * Records every change this server makes to the mailbox.
3
4
  *
@@ -13,6 +14,13 @@
13
14
  * by the sender, but it has been through sanitizeFilename — no control or
14
15
  * invisible characters, no separators — and without it the line could not say
15
16
  * which file to go and delete.
17
+ *
18
+ * That reasoning had a hole: folder names go in these lines too, and on a
19
+ * shared account they are chosen by whoever created the folder. `to=Archive`
20
+ * for a destination of `Archive<U+202E>…` is a log entry that reads as the wrong
21
+ * folder, and a CR in a name rewrites the line a human is looking at. So every
22
+ * string value is escaped on the way out — see {@link escapeInvisible}. What
23
+ * cannot be seen must not be written here.
16
24
  */
17
25
  export function audit(operation, details) {
18
26
  const fields = Object.entries(details)
@@ -25,9 +33,9 @@ export function audit(operation, details) {
25
33
  function format(value) {
26
34
  if (Array.isArray(value)) {
27
35
  return value.length > 20
28
- ? `[${value.slice(0, 20).join(',')},…+${value.length - 20}]`
29
- : `[${value.join(',')}]`;
36
+ ? `[${escapeInvisible(value.slice(0, 20).join(','))},…+${value.length - 20}]`
37
+ : `[${escapeInvisible(value.join(','))}]`;
30
38
  }
31
- return String(value);
39
+ return escapeInvisible(String(value));
32
40
  }
33
41
  //# sourceMappingURL=audit.js.map
package/dist/audit.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,KAAK,CACnB,SAAiB,EACjB,OAAgC;IAEhC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;SACnC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC;SAC1C,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;SAChD,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,OAAO,CAAC,KAAK,CACX,kBAAkB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,SAAS,IAAI,MAAM,EAAE,CACpE,CAAC;AACJ,CAAC;AAED,4EAA4E;AAC5E,SAAS,MAAM,CAAC,KAAc;IAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,MAAM,GAAG,EAAE;YACtB,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,MAAM,GAAG,EAAE,GAAG;YAC5D,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAC7B,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,KAAK,CACnB,SAAiB,EACjB,OAAgC;IAEhC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;SACnC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC;SAC1C,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;SAChD,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,OAAO,CAAC,KAAK,CACX,kBAAkB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,SAAS,IAAI,MAAM,EAAE,CACpE,CAAC;AACJ,CAAC;AAED,4EAA4E;AAC5E,SAAS,MAAM,CAAC,KAAc;IAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,MAAM,GAAG,EAAE;YACtB,CAAC,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,MAAM,GAAG,EAAE,GAAG;YAC7E,CAAC,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;IAC9C,CAAC;IACD,OAAO,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,CAAC"}
package/dist/config.d.ts CHANGED
@@ -34,6 +34,17 @@ export interface ImapConfig {
34
34
  */
35
35
  downloadDir: string | undefined;
36
36
  maxDownloadBytes: number;
37
+ /**
38
+ * Ceiling on the bytes handed to the text-extraction worker.
39
+ *
40
+ * A third limit because it answers a third question. `maxAttachmentBytes`
41
+ * bounds what may enter the model's context — extraction does not, since only
42
+ * the extracted text comes back and `max_chars` bounds that. `maxDownloadBytes`
43
+ * bounds what may be written to the filesystem. This one bounds how much
44
+ * hostile input a parser is asked to chew on inside a thread that can be
45
+ * terminated, which is a memory question and neither of the other two.
46
+ */
47
+ maxExtractBytes: number;
37
48
  }
38
49
  export interface Config {
39
50
  imap: ImapConfig;
@@ -48,6 +59,13 @@ export interface Config {
48
59
  * the rest of the family; the default deliberately is not.
49
60
  */
50
61
  readOnly: boolean;
62
+ /**
63
+ * Whether a client that *can* show a dialog is asked before a guarded tool
64
+ * acts. `ELICITATION=false` turns the dialog off — the guard stays and falls
65
+ * back to the two-call token, so there is no setting in which a guarded call
66
+ * goes unannounced.
67
+ */
68
+ elicitation: boolean;
51
69
  /**
52
70
  * Raw value of `IMAP_ALLOW_TOOLS` — comma-separated tool names, `list_*`
53
71
  * prefixes, or `essential`. Kept unparsed on purpose: this file is a mirror
@@ -73,3 +91,17 @@ export declare function missingConfigKeys(config: Config): string[];
73
91
  * IMAP session, and a bad port would connect somewhere unintended.
74
92
  */
75
93
  export declare function loadConfig(env?: NodeJS.ProcessEnv): Config;
94
+ /**
95
+ * Reads `ELICITATION` — deliberately unprefixed, and deliberately fatal on
96
+ * anything it does not recognise.
97
+ *
98
+ * Unprefixed: environment variables are process-wide, so this is one switch for
99
+ * every server in the same environment. That is also its risk, which is why a
100
+ * server started with it off says so on its startup line.
101
+ *
102
+ * Fatal, like `parseTlsMode` above and unlike `IMAP_READ_ONLY`: this is the
103
+ * first variable of the family that defaults to *on*, so a typo that fell back
104
+ * to the default would leave the dialog running while the operator believes it
105
+ * is off — and an operator who believes that has no way to find out.
106
+ */
107
+ export declare function parseElicitation(raw: string | undefined): boolean;