nodemailer 6.9.9 → 6.9.11

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,20 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## [6.9.11](https://github.com/nodemailer/nodemailer/compare/v6.9.10...v6.9.11) (2024-02-29)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **headers:** Ensure that Content-type is the bottom header ([c7cf97e](https://github.com/nodemailer/nodemailer/commit/c7cf97e5ecc83f8eee773359951df995c9945446))
9
+
10
+ ## [6.9.10](https://github.com/nodemailer/nodemailer/compare/v6.9.9...v6.9.10) (2024-02-22)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **data-uri:** Do not use regular expressions for parsing data URI schemes ([12e65e9](https://github.com/nodemailer/nodemailer/commit/12e65e975d80efe6bafe6de4590829b3b5ebb492))
16
+ * **data-uri:** Moved all data-uri regexes to use the non-regex parseDataUri method ([edd5dfe](https://github.com/nodemailer/nodemailer/commit/edd5dfe5ce9b725f8b8ae2830797f65b2a2b0a33))
17
+
3
18
  ## [6.9.9](https://github.com/nodemailer/nodemailer/compare/v6.9.8...v6.9.9) (2024-02-01)
4
19
 
5
20
 
@@ -4,6 +4,7 @@
4
4
 
5
5
  const MimeNode = require('../mime-node');
6
6
  const mimeFuncs = require('../mime-funcs');
7
+ const parseDataURI = require('../shared').parseDataURI;
7
8
 
8
9
  /**
9
10
  * Creates the object for composing a MimeNode instance out from the mail options
@@ -537,12 +538,17 @@ class MailComposer {
537
538
  * @return {Object} Parsed element
538
539
  */
539
540
  _processDataUrl(element) {
540
- let parts = (element.path || element.href).match(/^data:((?:[^;]*;){0,20}(?:[^,]*)),(.*)$/i);
541
- if (!parts) {
541
+ let parsedDataUri;
542
+ if ((element.path || element.href).match(/^data:/)) {
543
+ parsedDataUri = parseDataURI(element.path || element.href);
544
+ }
545
+
546
+ if (!parsedDataUri) {
542
547
  return element;
543
548
  }
544
549
 
545
- element.content = /\bbase64$/i.test(parts[1]) ? Buffer.from(parts[2], 'base64') : Buffer.from(decodeURIComponent(parts[2]));
550
+ element.content = parsedDataUri.data;
551
+ element.contentType = element.contentType || parsedDataUri.contentType;
546
552
 
547
553
  if ('path' in element) {
548
554
  element.path = false;
@@ -552,12 +558,6 @@ class MailComposer {
552
558
  element.href = false;
553
559
  }
554
560
 
555
- parts[1].split(';').forEach(item => {
556
- if (/^\w+\/[^/]+$/i.test(item)) {
557
- element.contentType = element.contentType || item.toLowerCase();
558
- }
559
- });
560
-
561
561
  return element;
562
562
  }
563
563
  }
@@ -497,6 +497,15 @@ class MimeNode {
497
497
  if (!this.getHeader('MIME-Version')) {
498
498
  this.setHeader('MIME-Version', '1.0');
499
499
  }
500
+
501
+ // Ensure that Content-Type is the last header for the root node
502
+ for (let i = this._headers.length - 2; i >= 0; i--) {
503
+ let header = this._headers[i];
504
+ if (header.key === 'Content-Type') {
505
+ this._headers.splice(i, 1);
506
+ this._headers.push(header);
507
+ }
508
+ }
500
509
  }
501
510
 
502
511
  this._headers.forEach(header => {
@@ -418,6 +418,55 @@ module.exports.callbackPromise = (resolve, reject) =>
418
418
  }
419
419
  };
420
420
 
421
+ module.exports.parseDataURI = uri => {
422
+ let input = uri;
423
+ let commaPos = input.indexOf(',');
424
+ if (!commaPos) {
425
+ return uri;
426
+ }
427
+
428
+ let data = input.substring(commaPos + 1);
429
+ let metaStr = input.substring('data:'.length, commaPos);
430
+
431
+ let encoding;
432
+
433
+ let metaEntries = metaStr.split(';');
434
+ let lastMetaEntry = metaEntries.length > 1 ? metaEntries[metaEntries.length - 1] : false;
435
+ if (lastMetaEntry && lastMetaEntry.indexOf('=') < 0) {
436
+ encoding = lastMetaEntry.toLowerCase();
437
+ metaEntries.pop();
438
+ }
439
+
440
+ let contentType = metaEntries.shift() || 'application/octet-stream';
441
+ let params = {};
442
+ for (let entry of metaEntries) {
443
+ let sep = entry.indexOf('=');
444
+ if (sep >= 0) {
445
+ let key = entry.substring(0, sep);
446
+ let value = entry.substring(sep + 1);
447
+ params[key] = value;
448
+ }
449
+ }
450
+
451
+ switch (encoding) {
452
+ case 'base64':
453
+ data = Buffer.from(data, 'base64');
454
+ break;
455
+ case 'utf8':
456
+ data = Buffer.from(data);
457
+ break;
458
+ default:
459
+ try {
460
+ data = Buffer.from(decodeURIComponent(data));
461
+ } catch (err) {
462
+ data = Buffer.from(data);
463
+ }
464
+ data = Buffer.from(data);
465
+ }
466
+
467
+ return { data, encoding, contentType, params };
468
+ };
469
+
421
470
  /**
422
471
  * Resolves a String or a Buffer value for content value. Useful if the value
423
472
  * is a Stream or a file or an URL. If the value is a Stream, overwrites
@@ -470,11 +519,12 @@ module.exports.resolveContent = (data, key, callback) => {
470
519
  contentStream = nmfetch(content.path || content.href);
471
520
  return resolveStream(contentStream, callback);
472
521
  } else if (/^data:/i.test(content.path || content.href)) {
473
- let parts = (content.path || content.href).match(/^data:((?:[^;]*;)*(?:[^,]*)),(.*)$/i);
474
- if (!parts) {
522
+ let parsedDataUri = module.exports.parseDataURI(content.path || content.href);
523
+
524
+ if (!parsedDataUri || !parsedDataUri.data) {
475
525
  return callback(null, Buffer.from(0));
476
526
  }
477
- return callback(null, /\bbase64$/i.test(parts[1]) ? Buffer.from(parts[2], 'base64') : Buffer.from(decodeURIComponent(parts[2])));
527
+ return callback(null, parsedDataUri.data);
478
528
  } else if (content.path) {
479
529
  return resolveStream(fs.createReadStream(content.path), callback);
480
530
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodemailer",
3
- "version": "6.9.9",
3
+ "version": "6.9.11",
4
4
  "description": "Easy as cake e-mail sending from your Node.js applications",
5
5
  "main": "lib/nodemailer.js",
6
6
  "scripts": {
@@ -23,19 +23,19 @@
23
23
  },
24
24
  "homepage": "https://nodemailer.com/",
25
25
  "devDependencies": {
26
- "@aws-sdk/client-ses": "3.484.0",
26
+ "@aws-sdk/client-ses": "3.523.0",
27
27
  "bunyan": "1.8.15",
28
- "c8": "8.0.1",
29
- "eslint": "8.56.0",
28
+ "c8": "9.1.0",
29
+ "eslint": "8.57.0",
30
30
  "eslint-config-nodemailer": "1.2.0",
31
31
  "eslint-config-prettier": "9.1.0",
32
- "libbase64": "1.2.1",
33
- "libmime": "5.2.1",
34
- "libqp": "2.0.1",
32
+ "libbase64": "1.3.0",
33
+ "libmime": "5.3.4",
34
+ "libqp": "2.1.0",
35
35
  "nodemailer-ntlm-auth": "1.0.4",
36
36
  "proxy": "1.0.2",
37
37
  "proxy-test-server": "1.0.0",
38
- "smtp-server": "3.13.0"
38
+ "smtp-server": "3.13.2"
39
39
  },
40
40
  "engines": {
41
41
  "node": ">=6.0.0"