imapflow 1.0.103 → 1.0.106
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/lib/handler/parser-instance.js +22 -9
- package/lib/handler/token-parser.js +8 -2
- package/lib/imap-flow.js +27 -3
- package/lib/types.d.ts +3 -1
- package/package.json +3 -3
- package/test/imap-parser-test.js +13 -5
|
@@ -22,8 +22,6 @@ class ParserInstance {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
async getCommand() {
|
|
25
|
-
let responseCode;
|
|
26
|
-
|
|
27
25
|
if (this.tag === '+') {
|
|
28
26
|
// special case
|
|
29
27
|
this.humanReadable = this.remainder.trim();
|
|
@@ -42,13 +40,28 @@ class ParserInstance {
|
|
|
42
40
|
case 'BAD':
|
|
43
41
|
case 'PREAUTH':
|
|
44
42
|
case 'BYE':
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
43
|
+
{
|
|
44
|
+
let match = this.remainder.match(/^\s+\[/);
|
|
45
|
+
if (match) {
|
|
46
|
+
let nesting = 1;
|
|
47
|
+
for (let i = match[0].length; i <= this.remainder.length; i++) {
|
|
48
|
+
let c = this.remainder[i];
|
|
49
|
+
|
|
50
|
+
if (c === '[') {
|
|
51
|
+
nesting++;
|
|
52
|
+
} else if (c === ']') {
|
|
53
|
+
nesting--;
|
|
54
|
+
}
|
|
55
|
+
if (!nesting) {
|
|
56
|
+
this.humanReadable = this.remainder.substring(i + 1).trim();
|
|
57
|
+
this.remainder = this.remainder.substring(0, i + 1);
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
this.humanReadable = this.remainder.trim();
|
|
63
|
+
this.remainder = '';
|
|
64
|
+
}
|
|
52
65
|
}
|
|
53
66
|
break;
|
|
54
67
|
}
|
|
@@ -167,6 +167,7 @@ class TokenParser {
|
|
|
167
167
|
this.currentNode.isClosed = true;
|
|
168
168
|
this.currentNode.endPos = this.pos + i;
|
|
169
169
|
this.currentNode = this.currentNode.parentNode;
|
|
170
|
+
|
|
170
171
|
checkSP();
|
|
171
172
|
break;
|
|
172
173
|
|
|
@@ -222,7 +223,7 @@ class TokenParser {
|
|
|
222
223
|
// [ starts section
|
|
223
224
|
case '[':
|
|
224
225
|
// If it is the *first* element after response command, then process as a response argument list
|
|
225
|
-
if (['OK', 'NO', 'BAD', 'BYE', 'PREAUTH'].
|
|
226
|
+
if (['OK', 'NO', 'BAD', 'BYE', 'PREAUTH'].includes(this.parent.command.toUpperCase()) && this.currentNode === this.tree) {
|
|
226
227
|
this.currentNode.endPos = this.pos + i;
|
|
227
228
|
|
|
228
229
|
this.currentNode = this.createNode(this.currentNode, this.pos + i);
|
|
@@ -258,6 +259,7 @@ class TokenParser {
|
|
|
258
259
|
// close out the SECTION
|
|
259
260
|
this.currentNode.isClosed = true;
|
|
260
261
|
this.currentNode = this.currentNode.parentNode;
|
|
262
|
+
|
|
261
263
|
checkSP();
|
|
262
264
|
}
|
|
263
265
|
|
|
@@ -302,8 +304,8 @@ class TokenParser {
|
|
|
302
304
|
this.currentNode.endPos = this.pos + i;
|
|
303
305
|
this.currentNode = this.currentNode.parentNode;
|
|
304
306
|
this.state = 'NORMAL';
|
|
305
|
-
|
|
306
307
|
checkSP();
|
|
308
|
+
|
|
307
309
|
break;
|
|
308
310
|
}
|
|
309
311
|
|
|
@@ -541,6 +543,10 @@ class TokenParser {
|
|
|
541
543
|
|
|
542
544
|
this.currentNode.value += chr;
|
|
543
545
|
break;
|
|
546
|
+
|
|
547
|
+
case 'TEXT':
|
|
548
|
+
this.currentNode.value += chr;
|
|
549
|
+
break;
|
|
544
550
|
}
|
|
545
551
|
}
|
|
546
552
|
}
|
package/lib/imap-flow.js
CHANGED
|
@@ -127,10 +127,11 @@ class ImapFlow extends EventEmitter {
|
|
|
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
|
|
130
|
-
* @param {
|
|
130
|
+
* @param {String} [options.proxy] Optional proxy URL. Supports HTTP CONNECT (`http://`, `https://`) and SOCKS (`socks://`, `socks4://`, `socks5://`) proxies
|
|
131
131
|
* @param {Boolean} [options.qresync=false] If true, then enables QRESYNC support. EXPUNGE notifications will include `uid` property instead of `seq`
|
|
132
132
|
* @param {Number} [options.maxIdleTime] If set, then breaks and restarts IDLE every maxIdleTime ms
|
|
133
133
|
* @param {Boolean} [options.disableBinary=false] If true, then ignores the BINARY extension when making FETCH and APPEND calls
|
|
134
|
+
* @param {Boolean} [options.disableAutoEnable] Do not enable supported extensions by default
|
|
134
135
|
*/
|
|
135
136
|
constructor(options) {
|
|
136
137
|
super({ captureRejections: true });
|
|
@@ -211,6 +212,7 @@ class ImapFlow extends EventEmitter {
|
|
|
211
212
|
* @type {Map<string, boolean|number>}
|
|
212
213
|
*/
|
|
213
214
|
this.capabilities = new Map();
|
|
215
|
+
this.rawCapabilities = null;
|
|
214
216
|
|
|
215
217
|
this.expectCapabilityUpdate = false; // force CAPABILITY after LOGIN
|
|
216
218
|
|
|
@@ -645,8 +647,10 @@ class ImapFlow extends EventEmitter {
|
|
|
645
647
|
await this.compress();
|
|
646
648
|
}
|
|
647
649
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
+
if (!this.options.disableAutoEnable) {
|
|
651
|
+
// enable extensions if possible
|
|
652
|
+
await this.run('ENABLE', ['CONDSTORE', 'UTF8=ACCEPT'].concat(this.options.qresync ? 'QRESYNC' : []));
|
|
653
|
+
}
|
|
650
654
|
|
|
651
655
|
this.usable = true;
|
|
652
656
|
}
|
|
@@ -920,6 +924,7 @@ class ImapFlow extends EventEmitter {
|
|
|
920
924
|
}
|
|
921
925
|
|
|
922
926
|
async sectionCapability(section) {
|
|
927
|
+
this.rawCapabilities = section;
|
|
923
928
|
this.capabilities = updateCapabilities(section);
|
|
924
929
|
if (this.expectCapabilityUpdate) {
|
|
925
930
|
this.expectCapabilityUpdate = false;
|
|
@@ -927,6 +932,7 @@ class ImapFlow extends EventEmitter {
|
|
|
927
932
|
}
|
|
928
933
|
|
|
929
934
|
async untaggedCapability(untagged) {
|
|
935
|
+
this.rawCapabilities = untagged.attributes;
|
|
930
936
|
this.capabilities = updateCapabilities(untagged.attributes);
|
|
931
937
|
if (this.expectCapabilityUpdate) {
|
|
932
938
|
this.expectCapabilityUpdate = false;
|
|
@@ -2611,6 +2617,24 @@ class ImapFlow extends EventEmitter {
|
|
|
2611
2617
|
|
|
2612
2618
|
return synteticLogger;
|
|
2613
2619
|
}
|
|
2620
|
+
|
|
2621
|
+
unbind() {
|
|
2622
|
+
this.socket.unpipe(this.streamer);
|
|
2623
|
+
if (this._inflate) {
|
|
2624
|
+
this._inflate.unpipe(this.streamer);
|
|
2625
|
+
}
|
|
2626
|
+
|
|
2627
|
+
this.socket.removeListener('error', this._socketError);
|
|
2628
|
+
this.socket.removeListener('close', this._socketClose);
|
|
2629
|
+
this.socket.removeListener('end', this._socketEnd);
|
|
2630
|
+
this.socket.removeListener('tlsClientError', this._socketError);
|
|
2631
|
+
this.socket.removeListener('timeout', this._socketTimeout);
|
|
2632
|
+
|
|
2633
|
+
return {
|
|
2634
|
+
readSocket: this._inflate || this.socket,
|
|
2635
|
+
writeSocket: this.writeSocket || this.socket
|
|
2636
|
+
};
|
|
2637
|
+
}
|
|
2614
2638
|
}
|
|
2615
2639
|
|
|
2616
2640
|
/**
|
package/lib/types.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ declare module "imapflow" {
|
|
|
30
30
|
* @param [options.qresync = false] - If true, then enables QRESYNC support. EXPUNGE notifications will include `uid` property instead of `seq`
|
|
31
31
|
* @param [options.maxIdleTime] - If set, then breaks and restarts IDLE every maxIdleTime ms
|
|
32
32
|
* @param [options.disableBinary = false] - If true, then ignores the BINARY extension when making FETCH and APPEND calls
|
|
33
|
+
* @param [options.disableAutoEnable] - Do not enable supported extensions by default
|
|
33
34
|
*/
|
|
34
35
|
class ImapFlow extends EventEmitter {
|
|
35
36
|
constructor(options: {
|
|
@@ -54,10 +55,11 @@ declare module "imapflow" {
|
|
|
54
55
|
logRaw?: boolean;
|
|
55
56
|
emitLogs?: boolean;
|
|
56
57
|
verifyOnly?: boolean;
|
|
57
|
-
proxy?:
|
|
58
|
+
proxy?: string;
|
|
58
59
|
qresync?: boolean;
|
|
59
60
|
maxIdleTime?: number;
|
|
60
61
|
disableBinary?: boolean;
|
|
62
|
+
disableAutoEnable?: boolean;
|
|
61
63
|
});
|
|
62
64
|
/**
|
|
63
65
|
* Current module version as a static class property
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "imapflow",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.106",
|
|
4
4
|
"description": "IMAP Client for Node",
|
|
5
5
|
"main": "./lib/imap-flow.js",
|
|
6
6
|
"scripts": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@babel/eslint-plugin": "7.18.10",
|
|
32
32
|
"@babel/plugin-syntax-class-properties": "7.12.13",
|
|
33
33
|
"@babel/preset-env": "7.18.10",
|
|
34
|
-
"@types/node": "18.7.
|
|
34
|
+
"@types/node": "18.7.11",
|
|
35
35
|
"braintree-jsdoc-template": "3.3.0",
|
|
36
36
|
"eslint": "8.22.0",
|
|
37
37
|
"eslint-config-nodemailer": "1.2.0",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"libqp": "1.1.0",
|
|
53
53
|
"mailsplit": "5.3.2",
|
|
54
54
|
"nodemailer": "6.7.8",
|
|
55
|
-
"pino": "8.4.
|
|
55
|
+
"pino": "8.4.2",
|
|
56
56
|
"socks": "2.7.0"
|
|
57
57
|
}
|
|
58
58
|
}
|
package/test/imap-parser-test.js
CHANGED
|
@@ -914,11 +914,19 @@ module.exports['IMAP Parser, unicode select'] = test =>
|
|
|
914
914
|
value: '',
|
|
915
915
|
section: [{ type: 'ATOM', value: 'READ-WRITE' }]
|
|
916
916
|
},
|
|
917
|
-
{ type: '
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
917
|
+
{ type: 'TEXT', value: '[Gmail]/Visi laiškai selected. (Success) [THROTTLED]' }
|
|
918
|
+
])
|
|
919
|
+
);
|
|
920
|
+
|
|
921
|
+
module.exports['IMAP Parser, unicode select 2'] = test =>
|
|
922
|
+
asyncWrapper(test, async test =>
|
|
923
|
+
test.deepEqual((await parser('E OK [READ-WRITE] [Gmail]/Вся почта selected. (Success) [THROTTLED]')).attributes, [
|
|
924
|
+
{
|
|
925
|
+
type: 'ATOM',
|
|
926
|
+
value: '',
|
|
927
|
+
section: [{ type: 'ATOM', value: 'READ-WRITE' }]
|
|
928
|
+
},
|
|
929
|
+
{ type: 'TEXT', value: '[Gmail]/Вся почта selected. (Success) [THROTTLED]' }
|
|
922
930
|
])
|
|
923
931
|
);
|
|
924
932
|
|