nodemailer 8.0.5 → 8.0.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,19 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## [8.0.7](https://github.com/nodemailer/nodemailer/compare/v8.0.6...v8.0.7) (2026-04-27)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * keep domain as UTF-8 when local part is non-ASCII ([#1814](https://github.com/nodemailer/nodemailer/issues/1814)) ([66d4ecb](https://github.com/nodemailer/nodemailer/commit/66d4ecb5aa431f3614a26b3c08b9c63cdf32a9ea))
9
+
10
+ ## [8.0.6](https://github.com/nodemailer/nodemailer/compare/v8.0.5...v8.0.6) (2026-04-24)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * restore base64 wrap() trim behavior to prevent trailing CRLF ([#1810](https://github.com/nodemailer/nodemailer/issues/1810)) ([#1811](https://github.com/nodemailer/nodemailer/issues/1811)) ([b1ae6c1](https://github.com/nodemailer/nodemailer/commit/b1ae6c1c2927240737d9f68f316f0c84042b8adb))
16
+
3
17
  ## [8.0.5](https://github.com/nodemailer/nodemailer/compare/v8.0.4...v8.0.5) (2026-04-07)
4
18
 
5
19
 
@@ -36,12 +36,12 @@ function wrap(str, lineLength) {
36
36
  const chunkLength = lineLength * 1024;
37
37
  const wrapRegex = new RegExp('.{' + lineLength + '}', 'g');
38
38
  while (pos < str.length) {
39
- const wrappedLines = str.substr(pos, chunkLength).replace(wrapRegex, '$&\r\n');
39
+ const wrappedLines = str.substr(pos, chunkLength).replace(wrapRegex, '$&\r\n').trim();
40
40
  result.push(wrappedLines);
41
41
  pos += chunkLength;
42
42
  }
43
43
 
44
- return result.join('');
44
+ return result.join('\r\n').trim();
45
45
  }
46
46
 
47
47
  /**
@@ -95,20 +95,17 @@ class Encoder extends Transform {
95
95
  if (this.options.lineLength) {
96
96
  b64 = wrap(b64, this.options.lineLength);
97
97
 
98
+ // remove last line as it is still most probably incomplete
98
99
  const lastLF = b64.lastIndexOf('\n');
99
100
  if (lastLF < 0) {
100
101
  this._curLine = b64;
101
102
  b64 = '';
103
+ } else if (lastLF === b64.length - 1) {
104
+ this._curLine = '';
102
105
  } else {
103
106
  this._curLine = b64.substring(lastLF + 1);
104
107
  b64 = b64.substring(0, lastLF + 1);
105
-
106
- if (b64 && !b64.endsWith('\r\n')) {
107
- b64 += '\r\n';
108
- }
109
108
  }
110
- } else {
111
- this._curLine = '';
112
109
  }
113
110
 
114
111
  if (b64) {
@@ -125,6 +122,7 @@ class Encoder extends Transform {
125
122
  }
126
123
 
127
124
  if (this._curLine) {
125
+ this._curLine = wrap(this._curLine, this.options.lineLength);
128
126
  this.outputBytes += this._curLine.length;
129
127
  this.push(Buffer.from(this._curLine, 'ascii'));
130
128
  this._curLine = '';
@@ -1225,17 +1225,21 @@ class MimeNode {
1225
1225
  let user = address.substr(0, lastAt);
1226
1226
  const domain = address.substr(lastAt + 1);
1227
1227
 
1228
- // Usernames are not touched and are kept as is even if these include unicode
1229
- // Domains are punycoded by default
1230
- // 'jõgeva.ee' will be converted to 'xn--jgeva-dua.ee'
1231
- // non-unicode domains are left as is
1228
+ // Usernames are not touched and are kept as is even if these include unicode.
1229
+ // Domains are punycoded when the local part is ASCII ('safe@jõgeva.ee' -> 'safe@xn--jgeva-dua.ee').
1230
+ // When the local part contains non-ASCII bytes the address already requires SMTPUTF8,
1231
+ // so the domain is kept (or decoded back) as UTF-8 for symmetry on both sides of '@'.
1232
1232
 
1233
- let encodedDomain;
1233
+ let encodedDomain = domain;
1234
1234
 
1235
1235
  try {
1236
- encodedDomain = punycode.toASCII(domain.toLowerCase());
1236
+ if (/[\x80-\uFFFF]/.test(user)) {
1237
+ encodedDomain = punycode.toUnicode(domain.toLowerCase());
1238
+ } else {
1239
+ encodedDomain = punycode.toASCII(domain.toLowerCase());
1240
+ }
1237
1241
  } catch (_err) {
1238
- // keep as is?
1242
+ // keep domain as supplied
1239
1243
  }
1240
1244
 
1241
1245
  if (user.indexOf(' ') >= 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodemailer",
3
- "version": "8.0.5",
3
+ "version": "8.0.7",
4
4
  "description": "Easy as cake e-mail sending from your Node.js applications",
5
5
  "main": "lib/nodemailer.js",
6
6
  "scripts": {
@@ -27,20 +27,19 @@
27
27
  },
28
28
  "homepage": "https://nodemailer.com/",
29
29
  "devDependencies": {
30
- "@aws-sdk/client-sesv2": "3.1025.0",
30
+ "@aws-sdk/client-sesv2": "3.1037.0",
31
31
  "bunyan": "1.8.15",
32
32
  "c8": "11.0.0",
33
- "eslint": "10.2.0",
33
+ "eslint": "10.2.1",
34
34
  "eslint-config-prettier": "10.1.8",
35
- "globals": "17.4.0",
35
+ "globals": "17.5.0",
36
36
  "libbase64": "1.3.0",
37
- "libmime": "5.3.7",
37
+ "libmime": "5.3.8",
38
38
  "libqp": "2.1.1",
39
- "nodemailer-ntlm-auth": "1.0.4",
40
- "prettier": "3.8.1",
39
+ "prettier": "3.8.3",
41
40
  "proxy": "1.0.2",
42
41
  "proxy-test-server": "1.0.0",
43
- "smtp-server": "3.18.3"
42
+ "smtp-server": "3.18.4"
44
43
  },
45
44
  "engines": {
46
45
  "node": ">=6.0.0"