postal-mime 2.2.9 → 2.3.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.3.2](https://github.com/postalsys/postal-mime/compare/v2.3.1...v2.3.2) (2024-09-23)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * Modified README to trigger a new release (previous npm publish failed) ([f975ef4](https://github.com/postalsys/postal-mime/commit/f975ef4bc8403af72d8cd25ee2d4b3a12cdf82e4))
9
+
10
+ ## [2.3.1](https://github.com/postalsys/postal-mime/compare/v2.3.0...v2.3.1) (2024-09-23)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **message/rfc822:** Added option 'forceRfc822Attachments' to handle all message/rfc822 nodes as attachments instead of inline content ([bf47621](https://github.com/postalsys/postal-mime/commit/bf47621da7c55a31acb39fb505f415b1ed4ce5e2))
16
+
17
+ ## [2.3.0](https://github.com/postalsys/postal-mime/compare/v2.2.9...v2.3.0) (2024-09-23)
18
+
19
+
20
+ ### Features
21
+
22
+ * Treat message/rfc822 as an attachment for delivery-status and feedback-report ([21e6224](https://github.com/postalsys/postal-mime/commit/21e62245aeb416b921ba683dd8628f5948831c56))
23
+
3
24
  ## [2.2.9](https://github.com/postalsys/postal-mime/compare/v2.2.8...v2.2.9) (2024-09-16)
4
25
 
5
26
 
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Email parser for browser and serverless environments.
4
4
 
5
- PostalMime can be run in the main web thread or from Web Workers. It can also be used in serverless functions.
5
+ PostalMime can be run in the main web thread or from Web Workers. It can also be used in serverless functions like Cloudflare Email Workers.
6
6
 
7
7
  > [!TIP]
8
8
  > PostalMime is developed by the makers of **[EmailEngine](https://emailengine.app/?utm_source=github&utm_campaign=imapflow&utm_medium=readme-link)** – a self-hosted email gateway that allows making **REST requests against IMAP and SMTP servers**. EmailEngine also sends webhooks whenever something changes on the registered accounts.
@@ -98,7 +98,8 @@ Where:
98
98
 
99
99
  - **email**: The RFC822 formatted email. This can be a string, an ArrayBuffer/Uint8Array, a Blob object, a Node.js Buffer, or a [ReadableStream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream).
100
100
  - **options**: An optional object containing configuration options.
101
- - **rfc822Attachments**: A boolean (defaults to `false`). If set to `true`, it treats `Message/RFC822` attachments without a Content-Disposition declaration as attachments. By default, these messages are treated as inline values.
101
+ - **rfc822Attachments**: A boolean (defaults to `false`). If set to `true`, then treats `message/rfc822` attachments without a Content-Disposition declaration as attachments. By default, these messages are treated as inline values.
102
+ - **forceRfc822Attachments**: A boolean (defaults to `false`). If set to `true`, then treats all `message/rfc822` nodes as attachments.
102
103
 
103
104
  This method parses an email message into a structured object with the following properties:
104
105
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postal-mime",
3
- "version": "2.2.9",
3
+ "version": "2.3.2",
4
4
  "description": "Email parser for browser environments",
5
5
  "main": "./src/postal-mime.js",
6
6
  "exports": {
@@ -28,7 +28,7 @@
28
28
  "author": "Andris Reinman",
29
29
  "license": "MIT-0",
30
30
  "devDependencies": {
31
- "@types/node": "22.5.5",
31
+ "@types/node": "22.6.0",
32
32
  "cross-blob": "3.0.2",
33
33
  "cross-env": "7.0.3",
34
34
  "eslint": "8.57.0",
package/postal-mime.d.ts CHANGED
@@ -53,7 +53,8 @@ declare function decodeWords (
53
53
  ): string;
54
54
 
55
55
  declare type PostalMimeOptions = {
56
- rfc822Attachments?: boolean
56
+ rfc822Attachments?: boolean,
57
+ forceRfc822Attachments?: boolean
57
58
  }
58
59
 
59
60
  declare class PostalMime {
@@ -123,15 +123,15 @@ export default class PostalMime {
123
123
  let textTypes = new Set();
124
124
  let textMap = (this.textMap = new Map());
125
125
 
126
+ let forceRfc822Attachments = this.forceRfc822Attachments();
127
+
126
128
  let walk = async (node, alternative, related) => {
127
129
  alternative = alternative || false;
128
130
  related = related || false;
129
131
 
130
132
  if (!node.contentType.multipart) {
131
- // regular node
132
-
133
133
  // is it inline message/rfc822
134
- if (this.isInlineMessageRfc822(node)) {
134
+ if (this.isInlineMessageRfc822(node) && !forceRfc822Attachments) {
135
135
  const subParser = new PostalMime();
136
136
  node.subMessage = await subParser.parse(node.content);
137
137
 
@@ -168,9 +168,6 @@ export default class PostalMime {
168
168
  // is it text?
169
169
  else if (this.isInlineTextNode(node)) {
170
170
  let textType = node.contentType.parsed.value.substr(node.contentType.parsed.value.indexOf('/') + 1);
171
- if (node.contentType.parsed.value === 'message/delivery-status') {
172
- textType = 'plain';
173
- }
174
171
 
175
172
  let selectorNode = alternative || node;
176
173
  if (!textMap.has(selectorNode)) {
@@ -218,13 +215,6 @@ export default class PostalMime {
218
215
  break;
219
216
  }
220
217
 
221
- case 'message/delivery-status': {
222
- // Enforce into unicode
223
- const decodedText = node.getTextContent().replace(/\r?\n/g, '\n').replace(/\n*$/, '\n');
224
- attachment.content = textEncoder.encode(decodedText);
225
- break;
226
- }
227
-
228
218
  // Regular attachments
229
219
  default:
230
220
  attachment.content = node.content;
@@ -330,8 +320,6 @@ export default class PostalMime {
330
320
  switch (node.contentType.parsed.value) {
331
321
  case 'text/html':
332
322
  case 'text/plain':
333
- // message/delivery-status is cast into regular plaintext content
334
- case 'message/delivery-status':
335
323
  return true;
336
324
 
337
325
  case 'text/calendar':
@@ -349,6 +337,28 @@ export default class PostalMime {
349
337
  return disposition === 'inline';
350
338
  }
351
339
 
340
+ // Check if this is a specially crafted report email where message/rfc822 content should not be inlined
341
+ forceRfc822Attachments() {
342
+ if (this.options.forceRfc822Attachments) {
343
+ return true;
344
+ }
345
+
346
+ let forceRfc822Attachments = false;
347
+ let walk = node => {
348
+ if (!node.contentType.multipart) {
349
+ if (['message/delivery-status', 'message/feedback-report'].includes(node.contentType.parsed.value)) {
350
+ forceRfc822Attachments = true;
351
+ }
352
+ }
353
+
354
+ for (let childNode of node.childNodes) {
355
+ walk(childNode);
356
+ }
357
+ };
358
+ walk(this.root);
359
+ return forceRfc822Attachments;
360
+ }
361
+
352
362
  async resolveStream(stream) {
353
363
  let chunkLen = 0;
354
364
  let chunks = [];