imapflow 1.0.143 → 1.0.144

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,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.0.144](https://github.com/postalsys/imapflow/compare/v1.0.143...v1.0.144) (2023-09-13)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **MS365:** Wait until responding with a throttling response ([#142](https://github.com/postalsys/imapflow/issues/142)) ([09bfb3e](https://github.com/postalsys/imapflow/commit/09bfb3e1b90bdd37bc1c9b40e9284ad4afbd5c72))
9
+
3
10
  ## [1.0.143](https://github.com/postalsys/imapflow/compare/v1.0.142...v1.0.143) (2023-09-04)
4
11
 
5
12
 
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "imapflow",
3
- "version": "1.0.143",
3
+ "version": "1.0.144",
4
4
  "description": "IMAP Client for Node",
5
5
  "main": "./lib/imap-flow.js",
6
6
  "scripts": {
@@ -27,13 +27,13 @@
27
27
  },
28
28
  "homepage": "https://imapflow.com/",
29
29
  "devDependencies": {
30
- "@babel/eslint-parser": "7.22.11",
30
+ "@babel/eslint-parser": "7.22.15",
31
31
  "@babel/eslint-plugin": "7.22.10",
32
32
  "@babel/plugin-syntax-class-properties": "7.12.13",
33
- "@babel/preset-env": "7.22.14",
34
- "@types/node": "20.5.9",
33
+ "@babel/preset-env": "7.22.15",
34
+ "@types/node": "20.6.0",
35
35
  "braintree-jsdoc-template": "3.3.0",
36
- "eslint": "8.48.0",
36
+ "eslint": "8.49.0",
37
37
  "eslint-config-nodemailer": "1.2.0",
38
38
  "eslint-config-prettier": "9.0.0",
39
39
  "grunt": "1.6.1",
@@ -51,8 +51,8 @@
51
51
  "libmime": "5.2.1",
52
52
  "libqp": "2.0.1",
53
53
  "mailsplit": "5.4.0",
54
- "nodemailer": "6.9.4",
55
- "pino": "8.15.0",
54
+ "nodemailer": "6.9.5",
55
+ "pino": "8.15.1",
56
56
  "socks": "2.7.1"
57
57
  }
58
58
  }
@@ -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
+ });