imapflow 1.0.128 → 1.0.130

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,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ - 1.0.129 - 2023-06-12
4
+
5
+ - Bumped deps for maintenance
6
+
3
7
  - 1.0.127 - 2023-04-10
4
8
 
5
9
  - Use default Node.js TLS settings
package/lib/imap-flow.js CHANGED
@@ -123,7 +123,7 @@ class ImapFlow extends EventEmitter {
123
123
  * @param {Boolean} [options.tls.rejectUnauthorized=true] if `false` then client accepts self-signed and expired certificates from the server
124
124
  * @param {String} [options.tls.minVersion=TLSv1.2] To improvde security you might need to use something newer, eg *'TLSv1.2'*
125
125
  * @param {Number} [options.tls.minDHSize=1024] Minimum size of the DH parameter in bits to accept a TLS connection
126
- * @param {Object} [options.logger] Custom logger instance with `debug(obj)`, `info(obj)`, `warn(obj)` and `error(obj)` methods. If not provided then ImapFlow logs to console using pino format
126
+ * @param {Object} [options.logger] Custom logger instance with `debug(obj)`, `info(obj)`, `warn(obj)` and `error(obj)` methods. If not provided then ImapFlow logs to console using pino format. Can be disabled by setting to `false`
127
127
  * @param {Boolean} [options.logRaw=false] If true then log data read from and written to socket encoded in base64
128
128
  * @param {Boolean} [options.emitLogs=false] If `true` then in addition of sending data to logger, ImapFlow emits 'log' events with the same data
129
129
  * @param {Boolean} [options.verifyOnly=false] If `true` then logs out automatically after successful authentication
package/lib/tools.js CHANGED
@@ -165,6 +165,10 @@ module.exports = {
165
165
  listed: !!folder.listed
166
166
  };
167
167
 
168
+ if (folder.delimiter) {
169
+ data.delimiter = folder.delimiter;
170
+ }
171
+
168
172
  if (folder.specialUse) {
169
173
  data.specialUse = folder.specialUse;
170
174
  }
@@ -420,13 +424,99 @@ module.exports = {
420
424
  return envelope;
421
425
  },
422
426
 
427
+ getStructuredParams(arr) {
428
+ let key;
429
+
430
+ let params = {};
431
+
432
+ [].concat(arr || []).forEach((val, j) => {
433
+ if (j % 2) {
434
+ params[key] = libmime.decodeWords(((val && val.value) || '').toString());
435
+ } else {
436
+ key = ((val && val.value) || '').toString().toLowerCase();
437
+ }
438
+ });
439
+
440
+ // preprocess values
441
+ Object.keys(params).forEach(key => {
442
+ let actualKey;
443
+ let nr;
444
+ let value;
445
+
446
+ let match = key.match(/\*((\d+)\*?)?$/);
447
+
448
+ if (!match) {
449
+ // nothing to do here, does not seem like a continuation param
450
+ return;
451
+ }
452
+
453
+ actualKey = key.substr(0, match.index).toLowerCase();
454
+ nr = Number(match[2]) || 0;
455
+
456
+ if (!params[actualKey] || typeof params[actualKey] !== 'object') {
457
+ params[actualKey] = {
458
+ charset: false,
459
+ values: []
460
+ };
461
+ }
462
+
463
+ value = params[key];
464
+
465
+ if (nr === 0 && match[0].charAt(match[0].length - 1) === '*' && (match = value.match(/^([^']*)'[^']*'(.*)$/))) {
466
+ params[actualKey].charset = match[1] || 'utf-8';
467
+ value = match[2];
468
+ }
469
+
470
+ params[actualKey].values.push({ nr, value });
471
+
472
+ // remove the old reference
473
+ delete params[key];
474
+ });
475
+
476
+ // concatenate split rfc2231 strings and convert encoded strings to mime encoded words
477
+ Object.keys(params).forEach(key => {
478
+ let value;
479
+ if (params[key] && Array.isArray(params[key].values)) {
480
+ value = params[key].values
481
+ .sort((a, b) => a.nr - b.nr)
482
+ .map(val => (val && val.value) || '')
483
+ .join('');
484
+
485
+ if (params[key].charset) {
486
+ // convert "%AB" to "=?charset?Q?=AB?=" and then to unicode
487
+ params[key] = libmime.decodeWords(
488
+ '=?' +
489
+ params[key].charset +
490
+ '?Q?' +
491
+ value
492
+ // fix invalidly encoded chars
493
+ .replace(/[=?_\s]/g, s => {
494
+ let c = s.charCodeAt(0).toString(16);
495
+ if (s === ' ') {
496
+ return '_';
497
+ } else {
498
+ return '%' + (c.length < 2 ? '0' : '') + c;
499
+ }
500
+ })
501
+ // change from urlencoding to percent encoding
502
+ .replace(/%/g, '=') +
503
+ '?='
504
+ );
505
+ } else {
506
+ params[key] = libmime.decodeWords(value);
507
+ }
508
+ }
509
+ });
510
+
511
+ return params;
512
+ },
513
+
423
514
  parseBodystructure(entry) {
424
515
  let walk = (node, path) => {
425
516
  path = path || [];
426
517
 
427
518
  let curNode = {},
428
519
  i = 0,
429
- key,
430
520
  part = 0;
431
521
 
432
522
  if (path.length) {
@@ -449,14 +539,7 @@ module.exports = {
449
539
  // body parameter parenthesized list
450
540
  if (i < node.length - 1) {
451
541
  if (node[i]) {
452
- curNode.parameters = {};
453
- [].concat(node[i] || []).forEach((val, j) => {
454
- if (j % 2) {
455
- curNode.parameters[key] = libmime.decodeWords(((val && val.value) || '').toString());
456
- } else {
457
- key = ((val && val.value) || '').toString().toLowerCase();
458
- }
459
- });
542
+ curNode.parameters = this.getStructuredParams(node[i]);
460
543
  }
461
544
  i++;
462
545
  }
@@ -466,14 +549,7 @@ module.exports = {
466
549
 
467
550
  // body parameter parenthesized list
468
551
  if (node[i]) {
469
- curNode.parameters = {};
470
- [].concat(node[i] || []).forEach((val, j) => {
471
- if (j % 2) {
472
- curNode.parameters[key] = libmime.decodeWords(((val && val.value) || '').toString());
473
- } else {
474
- key = ((val && val.value) || '').toString().toLowerCase();
475
- }
476
- });
552
+ curNode.parameters = this.getStructuredParams(node[i]);
477
553
  }
478
554
  i++;
479
555
 
@@ -554,14 +630,7 @@ module.exports = {
554
630
  if (Array.isArray(node[i]) && node[i].length) {
555
631
  curNode.disposition = ((node[i][0] || {}).value || '').toString().toLowerCase();
556
632
  if (Array.isArray(node[i][1])) {
557
- curNode.dispositionParameters = {};
558
- [].concat(node[i][1] || []).forEach((val, j) => {
559
- if (j % 2) {
560
- curNode.dispositionParameters[key] = libmime.decodeWords(((val && val.value) || '').toString());
561
- } else {
562
- key = ((val && val.value) || '').toString().toLowerCase();
563
- }
564
- });
633
+ curNode.dispositionParameters = this.getStructuredParams(node[i][1]);
565
634
  }
566
635
  }
567
636
  i++;
package/lib/types.d.ts CHANGED
@@ -22,7 +22,7 @@ declare module "imapflow" {
22
22
  * @param [options.tls.rejectUnauthorized = true] - if `false` then client accepts self-signed and expired certificates from the server
23
23
  * @param [options.tls.minVersion = TLSv1.2] - To improvde security you might need to use something newer, eg *'TLSv1.2'*
24
24
  * @param [options.tls.minDHSize = 1024] - Minimum size of the DH parameter in bits to accept a TLS connection
25
- * @param [options.logger] - Custom logger instance with `debug(obj)`, `info(obj)`, `warn(obj)` and `error(obj)` methods. If not provided then ImapFlow logs to console using pino format
25
+ * @param [options.logger] - Custom logger instance with `debug(obj)`, `info(obj)`, `warn(obj)` and `error(obj)` methods. If not provided then ImapFlow logs to console using pino format. Can be disabled by setting to `false`
26
26
  * @param [options.logRaw = false] - If true then log data read from and written to socket encoded in base64
27
27
  * @param [options.emitLogs = false] - If `true` then in addition of sending data to logger, ImapFlow emits 'log' events with the same data
28
28
  * @param [options.verifyOnly = false] - If `true` then logs out automatically after successful authentication
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "imapflow",
3
- "version": "1.0.128",
3
+ "version": "1.0.130",
4
4
  "description": "IMAP Client for Node",
5
5
  "main": "./lib/imap-flow.js",
6
6
  "scripts": {
@@ -27,19 +27,19 @@
27
27
  },
28
28
  "homepage": "https://imapflow.com/",
29
29
  "devDependencies": {
30
- "@babel/eslint-parser": "7.21.3",
31
- "@babel/eslint-plugin": "7.19.1",
30
+ "@babel/eslint-parser": "7.22.5",
31
+ "@babel/eslint-plugin": "7.22.5",
32
32
  "@babel/plugin-syntax-class-properties": "7.12.13",
33
- "@babel/preset-env": "7.21.4",
34
- "@types/node": "18.15.11",
33
+ "@babel/preset-env": "7.22.5",
34
+ "@types/node": "20.3.1",
35
35
  "braintree-jsdoc-template": "3.3.0",
36
- "eslint": "8.38.0",
36
+ "eslint": "8.42.0",
37
37
  "eslint-config-nodemailer": "1.2.0",
38
38
  "eslint-config-prettier": "8.8.0",
39
39
  "grunt": "1.6.1",
40
40
  "grunt-cli": "1.4.3",
41
41
  "grunt-contrib-nodeunit": "5.0.0",
42
- "grunt-eslint": "24.0.1",
42
+ "grunt-eslint": "24.1.0",
43
43
  "jsdoc": "3.6.11",
44
44
  "st": "3.0.0",
45
45
  "tsd-jsdoc": "2.5.0"
@@ -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.1",
55
- "pino": "8.11.0",
54
+ "nodemailer": "6.9.3",
55
+ "pino": "8.14.1",
56
56
  "socks": "2.7.1"
57
57
  }
58
58
  }