imapflow 1.0.143 → 1.0.145
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 +15 -0
- package/lib/commands/list.js +5 -1
- package/lib/imap-flow.js +22 -1
- package/lib/special-use.js +9 -3
- package/lib/types.d.ts +2 -2
- package/package.json +9 -8
- package/test/imap-parser-test.js +7 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.145](https://github.com/postalsys/imapflow/compare/v1.0.144...v1.0.145) (2023-10-26)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **docs:** Fixed mailbox property name in AppendResponseObject ([ca6d789](https://github.com/postalsys/imapflow/commit/ca6d789b761d3117f733ed7b026122098f4d9142))
|
|
9
|
+
* **special-use:** support custom special use flags for the Archive folder ([17aa6a8](https://github.com/postalsys/imapflow/commit/17aa6a8baf180a7349fe30f897184eb8e359a498))
|
|
10
|
+
|
|
11
|
+
## [1.0.144](https://github.com/postalsys/imapflow/compare/v1.0.143...v1.0.144) (2023-09-13)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* **MS365:** Wait until responding with a throttling response ([#142](https://github.com/postalsys/imapflow/issues/142)) ([09bfb3e](https://github.com/postalsys/imapflow/commit/09bfb3e1b90bdd37bc1c9b40e9284ad4afbd5c72))
|
|
17
|
+
|
|
3
18
|
## [1.0.143](https://github.com/postalsys/imapflow/compare/v1.0.142...v1.0.143) (2023-09-04)
|
|
4
19
|
|
|
5
20
|
|
package/lib/commands/list.js
CHANGED
|
@@ -62,7 +62,11 @@ module.exports = async (connection, reference, mailbox, options) => {
|
|
|
62
62
|
let specialUseHints = {};
|
|
63
63
|
if (options.specialUseHints && typeof options.specialUseHints === 'object') {
|
|
64
64
|
for (let type of Object.keys(options.specialUseHints)) {
|
|
65
|
-
if (
|
|
65
|
+
if (
|
|
66
|
+
['sent', 'junk', 'trash', 'drafts', 'archive'].includes(type) &&
|
|
67
|
+
options.specialUseHints[type] &&
|
|
68
|
+
typeof options.specialUseHints[type] === 'string'
|
|
69
|
+
) {
|
|
66
70
|
specialUseHints[normalizePath(connection, options.specialUseHints[type])] = `\\${type.replace(/^./, c => c.toUpperCase())}`;
|
|
67
71
|
}
|
|
68
72
|
}
|
package/lib/imap-flow.js
CHANGED
|
@@ -561,7 +561,28 @@ class ImapFlow extends EventEmitter {
|
|
|
561
561
|
err.responseStatus = parsed.command.toUpperCase();
|
|
562
562
|
if (txt) {
|
|
563
563
|
err.responseText = txt;
|
|
564
|
+
|
|
565
|
+
// MS365 throttling
|
|
566
|
+
// tag BAD Request is throttled. Suggested Backoff Time: 92415 milliseconds
|
|
567
|
+
if (/Request is throttled/i.test(txt) && /Backoff Time/i.test(txt)) {
|
|
568
|
+
let throttlingMatch = txt.match(/Backoff Time[:=\s]+(\d+)/i);
|
|
569
|
+
if (throttlingMatch && throttlingMatch[1] && !isNaN(throttlingMatch[1])) {
|
|
570
|
+
err.code = 'ETHROTTLE';
|
|
571
|
+
err.throttleReset = Number(throttlingMatch[1]);
|
|
572
|
+
|
|
573
|
+
let delayResponse = err.throttleReset;
|
|
574
|
+
if (delayResponse > 5 * 60 * 1000) {
|
|
575
|
+
// max delay cap
|
|
576
|
+
delayResponse = 5 * 60 * 1000;
|
|
577
|
+
}
|
|
578
|
+
if (delayResponse) {
|
|
579
|
+
this.log.warn({ msg: 'Throttling detected', err, cid: this.id, delayResponse });
|
|
580
|
+
await new Promise(r => setTimeout(r, delayResponse));
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
564
584
|
}
|
|
585
|
+
|
|
565
586
|
request.reject(err);
|
|
566
587
|
break;
|
|
567
588
|
}
|
|
@@ -1918,7 +1939,7 @@ class ImapFlow extends EventEmitter {
|
|
|
1918
1939
|
/**
|
|
1919
1940
|
* @typedef {Object} AppendResponseObject
|
|
1920
1941
|
* @global
|
|
1921
|
-
* @property {String}
|
|
1942
|
+
* @property {String} destination full mailbox path where the message was uploaded to
|
|
1922
1943
|
* @property {BigInt} [uidValidity] mailbox `UIDVALIDITY` if server has `UIDPLUS` extension enabled
|
|
1923
1944
|
* @property {Number} [uid] UID of the uploaded message if server has `UIDPLUS` extension enabled
|
|
1924
1945
|
* @property {Number} [seq] sequence number of the uploaded message if path is currently selected mailbox
|
package/lib/special-use.js
CHANGED
|
@@ -182,7 +182,7 @@ module.exports = {
|
|
|
182
182
|
'الرسائل العشوائية',
|
|
183
183
|
'هرزنامه',
|
|
184
184
|
'สแปม',
|
|
185
|
-
'
|
|
185
|
+
'垃圾郵件',
|
|
186
186
|
'垃圾邮件',
|
|
187
187
|
'垃圾電郵'
|
|
188
188
|
],
|
|
@@ -275,7 +275,9 @@ module.exports = {
|
|
|
275
275
|
'草稿',
|
|
276
276
|
'草稿',
|
|
277
277
|
'임시 보관함'
|
|
278
|
-
]
|
|
278
|
+
],
|
|
279
|
+
|
|
280
|
+
'\\Archive': ['archive']
|
|
279
281
|
},
|
|
280
282
|
|
|
281
283
|
specialUse(hasSpecialUseExtension, folder) {
|
|
@@ -289,7 +291,11 @@ module.exports = {
|
|
|
289
291
|
}
|
|
290
292
|
|
|
291
293
|
if (!result || !result.flag) {
|
|
292
|
-
let name = folder.name
|
|
294
|
+
let name = folder.name
|
|
295
|
+
.toLowerCase()
|
|
296
|
+
.replace(/\u200e/g, '')
|
|
297
|
+
.trim();
|
|
298
|
+
|
|
293
299
|
result = {
|
|
294
300
|
flag: Object.keys(module.exports.names).find(flag => module.exports.names[flag].includes(name)),
|
|
295
301
|
source: 'name'
|
package/lib/types.d.ts
CHANGED
|
@@ -805,13 +805,13 @@ declare type SearchObject = {
|
|
|
805
805
|
};
|
|
806
806
|
|
|
807
807
|
/**
|
|
808
|
-
* @property
|
|
808
|
+
* @property destination - full mailbox path where the message was uploaded to
|
|
809
809
|
* @property [uidValidity] - mailbox `UIDVALIDITY` if server has `UIDPLUS` extension enabled
|
|
810
810
|
* @property [uid] - UID of the uploaded message if server has `UIDPLUS` extension enabled
|
|
811
811
|
* @property [seq] - sequence number of the uploaded message if path is currently selected mailbox
|
|
812
812
|
*/
|
|
813
813
|
declare type AppendResponseObject = {
|
|
814
|
-
|
|
814
|
+
destination: string;
|
|
815
815
|
uidValidity?: bigint;
|
|
816
816
|
uid?: number;
|
|
817
817
|
seq?: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "imapflow",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.145",
|
|
4
4
|
"description": "IMAP Client for Node",
|
|
5
5
|
"main": "./lib/imap-flow.js",
|
|
6
6
|
"scripts": {
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"docs": "rm -rf docs && mkdir -p docs && jsdoc lib/imap-flow.js -c jsdoc.json -R README.md --destination docs/ && cp assets/favicon.ico docs",
|
|
10
10
|
"dst": "node types.js",
|
|
11
11
|
"build": "npm run docs && npm run dst",
|
|
12
|
-
"st": "npm run docs && st -d docs -i index.html"
|
|
12
|
+
"st": "npm run docs && st -d docs -i index.html",
|
|
13
|
+
"update": "rm -rf node_modules package-lock.json && ncu -u && npm install"
|
|
13
14
|
},
|
|
14
15
|
"repository": {
|
|
15
16
|
"type": "git",
|
|
@@ -27,13 +28,13 @@
|
|
|
27
28
|
},
|
|
28
29
|
"homepage": "https://imapflow.com/",
|
|
29
30
|
"devDependencies": {
|
|
30
|
-
"@babel/eslint-parser": "7.22.
|
|
31
|
+
"@babel/eslint-parser": "7.22.15",
|
|
31
32
|
"@babel/eslint-plugin": "7.22.10",
|
|
32
33
|
"@babel/plugin-syntax-class-properties": "7.12.13",
|
|
33
|
-
"@babel/preset-env": "7.
|
|
34
|
-
"@types/node": "20.
|
|
34
|
+
"@babel/preset-env": "7.23.2",
|
|
35
|
+
"@types/node": "20.8.9",
|
|
35
36
|
"braintree-jsdoc-template": "3.3.0",
|
|
36
|
-
"eslint": "8.
|
|
37
|
+
"eslint": "8.52.0",
|
|
37
38
|
"eslint-config-nodemailer": "1.2.0",
|
|
38
39
|
"eslint-config-prettier": "9.0.0",
|
|
39
40
|
"grunt": "1.6.1",
|
|
@@ -51,8 +52,8 @@
|
|
|
51
52
|
"libmime": "5.2.1",
|
|
52
53
|
"libqp": "2.0.1",
|
|
53
54
|
"mailsplit": "5.4.0",
|
|
54
|
-
"nodemailer": "6.9.
|
|
55
|
-
"pino": "8.
|
|
55
|
+
"nodemailer": "6.9.7",
|
|
56
|
+
"pino": "8.16.1",
|
|
56
57
|
"socks": "2.7.1"
|
|
57
58
|
}
|
|
58
59
|
}
|
package/test/imap-parser-test.js
CHANGED
|
@@ -977,3 +977,10 @@ module.exports['IMAP Parser, NO with a dot'] = test =>
|
|
|
977
977
|
test.equal(parsed.command, 'NO');
|
|
978
978
|
test.deepEqual(parsed.attributes, [{ type: 'TEXT', value: 'Server Unavailable. 15' }]);
|
|
979
979
|
});
|
|
980
|
+
|
|
981
|
+
module.exports['IMAP Parser, BAD with throttling'] = test =>
|
|
982
|
+
asyncWrapper(test, async test => {
|
|
983
|
+
let parsed = await parser('X BAD Request is throttled. Suggested Backoff Time: 92415 milliseconds');
|
|
984
|
+
test.equal(parsed.command, 'BAD');
|
|
985
|
+
test.deepEqual(parsed.attributes, [{ type: 'TEXT', value: 'Request is throttled. Suggested Backoff Time: 92415 milliseconds' }]);
|
|
986
|
+
});
|