nodemailer 6.7.4 → 6.7.7

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,13 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 6.7.7 2022-07-06
4
+
5
+ - Resolver fixes
6
+
7
+ ## 6.7.5 2022-05-04
8
+
9
+ - No changes, pushing a new README to npmjs.org
10
+
3
11
  ## 6.7.4 2022-04-29
4
12
 
5
13
  - Ensure compatibility with Node 18
package/README.md CHANGED
@@ -8,9 +8,15 @@ Send emails from Node.js – easy as cake! 🍰✉️
8
8
 
9
9
  See [nodemailer.com](https://nodemailer.com/) for documentation and terms.
10
10
 
11
- ## Having an issue?
11
+ ---
12
+
13
+ > Check out **[EmailEngine](https://emailengine.app/?utm_source=github-nodemailer&utm_campaign=nodemailer&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.\
14
+ > \
15
+ > Using the email accounts registered with EmailEngine, you can receive and [send emails](https://emailengine.app/sending-emails?utm_source=github-nodemailer&utm_campaign=nodemailer&utm_medium=readme-link). EmailEngine supports OAuth2, delayed sends, opens and clicks tracking, bounce detection, etc. All on top of regular email accounts without an external MTA service.
12
16
 
13
- > Nodemailer supports all Node.js versions starting from Node.js@v6.0.0. The existing test suite does not support such old Node.js versions, so all features are not tested. From time to time, some regression bugs might occur because of this.
17
+ ---
18
+
19
+ ## Having an issue?
14
20
 
15
21
  #### First review the docs
16
22
 
@@ -18,7 +24,7 @@ Documentation for Nodemailer can be found at [nodemailer.com](https://nodemailer
18
24
 
19
25
  #### Nodemailer throws a SyntaxError for "..."
20
26
 
21
- You are using an older Node.js version than v6.0. Upgrade Node.js to get support for the spread operator.
27
+ You are using an older Node.js version than v6.0. Upgrade Node.js to get support for the spread operator. Nodemailer supports all Node.js versions starting from Node.js@v6.0.0.
22
28
 
23
29
  #### I'm having issues with Gmail
24
30
 
@@ -51,7 +51,7 @@ function wrap(str, lineLength) {
51
51
  *
52
52
  * @constructor
53
53
  * @param {Object} options Stream options
54
- * @param {Number} [options.lineLength=76] Maximum lenght for lines, set to false to disable wrapping
54
+ * @param {Number} [options.lineLength=76] Maximum length for lines, set to false to disable wrapping
55
55
  */
56
56
  class Encoder extends Transform {
57
57
  constructor(options) {
@@ -532,7 +532,7 @@ const mimeTypes = new Map([
532
532
  ['application/x-bittorrent', 'torrent'],
533
533
  ['application/x-bsh', ['bsh', 'sh', 'shar']],
534
534
  ['application/x-bytecode.elisp', 'elc'],
535
- ['applicaiton/x-bytecode.python', 'pyc'],
535
+ ['application/x-bytecode.python', 'pyc'],
536
536
  ['application/x-bzip', 'bz'],
537
537
  ['application/x-bzip2', ['boz', 'bz2']],
538
538
  ['application/x-cdf', 'cdf'],
@@ -1688,7 +1688,7 @@ const extensions = new Map([
1688
1688
  ['pwz', 'application/vnd.ms-powerpoint'],
1689
1689
  ['py', 'text/x-script.phyton'],
1690
1690
  ['pya', 'audio/vnd.ms-playready.media.pya'],
1691
- ['pyc', 'applicaiton/x-bytecode.python'],
1691
+ ['pyc', 'application/x-bytecode.python'],
1692
1692
  ['pyv', 'video/vnd.ms-playready.media.pyv'],
1693
1693
  ['qam', 'application/vnd.epson.quickanime'],
1694
1694
  ['qbo', 'application/vnd.intu.qbo'],
@@ -3,7 +3,6 @@
3
3
  'use strict';
4
4
 
5
5
  const crypto = require('crypto');
6
- const os = require('os');
7
6
  const fs = require('fs');
8
7
  const punycode = require('punycode');
9
8
  const PassThrough = require('stream').PassThrough;
@@ -1282,7 +1281,7 @@ class MimeNode {
1282
1281
  ) +
1283
1282
  '@' +
1284
1283
  // try to use the domain of the FROM address or fallback to server hostname
1285
- (this.getEnvelope().from || this.hostname || os.hostname() || 'localhost').split('@').pop() +
1284
+ (this.getEnvelope().from || this.hostname || 'localhost').split('@').pop() +
1286
1285
  '>'
1287
1286
  );
1288
1287
  }
@@ -12,23 +12,37 @@ const os = require('os');
12
12
 
13
13
  const DNS_TTL = 5 * 60 * 1000;
14
14
 
15
- const networkInterfaces = (module.exports.networkInterfaces = os.networkInterfaces());
15
+ let networkInterfaces;
16
+ try {
17
+ networkInterfaces = os.networkInterfaces();
18
+ } catch (err) {
19
+ // fails on some systems
20
+ }
21
+
22
+ module.exports.networkInterfaces = networkInterfaces;
23
+
24
+ const isFamilySupported = (family, allowInternal) => {
25
+ let networkInterfaces = module.exports.networkInterfaces;
26
+ if (!networkInterfaces) {
27
+ // hope for the best
28
+ return true;
29
+ }
16
30
 
17
- const isFamilySupported = family => {
18
31
  const familySupported =
19
32
  // crux that replaces Object.values(networkInterfaces) as Object.values is not supported in nodejs v6
20
33
  Object.keys(networkInterfaces)
21
34
  .map(key => networkInterfaces[key])
22
35
  // crux that replaces .flat() as it is not supported in older Node versions (v10 and older)
23
36
  .reduce((acc, val) => acc.concat(val), [])
24
- .filter(i => !i.internal)
37
+ .filter(i => !i.internal || allowInternal)
25
38
  .filter(i => i.family === 'IPv' + family || i.family === family).length > 0;
26
39
 
27
40
  return familySupported;
28
41
  };
29
42
 
30
- const resolver = (family, hostname, callback) => {
31
- const familySupported = isFamilySupported(family);
43
+ const resolver = (family, hostname, options, callback) => {
44
+ options = options || {};
45
+ const familySupported = isFamilySupported(family, options.allowInternalNetworkInterfaces);
32
46
 
33
47
  if (!familySupported) {
34
48
  return callback(null, []);
@@ -107,7 +121,7 @@ module.exports.resolveHostname = (options, callback) => {
107
121
  }
108
122
  }
109
123
 
110
- resolver(4, options.host, (err, addresses) => {
124
+ resolver(4, options.host, options, (err, addresses) => {
111
125
  if (err) {
112
126
  if (cached) {
113
127
  // ignore error, use expired value
@@ -141,7 +155,7 @@ module.exports.resolveHostname = (options, callback) => {
141
155
  );
142
156
  }
143
157
 
144
- resolver(6, options.host, (err, addresses) => {
158
+ resolver(6, options.host, options, (err, addresses) => {
145
159
  if (err) {
146
160
  if (cached) {
147
161
  // ignore error, use expired value
@@ -44,7 +44,7 @@ function httpProxyClient(proxyUrl, destinationPort, destinationHost, callback) {
44
44
  // Error harness for initial connection. Once connection is established, the responsibility
45
45
  // to handle errors is passed to whoever uses this socket
46
46
  let finished = false;
47
- let tempSocketErr = function (err) {
47
+ let tempSocketErr = err => {
48
48
  if (finished) {
49
49
  return;
50
50
  }
@@ -57,6 +57,12 @@ function httpProxyClient(proxyUrl, destinationPort, destinationHost, callback) {
57
57
  callback(err);
58
58
  };
59
59
 
60
+ let timeoutErr = () => {
61
+ let err = new Error('Proxy socket timed out');
62
+ err.code = 'ETIMEDOUT';
63
+ tempSocketErr(err);
64
+ };
65
+
60
66
  socket = connect(options, () => {
61
67
  if (finished) {
62
68
  return;
@@ -119,12 +125,18 @@ function httpProxyClient(proxyUrl, destinationPort, destinationHost, callback) {
119
125
  }
120
126
 
121
127
  socket.removeListener('error', tempSocketErr);
128
+ socket.removeListener('timeout', timeoutErr);
129
+ socket.setTimeout(0);
130
+
122
131
  return callback(null, socket);
123
132
  }
124
133
  };
125
134
  socket.on('data', onSocketData);
126
135
  });
127
136
 
137
+ socket.setTimeout(httpProxyClient.timeout || 30 * 1000);
138
+ socket.on('timeout', timeoutErr);
139
+
128
140
  socket.once('error', tempSocketErr);
129
141
  }
130
142
 
@@ -56,6 +56,8 @@ class SMTPConnection extends EventEmitter {
56
56
  this.port = Number(this.options.port) || (this.secureConnection ? 465 : 587);
57
57
  this.host = this.options.host || 'localhost';
58
58
 
59
+ this.allowInternalNetworkInterfaces = this.options.allowInternalNetworkInterfaces || false;
60
+
59
61
  if (typeof this.options.secure === 'undefined' && this.port === 465) {
60
62
  // if secure option is not set but port is 465, then default to secure
61
63
  this.secureConnection = true;
@@ -217,7 +219,8 @@ class SMTPConnection extends EventEmitter {
217
219
 
218
220
  let opts = {
219
221
  port: this.port,
220
- host: this.host
222
+ host: this.host,
223
+ allowInternalNetworkInterfaces: this.allowInternalNetworkInterfaces
221
224
  };
222
225
 
223
226
  if (this.options.localAddress) {
@@ -1755,10 +1758,16 @@ class SMTPConnection extends EventEmitter {
1755
1758
 
1756
1759
  _getHostname() {
1757
1760
  // defaul hostname is machine hostname or [IP]
1758
- let defaultHostname = os.hostname() || '';
1761
+ let defaultHostname;
1762
+ try {
1763
+ defaultHostname = os.hostname() || '';
1764
+ } catch (err) {
1765
+ // fails on windows 7
1766
+ defaultHostname = 'localhost';
1767
+ }
1759
1768
 
1760
1769
  // ignore if not FQDN
1761
- if (defaultHostname.indexOf('.') < 0) {
1770
+ if (!defaultHostname || defaultHostname.indexOf('.') < 0) {
1762
1771
  defaultHostname = '[127.0.0.1]';
1763
1772
  }
1764
1773
 
@@ -627,6 +627,13 @@ class SMTPPool extends EventEmitter {
627
627
 
628
628
  finalize();
629
629
  });
630
+ } else if (!auth && connection.allowsAuth && options.forceAuth) {
631
+ let err = new Error('Authentication info was not provided');
632
+ err.code = 'NoAuth';
633
+
634
+ returned = true;
635
+ connection.close();
636
+ return callback(err);
630
637
  } else {
631
638
  finalize();
632
639
  }
@@ -18,6 +18,7 @@ class SMTPTransport extends EventEmitter {
18
18
  super();
19
19
 
20
20
  options = options || {};
21
+
21
22
  if (typeof options === 'string') {
22
23
  options = {
23
24
  url: options
@@ -384,6 +385,13 @@ class SMTPTransport extends EventEmitter {
384
385
 
385
386
  finalize();
386
387
  });
388
+ } else if (!authData && connection.allowsAuth && options.forceAuth) {
389
+ let err = new Error('Authentication info was not provided');
390
+ err.code = 'NoAuth';
391
+
392
+ returned = true;
393
+ connection.close();
394
+ return callback(err);
387
395
  } else {
388
396
  finalize();
389
397
  }
@@ -11,6 +11,12 @@
11
11
  "host": "smtp.aol.com",
12
12
  "port": 587
13
13
  },
14
+
15
+ "Bluewin": {
16
+ "host": "smtpauths.bluewin.ch",
17
+ "domains": ["bluewin.ch"],
18
+ "port": 465
19
+ },
14
20
 
15
21
  "DebugMail": {
16
22
  "host": "debugmail.io",
@@ -188,8 +194,8 @@
188
194
  },
189
195
 
190
196
  "SendCloud": {
191
- "host": "smtpcloud.sohu.com",
192
- "port": 25
197
+ "host": "smtp.sendcloud.net",
198
+ "port": 2525
193
199
  },
194
200
 
195
201
  "SendGrid": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodemailer",
3
- "version": "6.7.4",
3
+ "version": "6.7.7",
4
4
  "description": "Easy as cake e-mail sending from your Node.js applications",
5
5
  "main": "lib/nodemailer.js",
6
6
  "scripts": {
@@ -20,24 +20,24 @@
20
20
  },
21
21
  "homepage": "https://nodemailer.com/",
22
22
  "devDependencies": {
23
- "@aws-sdk/client-ses": "3.79.0",
24
- "aws-sdk": "2.1124.0",
23
+ "@aws-sdk/client-ses": "3.121.0",
24
+ "aws-sdk": "2.1168.0",
25
25
  "bunyan": "1.8.15",
26
26
  "chai": "4.3.6",
27
27
  "eslint-config-nodemailer": "1.2.0",
28
28
  "eslint-config-prettier": "8.5.0",
29
- "grunt": "1.5.2",
29
+ "grunt": "1.5.3",
30
30
  "grunt-cli": "1.4.3",
31
31
  "grunt-eslint": "24.0.0",
32
32
  "grunt-mocha-test": "0.13.3",
33
33
  "libbase64": "1.2.1",
34
34
  "libmime": "5.1.0",
35
35
  "libqp": "1.1.0",
36
- "mocha": "9.2.2",
36
+ "mocha": "10.0.0",
37
37
  "nodemailer-ntlm-auth": "1.0.1",
38
38
  "proxy": "1.0.2",
39
39
  "proxy-test-server": "1.0.0",
40
- "sinon": "13.0.2",
40
+ "sinon": "14.0.0",
41
41
  "smtp-server": "3.11.0"
42
42
  },
43
43
  "engines": {