nodemailer 9.0.4 → 9.0.6
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 +23 -0
- package/README.md +2 -5
- package/lib/addressparser/index.js +140 -1
- package/lib/dkim/index.js +6 -1
- package/lib/dkim/sign.js +8 -3
- package/lib/fetch/index.js +115 -5
- package/lib/json-transport/index.js +1 -1
- package/lib/mail-composer/index.js +5 -3
- package/lib/mailer/mail-message.js +39 -34
- package/lib/mime-funcs/index.js +61 -13
- package/lib/mime-node/index.js +161 -41
- package/lib/punycode/index.js +1 -1
- package/lib/sendmail-transport/index.js +5 -2
- package/lib/ses-transport/index.js +4 -3
- package/lib/shared/index.js +27 -11
- package/lib/shared/objects.js +42 -0
- package/lib/stream-transport/index.js +1 -1
- package/package.json +6 -6
package/lib/shared/index.js
CHANGED
|
@@ -7,10 +7,15 @@ const util = require('util');
|
|
|
7
7
|
const fs = require('fs');
|
|
8
8
|
const nmfetch = require('../fetch');
|
|
9
9
|
const errors = require('../errors');
|
|
10
|
+
const objects = require('./objects');
|
|
10
11
|
const dns = require('dns');
|
|
11
12
|
const net = require('net');
|
|
12
13
|
const os = require('os');
|
|
13
14
|
|
|
15
|
+
// re-exported for the callers that already depend on this module, see ./objects
|
|
16
|
+
const isProtoKey = (module.exports.isProtoKey = objects.isProtoKey);
|
|
17
|
+
module.exports.copyOwnKeys = objects.copyOwnKeys;
|
|
18
|
+
|
|
14
19
|
const DNS_TTL = 5 * 60 * 1000;
|
|
15
20
|
const CACHE_CLEANUP_INTERVAL = 30 * 1000; // Minimum 30 seconds between cleanups
|
|
16
21
|
const MAX_CACHE_SIZE = 1000; // Maximum number of entries in cache
|
|
@@ -355,7 +360,9 @@ module.exports.parseConnectionUrl = str => {
|
|
|
355
360
|
return;
|
|
356
361
|
}
|
|
357
362
|
|
|
358
|
-
|
|
363
|
+
// `in` already keeps "__proto__" out, but only as a side effect of it being an
|
|
364
|
+
// Object.prototype member. Say it, so the protection survives a change to the check
|
|
365
|
+
if (!isProtoKey(lKey) && !(lKey in obj)) {
|
|
359
366
|
obj[lKey] = value;
|
|
360
367
|
}
|
|
361
368
|
});
|
|
@@ -470,7 +477,7 @@ module.exports.parseDataURI = uri => {
|
|
|
470
477
|
// Ensure there's a key before the '='
|
|
471
478
|
const key = entry.substring(0, sepPos).trim();
|
|
472
479
|
const value = entry.substring(sepPos + 1).trim();
|
|
473
|
-
if (key) {
|
|
480
|
+
if (key && !isProtoKey(key)) {
|
|
474
481
|
params[key] = value;
|
|
475
482
|
}
|
|
476
483
|
}
|
|
@@ -561,19 +568,24 @@ function resolveContentValue(data, key, options, callback) {
|
|
|
561
568
|
}
|
|
562
569
|
callback(null, value);
|
|
563
570
|
});
|
|
564
|
-
} else if (/^
|
|
571
|
+
} else if (/^data:/i.test(content.path || content.href)) {
|
|
572
|
+
const parsedDataUri = module.exports.parseDataURI(content.path || content.href);
|
|
573
|
+
|
|
574
|
+
return callback(null, parsedDataUri && parsedDataUri.data ? parsedDataUri.data : Buffer.alloc(0));
|
|
575
|
+
} else if (content.href || /^https?:\/\//i.test(content.path)) {
|
|
576
|
+
// An href is always a URL, and so is a path that looks like one. Let nmfetch
|
|
577
|
+
// decide whether it is fetchable, it validates the parsed URL. Testing the raw
|
|
578
|
+
// string here instead would let a file: href fall through to the "return as is"
|
|
579
|
+
// default below and travel on inside the resolved message.
|
|
580
|
+
const url = content.href || content.path;
|
|
565
581
|
if (options.disableUrlAccess) {
|
|
566
582
|
return setImmediate(() => {
|
|
567
|
-
const err = new Error('Url access rejected for ' +
|
|
583
|
+
const err = new Error('Url access rejected for ' + url);
|
|
568
584
|
err.code = errors.EURLACCESS;
|
|
569
585
|
callback(err);
|
|
570
586
|
});
|
|
571
587
|
}
|
|
572
|
-
return resolveStream(nmfetch(
|
|
573
|
-
} else if (/^data:/i.test(content.path || content.href)) {
|
|
574
|
-
const parsedDataUri = module.exports.parseDataURI(content.path || content.href);
|
|
575
|
-
|
|
576
|
-
return callback(null, parsedDataUri && parsedDataUri.data ? parsedDataUri.data : Buffer.alloc(0));
|
|
588
|
+
return resolveStream(nmfetch(url, { headers: content.httpHeaders, tls: content.tls }), callback);
|
|
577
589
|
} else if (content.path) {
|
|
578
590
|
if (options.disableFileAccess) {
|
|
579
591
|
return setImmediate(() => {
|
|
@@ -603,10 +615,14 @@ module.exports.assign = function (/* target, ... sources */) {
|
|
|
603
615
|
|
|
604
616
|
args.forEach(source => {
|
|
605
617
|
Object.keys(source || {}).forEach(key => {
|
|
618
|
+
if (isProtoKey(key)) {
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
606
621
|
if (['tls', 'auth'].includes(key) && source[key] && typeof source[key] === 'object') {
|
|
607
622
|
// tls and auth are special keys that need to be enumerated separately
|
|
608
|
-
// other objects are passed as is
|
|
609
|
-
|
|
623
|
+
// other objects are passed as is. Enumerating is a copy of user supplied
|
|
624
|
+
// keys just like the loop above, so it gets the same treatment
|
|
625
|
+
target[key] = module.exports.copyOwnKeys(target[key] || {}, source[key]);
|
|
610
626
|
} else {
|
|
611
627
|
target[key] = source[key];
|
|
612
628
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Safe copying of objects whose keys come from the caller.
|
|
4
|
+
//
|
|
5
|
+
// This lives in its own leaf module, like ./url.js, so that every layer can reach it.
|
|
6
|
+
// lib/shared/index.js requires lib/fetch, so lib/fetch can not require lib/shared back,
|
|
7
|
+
// and lib/mime-funcs is a leaf that would otherwise pull in dns/net/os/fs for a string
|
|
8
|
+
// comparison. lib/shared/index.js re-exports both functions for the callers that already
|
|
9
|
+
// depend on it.
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Detects a key that can not be copied onto a plain object with `target[key] = value`.
|
|
13
|
+
*
|
|
14
|
+
* "__proto__" is the only one: assigning it runs the inherited setter and replaces the
|
|
15
|
+
* prototype of the target instead of adding a property to it, so a caller can smuggle
|
|
16
|
+
* values past validation that only inspects own keys. JSON.parse produces such a key
|
|
17
|
+
* where an object literal can not. "constructor" and "prototype" have no such setter and
|
|
18
|
+
* become ordinary own properties, so dropping them would only discard legitimate values.
|
|
19
|
+
*
|
|
20
|
+
* @param {String} key Key to check
|
|
21
|
+
* @returns {Boolean} true if the key must not be copied
|
|
22
|
+
*/
|
|
23
|
+
module.exports.isProtoKey = key => key === '__proto__';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Copies own enumerable keys from a source object to a target object. Every copy that
|
|
27
|
+
* walks the keys of user supplied data goes through here, see isProtoKey.
|
|
28
|
+
*
|
|
29
|
+
* @param {Object} target Object to copy the keys to
|
|
30
|
+
* @param {Object} source Object to copy the keys from
|
|
31
|
+
* @param {Function} [skip] Optional predicate, return true to leave a key out
|
|
32
|
+
* @returns {Object} The target object
|
|
33
|
+
*/
|
|
34
|
+
module.exports.copyOwnKeys = (target, source, skip) => {
|
|
35
|
+
Object.keys(source || {}).forEach(key => {
|
|
36
|
+
if (module.exports.isProtoKey(key) || (skip && skip(key))) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
target[key] = source[key];
|
|
40
|
+
});
|
|
41
|
+
return target;
|
|
42
|
+
};
|
|
@@ -42,7 +42,7 @@ class StreamTransport {
|
|
|
42
42
|
// We probably need this in the output
|
|
43
43
|
mail.message.keepBcc = true;
|
|
44
44
|
|
|
45
|
-
const envelope = mail.
|
|
45
|
+
const envelope = mail.message.getEnvelope();
|
|
46
46
|
const messageId = mail.message.messageId();
|
|
47
47
|
|
|
48
48
|
const recipients = [].concat(envelope.to || []);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodemailer",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.6",
|
|
4
4
|
"description": "Easy as cake e-mail sending from your Node.js applications",
|
|
5
5
|
"main": "lib/nodemailer.js",
|
|
6
6
|
"scripts": {
|
|
@@ -27,19 +27,19 @@
|
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://nodemailer.com/",
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@aws-sdk/client-sesv2": "3.
|
|
30
|
+
"@aws-sdk/client-sesv2": "3.1119.0",
|
|
31
31
|
"bunyan": "1.8.15",
|
|
32
32
|
"c8": "12.0.0",
|
|
33
|
-
"eslint": "10.
|
|
33
|
+
"eslint": "10.9.1",
|
|
34
34
|
"eslint-config-prettier": "10.1.8",
|
|
35
|
-
"globals": "17.
|
|
35
|
+
"globals": "17.11.0",
|
|
36
36
|
"libbase64": "1.3.0",
|
|
37
|
-
"libmime": "5.4.
|
|
37
|
+
"libmime": "5.4.2",
|
|
38
38
|
"libqp": "2.1.1",
|
|
39
39
|
"prettier": "3.9.6",
|
|
40
40
|
"proxy": "1.0.2",
|
|
41
41
|
"proxy-test-server": "1.0.0",
|
|
42
|
-
"smtp-server": "3.19.
|
|
42
|
+
"smtp-server": "3.19.3"
|
|
43
43
|
},
|
|
44
44
|
"engines": {
|
|
45
45
|
"node": ">=6.0.0"
|