imapflow 1.0.109 → 1.0.111
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 +11 -0
- package/lib/handler/token-parser.js +3 -1
- package/lib/imap-flow.js +13 -3
- package/lib/types.d.ts +8 -0
- package/package.json +5 -5
- package/test/imap-parser-test.js +29 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
- 1.0.111 - 2022-10-13
|
|
4
|
+
|
|
5
|
+
- Added new connection options
|
|
6
|
+
- connectionTimeout=90000: how many milliseconds to wait for the connection to establish (default is 90 seconds)
|
|
7
|
+
- greetingTimeout=16000: how many milliseconds to wait for the greeting after connection is established (default is 16 seconds)
|
|
8
|
+
- socketTimeout=300000: how many milliseconds of inactivity to allow (default is 5 minutes)
|
|
9
|
+
|
|
10
|
+
- 1.0.110 - 2022-10-10
|
|
11
|
+
|
|
12
|
+
- Allow unicode atoms by default
|
|
13
|
+
|
|
3
14
|
- 1.0.109 - 2022-09-29
|
|
4
15
|
|
|
5
16
|
- New method `downloadMany`
|
|
@@ -271,7 +271,8 @@ class TokenParser {
|
|
|
271
271
|
// Any ATOM supported char starts a new Atom sequence, otherwise throw an error
|
|
272
272
|
// Allow \ as the first char for atom to support system flags
|
|
273
273
|
// Allow % to support LIST '' %
|
|
274
|
-
|
|
274
|
+
// Allow 8bit characters (presumably unicode)
|
|
275
|
+
if (imapFormalSyntax['ATOM-CHAR']().indexOf(chr) < 0 && chr !== '\\' && chr !== '%' && chr.charCodeAt(0) < 0x80) {
|
|
275
276
|
throw new Error(`Unexpected char at position ${this.pos + i} [E10: ${JSON.stringify(chr)}]`);
|
|
276
277
|
}
|
|
277
278
|
|
|
@@ -336,6 +337,7 @@ class TokenParser {
|
|
|
336
337
|
// if the char is not ATOM compatible, throw. Allow \* as an exception
|
|
337
338
|
if (
|
|
338
339
|
imapFormalSyntax['ATOM-CHAR']().indexOf(chr) < 0 &&
|
|
340
|
+
chr.charCodeAt(0) < 0x80 && // allow 8bit (presumably unicode) bytes
|
|
339
341
|
chr !== ']' &&
|
|
340
342
|
!(chr === '*' && this.currentNode.value === '\\') &&
|
|
341
343
|
(!this.parent || !this.parent.command || !['NO', 'BAD', 'OK'].includes(this.parent.command))
|
package/lib/imap-flow.js
CHANGED
|
@@ -132,6 +132,9 @@ class ImapFlow extends EventEmitter {
|
|
|
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
134
|
* @param {Boolean} [options.disableAutoEnable] Do not enable supported extensions by default
|
|
135
|
+
* @param {Number} [options.connectionTimeout=90000] how many milliseconds to wait for the connection to establish (default is 90 seconds)
|
|
136
|
+
* @param {Number} [options.greetingTimeout=16000] how many milliseconds to wait for the greeting after connection is established (default is 16 seconds)
|
|
137
|
+
* @param {Number} [options.socketTimeout=300000] how many milliseconds of inactivity to allow (default is 5 minutes)
|
|
135
138
|
*/
|
|
136
139
|
constructor(options) {
|
|
137
140
|
super({ captureRejections: true });
|
|
@@ -1187,23 +1190,29 @@ class ImapFlow extends EventEmitter {
|
|
|
1187
1190
|
this.connectTimeout = setTimeout(() => {
|
|
1188
1191
|
let err = new Error('Failed to established connection in required time');
|
|
1189
1192
|
err.code = 'CONNECT_TIMEOUT';
|
|
1193
|
+
err.details = {
|
|
1194
|
+
connectionTimeout: this.options.connectionTimeout || CONNECT_TIMEOUT
|
|
1195
|
+
};
|
|
1190
1196
|
this.log.error({ err, cid: this.id });
|
|
1191
1197
|
setImmediate(() => this.close());
|
|
1192
1198
|
reject(err);
|
|
1193
|
-
}, CONNECT_TIMEOUT);
|
|
1199
|
+
}, this.options.connectionTimeout || CONNECT_TIMEOUT);
|
|
1194
1200
|
|
|
1195
1201
|
let onConnect = () => {
|
|
1196
1202
|
clearTimeout(this.connectTimeout);
|
|
1197
1203
|
this.socket.setKeepAlive(true, 5 * 1000);
|
|
1198
|
-
this.socket.setTimeout(SOCKET_TIMEOUT);
|
|
1204
|
+
this.socket.setTimeout(this.options.socketTimeout || SOCKET_TIMEOUT);
|
|
1199
1205
|
|
|
1200
1206
|
this.greetingTimeout = setTimeout(() => {
|
|
1201
1207
|
let err = new Error(`Failed to receive greeting from server in required time${!this.secureConnection ? '. Maybe should use TLS?' : ''}`);
|
|
1202
1208
|
err.code = 'GREEETING_TIMEOUT';
|
|
1209
|
+
err.details = {
|
|
1210
|
+
greetingTimeout: this.options.greetingTimeout || GREETING_TIMEOUT
|
|
1211
|
+
};
|
|
1203
1212
|
this.log.error({ err, cid: this.id });
|
|
1204
1213
|
setImmediate(() => this.close());
|
|
1205
1214
|
reject(err);
|
|
1206
|
-
}, GREETING_TIMEOUT);
|
|
1215
|
+
}, this.options.greetingTimeout || GREETING_TIMEOUT);
|
|
1207
1216
|
|
|
1208
1217
|
this.tls = typeof this.socket.getCipher === 'function' ? this.socket.getCipher() : false;
|
|
1209
1218
|
|
|
@@ -2163,6 +2172,7 @@ class ImapFlow extends EventEmitter {
|
|
|
2163
2172
|
* @typedef {Object} DownloadObject
|
|
2164
2173
|
* @global
|
|
2165
2174
|
* @property {Object} meta content metadata
|
|
2175
|
+
* @property {number} meta.expectedSize The fetch response size
|
|
2166
2176
|
* @property {String} meta.contentType Content-Type of the streamed file. If part was not set then this value is "message/rfc822"
|
|
2167
2177
|
* @property {String} [meta.charset] Charset of the body part. Text parts are automaticaly converted to UTF-8, attachments are kept as is
|
|
2168
2178
|
* @property {String} [meta.disposition] Content-Disposition of the streamed file
|
package/lib/types.d.ts
CHANGED
|
@@ -31,6 +31,9 @@ declare module "imapflow" {
|
|
|
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
33
|
* @param [options.disableAutoEnable] - Do not enable supported extensions by default
|
|
34
|
+
* @param [options.connectionTimeout = 90000] - how many milliseconds to wait for the connection to establish (default is 90 seconds)
|
|
35
|
+
* @param [options.greetingTimeout = 16000] - how many milliseconds to wait for the greeting after connection is established (default is 16 seconds)
|
|
36
|
+
* @param [options.socketTimeout = 300000] - how many milliseconds of inactivity to allow (default is 5 minutes)
|
|
34
37
|
*/
|
|
35
38
|
class ImapFlow extends EventEmitter {
|
|
36
39
|
constructor(options: {
|
|
@@ -60,6 +63,9 @@ declare module "imapflow" {
|
|
|
60
63
|
maxIdleTime?: number;
|
|
61
64
|
disableBinary?: boolean;
|
|
62
65
|
disableAutoEnable?: boolean;
|
|
66
|
+
connectionTimeout?: number;
|
|
67
|
+
greetingTimeout?: number;
|
|
68
|
+
socketTimeout?: number;
|
|
63
69
|
});
|
|
64
70
|
/**
|
|
65
71
|
* Current module version as a static class property
|
|
@@ -941,6 +947,7 @@ declare type FetchMessageObject = {
|
|
|
941
947
|
|
|
942
948
|
/**
|
|
943
949
|
* @property meta - content metadata
|
|
950
|
+
* @property meta.expectedSize - The fetch response size
|
|
944
951
|
* @property meta.contentType - Content-Type of the streamed file. If part was not set then this value is "message/rfc822"
|
|
945
952
|
* @property [meta.charset] - Charset of the body part. Text parts are automaticaly converted to UTF-8, attachments are kept as is
|
|
946
953
|
* @property [meta.disposition] - Content-Disposition of the streamed file
|
|
@@ -949,6 +956,7 @@ declare type FetchMessageObject = {
|
|
|
949
956
|
*/
|
|
950
957
|
declare type DownloadObject = {
|
|
951
958
|
meta: {
|
|
959
|
+
expectedSize: number;
|
|
952
960
|
contentType: string;
|
|
953
961
|
charset?: string;
|
|
954
962
|
disposition?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "imapflow",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.111",
|
|
4
4
|
"description": "IMAP Client for Node",
|
|
5
5
|
"main": "./lib/imap-flow.js",
|
|
6
6
|
"scripts": {
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"@babel/eslint-parser": "7.19.1",
|
|
31
31
|
"@babel/eslint-plugin": "7.19.1",
|
|
32
32
|
"@babel/plugin-syntax-class-properties": "7.12.13",
|
|
33
|
-
"@babel/preset-env": "7.19.
|
|
34
|
-
"@types/node": "18.
|
|
33
|
+
"@babel/preset-env": "7.19.4",
|
|
34
|
+
"@types/node": "18.8.5",
|
|
35
35
|
"braintree-jsdoc-template": "3.3.0",
|
|
36
|
-
"eslint": "8.
|
|
36
|
+
"eslint": "8.25.0",
|
|
37
37
|
"eslint-config-nodemailer": "1.2.0",
|
|
38
38
|
"eslint-config-prettier": "8.5.0",
|
|
39
39
|
"grunt": "1.5.3",
|
|
@@ -53,6 +53,6 @@
|
|
|
53
53
|
"mailsplit": "5.3.2",
|
|
54
54
|
"nodemailer": "6.8.0",
|
|
55
55
|
"pino": "8.6.1",
|
|
56
|
-
"socks": "2.7.
|
|
56
|
+
"socks": "2.7.1"
|
|
57
57
|
}
|
|
58
58
|
}
|
package/test/imap-parser-test.js
CHANGED
|
@@ -941,3 +941,32 @@ module.exports['IMAP Parser, single quote in atom'] = test =>
|
|
|
941
941
|
{ type: 'ATOM', value: "'a" }
|
|
942
942
|
])
|
|
943
943
|
);
|
|
944
|
+
|
|
945
|
+
module.exports['IMAP Parser, unicode status 1'] = test =>
|
|
946
|
+
asyncWrapper(test, async test =>
|
|
947
|
+
test.deepEqual((await parser('* STATUS Segregator/Społeczności (MESSAGES 0 UIDNEXT 1 UIDVALIDITY 1)')).attributes, [
|
|
948
|
+
{ type: 'ATOM', value: 'Segregator/Społeczności' },
|
|
949
|
+
[
|
|
950
|
+
{ type: 'ATOM', value: 'MESSAGES' },
|
|
951
|
+
{ type: 'ATOM', value: '0' },
|
|
952
|
+
{ type: 'ATOM', value: 'UIDNEXT' },
|
|
953
|
+
{ type: 'ATOM', value: '1' },
|
|
954
|
+
{ type: 'ATOM', value: 'UIDVALIDITY' },
|
|
955
|
+
{ type: 'ATOM', value: '1' }
|
|
956
|
+
]
|
|
957
|
+
])
|
|
958
|
+
);
|
|
959
|
+
module.exports['IMAP Parser, unicode status 12'] = test =>
|
|
960
|
+
asyncWrapper(test, async test =>
|
|
961
|
+
test.deepEqual((await parser('* STATUS Šegregator/Społeczności (MESSAGES 0 UIDNEXT 1 UIDVALIDITY 1)')).attributes, [
|
|
962
|
+
{ type: 'ATOM', value: 'Šegregator/Społeczności' },
|
|
963
|
+
[
|
|
964
|
+
{ type: 'ATOM', value: 'MESSAGES' },
|
|
965
|
+
{ type: 'ATOM', value: '0' },
|
|
966
|
+
{ type: 'ATOM', value: 'UIDNEXT' },
|
|
967
|
+
{ type: 'ATOM', value: '1' },
|
|
968
|
+
{ type: 'ATOM', value: 'UIDVALIDITY' },
|
|
969
|
+
{ type: 'ATOM', value: '1' }
|
|
970
|
+
]
|
|
971
|
+
])
|
|
972
|
+
);
|