nodemailer 6.9.8 → 6.9.10
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/.ncurc.js +1 -3
- package/CHANGELOG.md +16 -0
- package/lib/mail-composer/index.js +9 -9
- package/lib/mailer/index.js +16 -14
- package/lib/shared/index.js +53 -3
- package/package.json +6 -9
package/.ncurc.js
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## [6.9.10](https://github.com/nodemailer/nodemailer/compare/v6.9.9...v6.9.10) (2024-02-22)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **data-uri:** Do not use regular expressions for parsing data URI schemes ([12e65e9](https://github.com/nodemailer/nodemailer/commit/12e65e975d80efe6bafe6de4590829b3b5ebb492))
|
|
9
|
+
* **data-uri:** Moved all data-uri regexes to use the non-regex parseDataUri method ([edd5dfe](https://github.com/nodemailer/nodemailer/commit/edd5dfe5ce9b725f8b8ae2830797f65b2a2b0a33))
|
|
10
|
+
|
|
11
|
+
## [6.9.9](https://github.com/nodemailer/nodemailer/compare/v6.9.8...v6.9.9) (2024-02-01)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* **security:** Fix issues described in GHSA-9h6g-pr28-7cqp. Do not use eternal matching pattern if only a few occurences are expected ([dd8f5e8](https://github.com/nodemailer/nodemailer/commit/dd8f5e8a4ddc99992e31df76bcff9c590035cd4a))
|
|
17
|
+
* **tests:** Use native node test runner, added code coverage support, removed grunt ([#1604](https://github.com/nodemailer/nodemailer/issues/1604)) ([be45c1b](https://github.com/nodemailer/nodemailer/commit/be45c1b299d012358d69247019391a02734d70af))
|
|
18
|
+
|
|
3
19
|
## [6.9.8](https://github.com/nodemailer/nodemailer/compare/v6.9.7...v6.9.8) (2023-12-30)
|
|
4
20
|
|
|
5
21
|
|
|
@@ -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
|
|
541
|
-
if (
|
|
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 =
|
|
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
|
}
|
package/lib/mailer/index.js
CHANGED
|
@@ -395,21 +395,23 @@ class Mail extends EventEmitter {
|
|
|
395
395
|
return callback(err);
|
|
396
396
|
}
|
|
397
397
|
let cidCounter = 0;
|
|
398
|
-
html = (html || '')
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
398
|
+
html = (html || '')
|
|
399
|
+
.toString()
|
|
400
|
+
.replace(/(<img\b[^<>]{0,1024} src\s{0,20}=[\s"']{0,20})(data:([^;]+);[^"'>\s]+)/gi, (match, prefix, dataUri, mimeType) => {
|
|
401
|
+
let cid = crypto.randomBytes(10).toString('hex') + '@localhost';
|
|
402
|
+
if (!mail.data.attachments) {
|
|
403
|
+
mail.data.attachments = [];
|
|
404
|
+
}
|
|
405
|
+
if (!Array.isArray(mail.data.attachments)) {
|
|
406
|
+
mail.data.attachments = [].concat(mail.data.attachments || []);
|
|
407
|
+
}
|
|
408
|
+
mail.data.attachments.push({
|
|
409
|
+
path: dataUri,
|
|
410
|
+
cid,
|
|
411
|
+
filename: 'image-' + ++cidCounter + '.' + mimeTypes.detectExtension(mimeType)
|
|
412
|
+
});
|
|
413
|
+
return prefix + 'cid:' + cid;
|
|
410
414
|
});
|
|
411
|
-
return prefix + 'cid:' + cid;
|
|
412
|
-
});
|
|
413
415
|
mail.data.html = html;
|
|
414
416
|
callback();
|
|
415
417
|
});
|
package/lib/shared/index.js
CHANGED
|
@@ -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
|
|
474
|
-
|
|
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,
|
|
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,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodemailer",
|
|
3
|
-
"version": "6.9.
|
|
3
|
+
"version": "6.9.10",
|
|
4
4
|
"description": "Easy as cake e-mail sending from your Node.js applications",
|
|
5
5
|
"main": "lib/nodemailer.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "
|
|
7
|
+
"test": "node --test --test-concurrency=1 test/**/*.test.js test/**/*-test.js",
|
|
8
|
+
"test:coverage": "c8 node --test --test-concurrency=1 test/**/*.test.js test/**/*-test.js",
|
|
9
|
+
"lint": "eslint .",
|
|
8
10
|
"update": "rm -rf node_modules/ package-lock.json && ncu -u && npm install"
|
|
9
11
|
},
|
|
10
12
|
"repository": {
|
|
@@ -23,21 +25,16 @@
|
|
|
23
25
|
"devDependencies": {
|
|
24
26
|
"@aws-sdk/client-ses": "3.484.0",
|
|
25
27
|
"bunyan": "1.8.15",
|
|
26
|
-
"
|
|
28
|
+
"c8": "8.0.1",
|
|
29
|
+
"eslint": "8.56.0",
|
|
27
30
|
"eslint-config-nodemailer": "1.2.0",
|
|
28
31
|
"eslint-config-prettier": "9.1.0",
|
|
29
|
-
"grunt": "1.6.1",
|
|
30
|
-
"grunt-cli": "1.4.3",
|
|
31
|
-
"grunt-eslint": "24.3.0",
|
|
32
|
-
"grunt-mocha-test": "0.13.3",
|
|
33
32
|
"libbase64": "1.2.1",
|
|
34
33
|
"libmime": "5.2.1",
|
|
35
34
|
"libqp": "2.0.1",
|
|
36
|
-
"mocha": "10.2.0",
|
|
37
35
|
"nodemailer-ntlm-auth": "1.0.4",
|
|
38
36
|
"proxy": "1.0.2",
|
|
39
37
|
"proxy-test-server": "1.0.0",
|
|
40
|
-
"sinon": "17.0.1",
|
|
41
38
|
"smtp-server": "3.13.0"
|
|
42
39
|
},
|
|
43
40
|
"engines": {
|