imapflow 1.0.171 → 1.0.173
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 +14 -0
- package/lib/commands/authenticate.js +4 -3
- package/lib/imap-flow.js +107 -47
- package/lib/tools.js +28 -17
- package/lib/types.d.ts +153 -79
- package/package.json +3 -3
- package/test/bodystructure-test.js +994 -0
- package/test/imap-parser-test.js +177 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.173](https://github.com/postalsys/imapflow/compare/v1.0.172...v1.0.173) (2025-01-08)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **bodystructure:** Handle invalid BODYSTRUCTURE from Bluemind mail server ([b63f861](https://github.com/postalsys/imapflow/commit/b63f861f2894d0a34583ad9ff512ef5071f63228))
|
|
9
|
+
|
|
10
|
+
## [1.0.172](https://github.com/postalsys/imapflow/compare/v1.0.171...v1.0.172) (2025-01-03)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **password-auth:** Added option auth.loginMethod to set specific authentication method ('LOGIN', 'AUTH=PLAIN', 'AUTH=LOGIN') ([ce3c339](https://github.com/postalsys/imapflow/commit/ce3c33908f5ad445b1a2fdcf2dfcbd4859413cf7))
|
|
16
|
+
|
|
3
17
|
## [1.0.171](https://github.com/postalsys/imapflow/compare/v1.0.170...v1.0.171) (2024-12-05)
|
|
4
18
|
|
|
5
19
|
|
|
@@ -137,7 +137,7 @@ async function authPlain(connection, username, password) {
|
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
// Authenticates user using LOGIN
|
|
140
|
-
module.exports = async (connection, username, { accessToken, password }) => {
|
|
140
|
+
module.exports = async (connection, username, { accessToken, password, loginMethod }) => {
|
|
141
141
|
if (connection.state !== connection.states.NOT_AUTHENTICATED) {
|
|
142
142
|
// nothing to do here
|
|
143
143
|
return;
|
|
@@ -151,10 +151,11 @@ module.exports = async (connection, username, { accessToken, password }) => {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
if (password) {
|
|
154
|
-
if (connection.capabilities.has('AUTH=PLAIN')) {
|
|
154
|
+
if ((!loginMethod && connection.capabilities.has('AUTH=PLAIN')) || loginMethod === 'AUTH=PLAIN') {
|
|
155
155
|
return await authPlain(connection, username, password);
|
|
156
156
|
}
|
|
157
|
-
|
|
157
|
+
|
|
158
|
+
if ((!loginMethod && connection.capabilities.has('AUTH=LOGIN')) || loginMethod === 'AUTH=LOGIN') {
|
|
158
159
|
return await authLogin(connection, username, password);
|
|
159
160
|
}
|
|
160
161
|
}
|
package/lib/imap-flow.js
CHANGED
|
@@ -116,48 +116,110 @@ class ImapFlow extends EventEmitter {
|
|
|
116
116
|
static version = packageInfo.version;
|
|
117
117
|
|
|
118
118
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* @
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* @
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* @
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
* @
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
* @
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
* @
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
* @
|
|
158
|
-
*
|
|
159
|
-
*
|
|
119
|
+
* IMAP connection options
|
|
120
|
+
*
|
|
121
|
+
* @property {String} host
|
|
122
|
+
* Hostname of the IMAP server.
|
|
123
|
+
*
|
|
124
|
+
* @property {Number} port
|
|
125
|
+
* Port number for the IMAP server.
|
|
126
|
+
*
|
|
127
|
+
* @property {Boolean} [secure=false]
|
|
128
|
+
* If `true`, establishes the connection directly over TLS (commonly on port 993).
|
|
129
|
+
* If `false`, a plain (unencrypted) connection is used first and, if possible, the connection is upgraded to STARTTLS.
|
|
130
|
+
*
|
|
131
|
+
* @property {Boolean} [doSTARTTLS=undefined]
|
|
132
|
+
* Determines whether to upgrade the connection to TLS via STARTTLS:
|
|
133
|
+
* - **true**: Start unencrypted and upgrade to TLS using STARTTLS before authentication.
|
|
134
|
+
* The connection fails if the server does not support STARTTLS or the upgrade fails.
|
|
135
|
+
* Note that `secure=true` combined with `doSTARTTLS=true` is invalid.
|
|
136
|
+
* - **false**: Never use STARTTLS, even if the server advertises support.
|
|
137
|
+
* This is useful if the server has a broken TLS setup.
|
|
138
|
+
* Combined with `secure=false`, this results in a fully unencrypted connection.
|
|
139
|
+
* Make sure you warn users about the security risks.
|
|
140
|
+
* - **undefined** (default): If `secure=false` (default), attempt to upgrade to TLS via STARTTLS before authentication if the server supports it. If not supported, continue unencrypted. This may expose the connection to a downgrade attack.
|
|
141
|
+
*
|
|
142
|
+
* @property {String} [servername]
|
|
143
|
+
* Server name for SNI or when using an IP address as `host`.
|
|
144
|
+
*
|
|
145
|
+
* @property {Boolean} [disableCompression=false]
|
|
146
|
+
* If `true`, the client does not attempt to use the COMPRESS=DEFLATE extension.
|
|
147
|
+
*
|
|
148
|
+
* @property {Object} auth
|
|
149
|
+
* Authentication options. Authentication occurs automatically during {@link connect}.
|
|
150
|
+
*
|
|
151
|
+
* @property {String} auth.user
|
|
152
|
+
* Username for authentication.
|
|
153
|
+
*
|
|
154
|
+
* @property {String} [auth.pass]
|
|
155
|
+
* Password for regular authentication.
|
|
156
|
+
*
|
|
157
|
+
* @property {String} [auth.accessToken]
|
|
158
|
+
* OAuth2 access token, if using OAuth2 authentication.
|
|
159
|
+
*
|
|
160
|
+
* @property {String} [auth.loginMethod]
|
|
161
|
+
* Optional login method for password-based authentication (e.g., "LOGIN", "AUTH=LOGIN", or "AUTH=PLAIN").
|
|
162
|
+
* If not set, ImapFlow chooses based on available mechanisms.
|
|
163
|
+
*
|
|
164
|
+
* @property {IdInfoObject} [clientInfo]
|
|
165
|
+
* Client identification info sent to the server (via the ID command).
|
|
166
|
+
*
|
|
167
|
+
* @property {Boolean} [disableAutoIdle=false]
|
|
168
|
+
* If `true`, do not start IDLE automatically. Useful when only specific operations are needed.
|
|
169
|
+
*
|
|
170
|
+
* @property {Object} [tls]
|
|
171
|
+
* Additional TLS options. For details, see [Node.js TLS connect](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback).
|
|
172
|
+
*
|
|
173
|
+
* @property {Boolean} [tls.rejectUnauthorized=true]
|
|
174
|
+
* If `false`, allows self-signed or expired certificates.
|
|
175
|
+
*
|
|
176
|
+
* @property {String} [tls.minVersion='TLSv1.2']
|
|
177
|
+
* Minimum accepted TLS version (e.g., `'TLSv1.2'`).
|
|
178
|
+
*
|
|
179
|
+
* @property {Number} [tls.minDHSize=1024]
|
|
180
|
+
* Minimum size (in bits) of the DH parameter for TLS connections.
|
|
181
|
+
*
|
|
182
|
+
* @property {Object|Boolean} [logger]
|
|
183
|
+
* Custom logger instance with `debug(obj)`, `info(obj)`, `warn(obj)`, and `error(obj)` methods.
|
|
184
|
+
* If `false`, logging is disabled. If not provided, ImapFlow logs to console in [pino format](https://getpino.io/).
|
|
185
|
+
*
|
|
186
|
+
* @property {Boolean} [logRaw=false]
|
|
187
|
+
* If `true`, logs all raw data (read and written) in base64 encoding. You can pipe such logs to [eerawlog](https://github.com/postalsys/eerawlog) command for readable output.
|
|
188
|
+
*
|
|
189
|
+
* @property {Boolean} [emitLogs=false]
|
|
190
|
+
* If `true`, emits `'log'` events with the same data passed to the logger.
|
|
191
|
+
*
|
|
192
|
+
* @property {Boolean} [verifyOnly=false]
|
|
193
|
+
* If `true`, disconnects after successful authentication without performing other actions.
|
|
194
|
+
*
|
|
195
|
+
* @property {String} [proxy]
|
|
196
|
+
* Proxy URL. Supports HTTP CONNECT (`http://`, `https://`) and SOCKS (`socks://`, `socks4://`, `socks5://`).
|
|
197
|
+
*
|
|
198
|
+
* @property {Boolean} [qresync=false]
|
|
199
|
+
* If `true`, enables QRESYNC support so that EXPUNGE notifications include `uid` instead of `seq`.
|
|
200
|
+
*
|
|
201
|
+
* @property {Number} [maxIdleTime]
|
|
202
|
+
* If set, breaks and restarts IDLE every `maxIdleTime` milliseconds.
|
|
203
|
+
*
|
|
204
|
+
* @property {String} [missingIdleCommand="NOOP"]
|
|
205
|
+
* Command to use if the server does not support IDLE.
|
|
206
|
+
*
|
|
207
|
+
* @property {Boolean} [disableBinary=false]
|
|
208
|
+
* If `true`, ignores the BINARY extension for FETCH and APPEND operations.
|
|
209
|
+
*
|
|
210
|
+
* @property {Boolean} [disableAutoEnable=false]
|
|
211
|
+
* If `true`, do not automatically enable supported IMAP extensions.
|
|
212
|
+
*
|
|
213
|
+
* @property {Number} [connectionTimeout=90000]
|
|
214
|
+
* Maximum time (in milliseconds) to wait for the connection to establish. Defaults to 90 seconds.
|
|
215
|
+
*
|
|
216
|
+
* @property {Number} [greetingTimeout=16000]
|
|
217
|
+
* Maximum time (in milliseconds) to wait for the server greeting after a connection is established. Defaults to 16 seconds.
|
|
218
|
+
*
|
|
219
|
+
* @property {Number} [socketTimeout=300000]
|
|
220
|
+
* Maximum period of inactivity (in milliseconds) before terminating the connection. Defaults to 5 minutes.
|
|
160
221
|
*/
|
|
222
|
+
|
|
161
223
|
constructor(options) {
|
|
162
224
|
super({ captureRejections: true });
|
|
163
225
|
|
|
@@ -277,10 +339,6 @@ class ImapFlow extends EventEmitter {
|
|
|
277
339
|
*/
|
|
278
340
|
this.idling = false;
|
|
279
341
|
|
|
280
|
-
/**
|
|
281
|
-
* If `true` then in addition of sending data to logger, ImapFlow emits 'log' events with the same data
|
|
282
|
-
* @type {Boolean}
|
|
283
|
-
*/
|
|
284
342
|
this.emitLogs = !!this.options.emitLogs;
|
|
285
343
|
// ordering number for emitted logs
|
|
286
344
|
this.lo = 0;
|
|
@@ -986,11 +1044,13 @@ class ImapFlow extends EventEmitter {
|
|
|
986
1044
|
|
|
987
1045
|
this.expectCapabilityUpdate = true;
|
|
988
1046
|
|
|
1047
|
+
let loginMethod = (this.options.auth.loginMethod || '').toString().trim().toUpperCase();
|
|
1048
|
+
|
|
989
1049
|
if (this.options.auth.accessToken) {
|
|
990
1050
|
this.authenticated = await this.run('AUTHENTICATE', this.options.auth.user, { accessToken: this.options.auth.accessToken });
|
|
991
1051
|
} else if (this.options.auth.pass) {
|
|
992
|
-
if (this.capabilities.has('AUTH=LOGIN') || this.capabilities.has('AUTH=PLAIN')) {
|
|
993
|
-
this.authenticated = await this.run('AUTHENTICATE', this.options.auth.user, { password: this.options.auth.pass });
|
|
1052
|
+
if ((this.capabilities.has('AUTH=LOGIN') || this.capabilities.has('AUTH=PLAIN')) && loginMethod !== 'LOGIN') {
|
|
1053
|
+
this.authenticated = await this.run('AUTHENTICATE', this.options.auth.user, { password: this.options.auth.pass, loginMethod });
|
|
994
1054
|
} else {
|
|
995
1055
|
this.authenticated = await this.run('LOGIN', this.options.auth.user, this.options.auth.pass);
|
|
996
1056
|
}
|
package/lib/tools.js
CHANGED
|
@@ -10,7 +10,7 @@ const iconv = require('iconv-lite');
|
|
|
10
10
|
|
|
11
11
|
const FLAG_COLORS = ['red', 'orange', 'yellow', 'green', 'blue', 'purple', 'grey'];
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
const tools = {
|
|
14
14
|
encodePath(connection, path) {
|
|
15
15
|
path = (path || '').toString();
|
|
16
16
|
if (!connection.enabled.has('UTF8=ACCEPT') && /[&\x00-\x08\x0b-\x0c\x0e-\x1f\u0080-\uffff]/.test(path)) {
|
|
@@ -57,7 +57,7 @@ module.exports = {
|
|
|
57
57
|
if (!a || !b) {
|
|
58
58
|
return false;
|
|
59
59
|
}
|
|
60
|
-
return
|
|
60
|
+
return tools.normalizePath(connection, a) === tools.normalizePath(connection, b);
|
|
61
61
|
},
|
|
62
62
|
|
|
63
63
|
updateCapabilities(list) {
|
|
@@ -336,11 +336,11 @@ module.exports = {
|
|
|
336
336
|
break;
|
|
337
337
|
|
|
338
338
|
case 'envelope':
|
|
339
|
-
map.envelope =
|
|
339
|
+
map.envelope = tools.parseEnvelope(attribute);
|
|
340
340
|
break;
|
|
341
341
|
|
|
342
342
|
case 'bodystructure':
|
|
343
|
-
map.bodyStructure =
|
|
343
|
+
map.bodyStructure = tools.parseBodystructure(attribute);
|
|
344
344
|
break;
|
|
345
345
|
|
|
346
346
|
case 'internaldate': {
|
|
@@ -398,7 +398,7 @@ module.exports = {
|
|
|
398
398
|
}
|
|
399
399
|
|
|
400
400
|
if (map.flags) {
|
|
401
|
-
let flagColor =
|
|
401
|
+
let flagColor = tools.getFlagColor(map.flags);
|
|
402
402
|
if (flagColor) {
|
|
403
403
|
map.flagColor = flagColor;
|
|
404
404
|
}
|
|
@@ -438,7 +438,7 @@ module.exports = {
|
|
|
438
438
|
address = '';
|
|
439
439
|
}
|
|
440
440
|
return {
|
|
441
|
-
name:
|
|
441
|
+
name: tools.processName(libmime.decodeWords(getStrValue(addr[0]))),
|
|
442
442
|
address
|
|
443
443
|
};
|
|
444
444
|
})
|
|
@@ -609,7 +609,7 @@ module.exports = {
|
|
|
609
609
|
// body parameter parenthesized list
|
|
610
610
|
if (i < node.length - 1) {
|
|
611
611
|
if (node[i]) {
|
|
612
|
-
curNode.parameters =
|
|
612
|
+
curNode.parameters = tools.getStructuredParams(node[i]);
|
|
613
613
|
}
|
|
614
614
|
i++;
|
|
615
615
|
}
|
|
@@ -619,7 +619,7 @@ module.exports = {
|
|
|
619
619
|
|
|
620
620
|
// body parameter parenthesized list
|
|
621
621
|
if (node[i]) {
|
|
622
|
-
curNode.parameters =
|
|
622
|
+
curNode.parameters = tools.getStructuredParams(node[i]);
|
|
623
623
|
}
|
|
624
624
|
i++;
|
|
625
625
|
|
|
@@ -652,7 +652,7 @@ module.exports = {
|
|
|
652
652
|
|
|
653
653
|
// envelope
|
|
654
654
|
if (node[i]) {
|
|
655
|
-
curNode.envelope =
|
|
655
|
+
curNode.envelope = tools.parseEnvelope([].concat(node[i] || []));
|
|
656
656
|
}
|
|
657
657
|
i++;
|
|
658
658
|
|
|
@@ -671,14 +671,23 @@ module.exports = {
|
|
|
671
671
|
curNode.lineCount = Number((node[i] || {}).value || 0) || 0;
|
|
672
672
|
}
|
|
673
673
|
i++;
|
|
674
|
-
}
|
|
675
|
-
// text/* adds additional line count values
|
|
674
|
+
}
|
|
676
675
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
676
|
+
if (/^text\//.test(curNode.type)) {
|
|
677
|
+
// text/* adds additional line count value
|
|
678
|
+
|
|
679
|
+
// NB! some less known servers do not include the line count value
|
|
680
|
+
// length should be 12+
|
|
681
|
+
if (node.length === 11 && Array.isArray(node[i + 1]) && !Array.isArray(node[i + 2])) {
|
|
682
|
+
// invalid structure, disposition params are shifted
|
|
683
|
+
} else {
|
|
684
|
+
// correct structure, line count number is provided
|
|
685
|
+
if (node[i]) {
|
|
686
|
+
// line count
|
|
687
|
+
curNode.lineCount = Number((node[i] || {}).value || 0) || 0;
|
|
688
|
+
}
|
|
689
|
+
i++;
|
|
680
690
|
}
|
|
681
|
-
i++;
|
|
682
691
|
}
|
|
683
692
|
|
|
684
693
|
// extension data (not available for BODY requests)
|
|
@@ -700,7 +709,7 @@ module.exports = {
|
|
|
700
709
|
if (Array.isArray(node[i]) && node[i].length) {
|
|
701
710
|
curNode.disposition = ((node[i][0] || {}).value || '').toString().toLowerCase();
|
|
702
711
|
if (Array.isArray(node[i][1])) {
|
|
703
|
-
curNode.dispositionParameters =
|
|
712
|
+
curNode.dispositionParameters = tools.getStructuredParams(node[i][1]);
|
|
704
713
|
}
|
|
705
714
|
}
|
|
706
715
|
i++;
|
|
@@ -762,7 +771,7 @@ module.exports = {
|
|
|
762
771
|
return;
|
|
763
772
|
}
|
|
764
773
|
|
|
765
|
-
let dateStr =
|
|
774
|
+
let dateStr = tools.formatDate(value).replace(/^0/, ''); //starts with date-day-fixed with leading 0 replaced by SP
|
|
766
775
|
let timeStr = value.toISOString().substr(11, 8);
|
|
767
776
|
|
|
768
777
|
return `${dateStr} ${timeStr} +0000`;
|
|
@@ -856,3 +865,5 @@ module.exports = {
|
|
|
856
865
|
return result.join(',');
|
|
857
866
|
}
|
|
858
867
|
};
|
|
868
|
+
|
|
869
|
+
module.exports = tools;
|
package/lib/types.d.ts
CHANGED
|
@@ -4,83 +4,50 @@ declare module "imapflow" {
|
|
|
4
4
|
import { EventEmitter } from "events";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* IMAP
|
|
8
|
-
* @
|
|
9
|
-
* @
|
|
10
|
-
* @
|
|
11
|
-
*
|
|
12
|
-
* @
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* @
|
|
25
|
-
* @
|
|
26
|
-
* @
|
|
27
|
-
* @
|
|
28
|
-
*
|
|
29
|
-
* @
|
|
30
|
-
* @
|
|
31
|
-
* @
|
|
32
|
-
* @
|
|
33
|
-
* @
|
|
34
|
-
* @
|
|
35
|
-
* @
|
|
36
|
-
*
|
|
37
|
-
* @
|
|
38
|
-
* @
|
|
39
|
-
* @
|
|
40
|
-
* @
|
|
41
|
-
* @
|
|
42
|
-
* @
|
|
43
|
-
* @
|
|
44
|
-
* @
|
|
45
|
-
* @
|
|
46
|
-
* @
|
|
47
|
-
* @
|
|
48
|
-
* @
|
|
7
|
+
* IMAP connection options
|
|
8
|
+
* @property host - Hostname of the IMAP server.
|
|
9
|
+
* @property port - Port number for the IMAP server.
|
|
10
|
+
* @property [secure = false] - If `true`, establishes the connection directly over TLS (commonly on port 993).
|
|
11
|
+
* If `false`, a plain (unencrypted) connection is used first and, if possible, the connection is upgraded to STARTTLS.
|
|
12
|
+
* @property [doSTARTTLS] - Determines whether to upgrade the connection to TLS via STARTTLS:
|
|
13
|
+
* - **true**: Start unencrypted and upgrade to TLS using STARTTLS before authentication.
|
|
14
|
+
* The connection fails if the server does not support STARTTLS or the upgrade fails.
|
|
15
|
+
* Note that `secure=true` combined with `doSTARTTLS=true` is invalid.
|
|
16
|
+
* - **false**: Never use STARTTLS, even if the server advertises support.
|
|
17
|
+
* This is useful if the server has a broken TLS setup.
|
|
18
|
+
* Combined with `secure=false`, this results in a fully unencrypted connection.
|
|
19
|
+
* Make sure you warn users about the security risks.
|
|
20
|
+
* - **undefined** (default): If `secure=false` (default), attempt to upgrade to TLS via STARTTLS before authentication if the server supports it. If not supported, continue unencrypted. This may expose the connection to a downgrade attack.
|
|
21
|
+
* @property [servername] - Server name for SNI or when using an IP address as `host`.
|
|
22
|
+
* @property [disableCompression = false] - If `true`, the client does not attempt to use the COMPRESS=DEFLATE extension.
|
|
23
|
+
* @property auth - Authentication options. Authentication occurs automatically during {@link connect}.
|
|
24
|
+
* @property auth.user - Username for authentication.
|
|
25
|
+
* @property [auth.pass] - Password for regular authentication.
|
|
26
|
+
* @property [auth.accessToken] - OAuth2 access token, if using OAuth2 authentication.
|
|
27
|
+
* @property [auth.loginMethod] - Optional login method for password-based authentication (e.g., "LOGIN", "AUTH=LOGIN", or "AUTH=PLAIN").
|
|
28
|
+
* If not set, ImapFlow chooses based on available mechanisms.
|
|
29
|
+
* @property [clientInfo] - Client identification info sent to the server (via the ID command).
|
|
30
|
+
* @property [disableAutoIdle = false] - If `true`, do not start IDLE automatically. Useful when only specific operations are needed.
|
|
31
|
+
* @property [tls] - Additional TLS options. For details, see [Node.js TLS connect](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback).
|
|
32
|
+
* @property [tls.rejectUnauthorized = true] - If `false`, allows self-signed or expired certificates.
|
|
33
|
+
* @property [tls.minVersion = 'TLSv1.2'] - Minimum accepted TLS version (e.g., `'TLSv1.2'`).
|
|
34
|
+
* @property [tls.minDHSize = 1024] - Minimum size (in bits) of the DH parameter for TLS connections.
|
|
35
|
+
* @property [logger] - Custom logger instance with `debug(obj)`, `info(obj)`, `warn(obj)`, and `error(obj)` methods.
|
|
36
|
+
* If `false`, logging is disabled. If not provided, ImapFlow logs to console in [pino format](https://getpino.io/).
|
|
37
|
+
* @property [logRaw = false] - If `true`, logs all raw data (read and written) in base64 encoding. You can pipe such logs to [eerawlog](https://github.com/postalsys/eerawlog) command for readable output.
|
|
38
|
+
* @property [emitLogs = false] - If `true`, emits `'log'` events with the same data passed to the logger.
|
|
39
|
+
* @property [verifyOnly = false] - If `true`, disconnects after successful authentication without performing other actions.
|
|
40
|
+
* @property [proxy] - Proxy URL. Supports HTTP CONNECT (`http://`, `https://`) and SOCKS (`socks://`, `socks4://`, `socks5://`).
|
|
41
|
+
* @property [qresync = false] - If `true`, enables QRESYNC support so that EXPUNGE notifications include `uid` instead of `seq`.
|
|
42
|
+
* @property [maxIdleTime] - If set, breaks and restarts IDLE every `maxIdleTime` milliseconds.
|
|
43
|
+
* @property [missingIdleCommand = "NOOP"] - Command to use if the server does not support IDLE.
|
|
44
|
+
* @property [disableBinary = false] - If `true`, ignores the BINARY extension for FETCH and APPEND operations.
|
|
45
|
+
* @property [disableAutoEnable = false] - If `true`, do not automatically enable supported IMAP extensions.
|
|
46
|
+
* @property [connectionTimeout = 90000] - Maximum time (in milliseconds) to wait for the connection to establish. Defaults to 90 seconds.
|
|
47
|
+
* @property [greetingTimeout = 16000] - Maximum time (in milliseconds) to wait for the server greeting after a connection is established. Defaults to 16 seconds.
|
|
48
|
+
* @property [socketTimeout = 300000] - Maximum period of inactivity (in milliseconds) before terminating the connection. Defaults to 5 minutes.
|
|
49
49
|
*/
|
|
50
50
|
class ImapFlow extends EventEmitter {
|
|
51
|
-
constructor(options: {
|
|
52
|
-
host: string;
|
|
53
|
-
port: number;
|
|
54
|
-
secure?: boolean;
|
|
55
|
-
doSTARTTLS?: boolean;
|
|
56
|
-
servername?: string;
|
|
57
|
-
disableCompression?: boolean;
|
|
58
|
-
auth: {
|
|
59
|
-
user: string;
|
|
60
|
-
pass?: string;
|
|
61
|
-
accessToken?: string;
|
|
62
|
-
};
|
|
63
|
-
clientInfo?: IdInfoObject;
|
|
64
|
-
disableAutoIdle?: boolean;
|
|
65
|
-
tls?: {
|
|
66
|
-
rejectUnauthorized?: boolean;
|
|
67
|
-
minVersion?: string;
|
|
68
|
-
minDHSize?: number;
|
|
69
|
-
};
|
|
70
|
-
logger?: any;
|
|
71
|
-
logRaw?: boolean;
|
|
72
|
-
emitLogs?: boolean;
|
|
73
|
-
verifyOnly?: boolean;
|
|
74
|
-
proxy?: string;
|
|
75
|
-
qresync?: boolean;
|
|
76
|
-
maxIdleTime?: number;
|
|
77
|
-
missingIdleCommand?: string;
|
|
78
|
-
disableBinary?: boolean;
|
|
79
|
-
disableAutoEnable?: boolean;
|
|
80
|
-
connectionTimeout?: number;
|
|
81
|
-
greetingTimeout?: number;
|
|
82
|
-
socketTimeout?: number;
|
|
83
|
-
});
|
|
84
51
|
/**
|
|
85
52
|
* Current module version as a static class property
|
|
86
53
|
* @property version - Module version
|
|
@@ -130,10 +97,6 @@ declare module "imapflow" {
|
|
|
130
97
|
* Is current mailbox idling (`true`) or not (`false`)
|
|
131
98
|
*/
|
|
132
99
|
idling: boolean;
|
|
133
|
-
/**
|
|
134
|
-
* If `true` then in addition of sending data to logger, ImapFlow emits 'log' events with the same data
|
|
135
|
-
*/
|
|
136
|
-
emitLogs: boolean;
|
|
137
100
|
/**
|
|
138
101
|
* Tries to upgrade the connection to TLS using STARTTLS.
|
|
139
102
|
* @returns true, if the connection is now protected by TLS, either direct TLS or STARTTLS.
|
|
@@ -568,6 +531,117 @@ declare module "imapflow" {
|
|
|
568
531
|
getMailboxLock(path: string | any[], options?: {
|
|
569
532
|
readOnly?: boolean;
|
|
570
533
|
}): Promise<MailboxLockObject>;
|
|
534
|
+
/**
|
|
535
|
+
* Hostname of the IMAP server.
|
|
536
|
+
*/
|
|
537
|
+
host: string;
|
|
538
|
+
/**
|
|
539
|
+
* Port number for the IMAP server.
|
|
540
|
+
*/
|
|
541
|
+
port: number;
|
|
542
|
+
/**
|
|
543
|
+
* If `true`, establishes the connection directly over TLS (commonly on port 993).
|
|
544
|
+
If `false`, a plain (unencrypted) connection is used first and, if possible, the connection is upgraded to STARTTLS.
|
|
545
|
+
*/
|
|
546
|
+
secure?: boolean;
|
|
547
|
+
/**
|
|
548
|
+
* Determines whether to upgrade the connection to TLS via STARTTLS:
|
|
549
|
+
- **true**: Start unencrypted and upgrade to TLS using STARTTLS before authentication.
|
|
550
|
+
The connection fails if the server does not support STARTTLS or the upgrade fails.
|
|
551
|
+
Note that `secure=true` combined with `doSTARTTLS=true` is invalid.
|
|
552
|
+
- **false**: Never use STARTTLS, even if the server advertises support.
|
|
553
|
+
This is useful if the server has a broken TLS setup.
|
|
554
|
+
Combined with `secure=false`, this results in a fully unencrypted connection.
|
|
555
|
+
Make sure you warn users about the security risks.
|
|
556
|
+
- **undefined** (default): If `secure=false` (default), attempt to upgrade to TLS via STARTTLS before authentication if the server supports it. If not supported, continue unencrypted. This may expose the connection to a downgrade attack.
|
|
557
|
+
*/
|
|
558
|
+
doSTARTTLS?: boolean;
|
|
559
|
+
/**
|
|
560
|
+
* Server name for SNI or when using an IP address as `host`.
|
|
561
|
+
*/
|
|
562
|
+
servername?: string;
|
|
563
|
+
/**
|
|
564
|
+
* If `true`, the client does not attempt to use the COMPRESS=DEFLATE extension.
|
|
565
|
+
*/
|
|
566
|
+
disableCompression?: boolean;
|
|
567
|
+
/**
|
|
568
|
+
* Authentication options. Authentication occurs automatically during {@link connect}.
|
|
569
|
+
*/
|
|
570
|
+
auth: {
|
|
571
|
+
user: string;
|
|
572
|
+
pass?: string;
|
|
573
|
+
accessToken?: string;
|
|
574
|
+
loginMethod?: string;
|
|
575
|
+
};
|
|
576
|
+
/**
|
|
577
|
+
* Client identification info sent to the server (via the ID command).
|
|
578
|
+
*/
|
|
579
|
+
clientInfo?: IdInfoObject;
|
|
580
|
+
/**
|
|
581
|
+
* If `true`, do not start IDLE automatically. Useful when only specific operations are needed.
|
|
582
|
+
*/
|
|
583
|
+
disableAutoIdle?: boolean;
|
|
584
|
+
/**
|
|
585
|
+
* Additional TLS options. For details, see [Node.js TLS connect](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback).
|
|
586
|
+
*/
|
|
587
|
+
tls?: {
|
|
588
|
+
rejectUnauthorized?: boolean;
|
|
589
|
+
minVersion?: string;
|
|
590
|
+
minDHSize?: number;
|
|
591
|
+
};
|
|
592
|
+
/**
|
|
593
|
+
* Custom logger instance with `debug(obj)`, `info(obj)`, `warn(obj)`, and `error(obj)` methods.
|
|
594
|
+
If `false`, logging is disabled. If not provided, ImapFlow logs to console in [pino format](https://getpino.io/).
|
|
595
|
+
*/
|
|
596
|
+
logger?: any | boolean;
|
|
597
|
+
/**
|
|
598
|
+
* If `true`, logs all raw data (read and written) in base64 encoding. You can pipe such logs to [eerawlog](https://github.com/postalsys/eerawlog) command for readable output.
|
|
599
|
+
*/
|
|
600
|
+
logRaw?: boolean;
|
|
601
|
+
/**
|
|
602
|
+
* If `true`, emits `'log'` events with the same data passed to the logger.
|
|
603
|
+
*/
|
|
604
|
+
emitLogs?: boolean;
|
|
605
|
+
/**
|
|
606
|
+
* If `true`, disconnects after successful authentication without performing other actions.
|
|
607
|
+
*/
|
|
608
|
+
verifyOnly?: boolean;
|
|
609
|
+
/**
|
|
610
|
+
* Proxy URL. Supports HTTP CONNECT (`http://`, `https://`) and SOCKS (`socks://`, `socks4://`, `socks5://`).
|
|
611
|
+
*/
|
|
612
|
+
proxy?: string;
|
|
613
|
+
/**
|
|
614
|
+
* If `true`, enables QRESYNC support so that EXPUNGE notifications include `uid` instead of `seq`.
|
|
615
|
+
*/
|
|
616
|
+
qresync?: boolean;
|
|
617
|
+
/**
|
|
618
|
+
* If set, breaks and restarts IDLE every `maxIdleTime` milliseconds.
|
|
619
|
+
*/
|
|
620
|
+
maxIdleTime?: number;
|
|
621
|
+
/**
|
|
622
|
+
* Command to use if the server does not support IDLE.
|
|
623
|
+
*/
|
|
624
|
+
missingIdleCommand?: string;
|
|
625
|
+
/**
|
|
626
|
+
* If `true`, ignores the BINARY extension for FETCH and APPEND operations.
|
|
627
|
+
*/
|
|
628
|
+
disableBinary?: boolean;
|
|
629
|
+
/**
|
|
630
|
+
* If `true`, do not automatically enable supported IMAP extensions.
|
|
631
|
+
*/
|
|
632
|
+
disableAutoEnable?: boolean;
|
|
633
|
+
/**
|
|
634
|
+
* Maximum time (in milliseconds) to wait for the connection to establish. Defaults to 90 seconds.
|
|
635
|
+
*/
|
|
636
|
+
connectionTimeout?: number;
|
|
637
|
+
/**
|
|
638
|
+
* Maximum time (in milliseconds) to wait for the server greeting after a connection is established. Defaults to 16 seconds.
|
|
639
|
+
*/
|
|
640
|
+
greetingTimeout?: number;
|
|
641
|
+
/**
|
|
642
|
+
* Maximum period of inactivity (in milliseconds) before terminating the connection. Defaults to 5 minutes.
|
|
643
|
+
*/
|
|
644
|
+
socketTimeout?: number;
|
|
571
645
|
}
|
|
572
646
|
}
|
|
573
647
|
|