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 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
- if (connection.capabilities.has('AUTH=LOGIN')) {
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
- * @param {Object} options IMAP connection options
120
- * @param {String} options.host Hostname of the IMAP server
121
- * @param {Number} options.port Port number for the IMAP server
122
- * @param {Boolean} [options.secure=false] Should the connection be established immediately and directly over TLS? Typically on port 993.
123
- * @param {Boolean} [options.doSTARTTLS=undefined] Should the connection be established using STARTTLS?
124
- * * If `true`, the connection is first established as unencrypted and then upgraded to TLS using STARTTLS, before authentication.
125
- * If the server does not advertize the `STARTTLS` `CAPABILITY`, or the upgrade fails for other reasons, then the connection fails.
126
- * Note: The combination `secure=true` (direct TLS) and `doSTARTTLS=true` is invalid.
127
- * * If `false`, then STARTTLS will not be used, even if the server advertizes it in IMAP `CAPABILITY`.
128
- * This helps with servers that have a broken TLS configuration.
129
- * If `doSTARTTLS=false` and `secure=false`, then a plain unencrypted socket is used.
130
- * Be sure to clearly warn the user about the consequences.
131
- * * If `undefined` (default) and `secure=false` (default), the connection is upgraded using STARTTLS before authentication, /only if possible/ .
132
- * If not possible, the connection will use an unencrypted plain socket.
133
- * This can mean TLS is used under normal circumstances, but a serious attacker can force an unencrypted connection and steal passwords,
134
- * called "downgrade attack". This can lead to a false sense of security. Be sure to warn the user.
135
- * @param {String} [options.servername] Servername for SNI (or when host is set to an IP address)
136
- * @param {Boolean} [options.disableCompression=false] if `true` then client does not try to use COMPRESS=DEFLATE extension
137
- * @param {Object} options.auth Authentication options. Authentication is requested automatically during <code>connect()</code>
138
- * @param {String} options.auth.user Usename
139
- * @param {String} [options.auth.pass] Password, if using regular authentication
140
- * @param {String} [options.auth.accessToken] OAuth2 Access Token, if using OAuth2 authentication
141
- * @param {IdInfoObject} [options.clientInfo] Client identification info
142
- * @param {Boolean} [options.disableAutoIdle=false] if `true` then IDLE is not started automatically. Useful if you only need to perform specific tasks over the connection
143
- * @param {Object} [options.tls] Additional TLS options (see [Node.js TLS connect](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback) for all available options)
144
- * @param {Boolean} [options.tls.rejectUnauthorized=true] if `false` then client accepts self-signed and expired certificates from the server
145
- * @param {String} [options.tls.minVersion=TLSv1.2] To improvde security you might need to use something newer, eg *'TLSv1.2'*
146
- * @param {Number} [options.tls.minDHSize=1024] Minimum size of the DH parameter in bits to accept a TLS connection
147
- * @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`
148
- * @param {Boolean} [options.logRaw=false] If true then log data read from and written to socket encoded in base64
149
- * @param {Boolean} [options.emitLogs=false] If `true` then in addition of sending data to logger, ImapFlow emits 'log' events with the same data
150
- * @param {Boolean} [options.verifyOnly=false] If `true` then logs out automatically after successful authentication
151
- * @param {String} [options.proxy] Optional proxy URL. Supports HTTP CONNECT (`http://`, `https://`) and SOCKS (`socks://`, `socks4://`, `socks5://`) proxies
152
- * @param {Boolean} [options.qresync=false] If true, then enables QRESYNC support. EXPUNGE notifications will include `uid` property instead of `seq`
153
- * @param {Number} [options.maxIdleTime] If set, then breaks and restarts IDLE every maxIdleTime ms
154
- * @param {String} [options.missingIdleCommand="NOOP"] Which command to use if server does not support IDLE
155
- * @param {Boolean} [options.disableBinary=false] If true, then ignores the BINARY extension when making FETCH and APPEND calls
156
- * @param {Boolean} [options.disableAutoEnable] Do not enable supported extensions by default
157
- * @param {Number} [options.connectionTimeout=90000] how many milliseconds to wait for the connection to establish (default is 90 seconds)
158
- * @param {Number} [options.greetingTimeout=16000] how many milliseconds to wait for the greeting after connection is established (default is 16 seconds)
159
- * @param {Number} [options.socketTimeout=300000] how many milliseconds of inactivity to allow (default is 5 minutes)
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
- module.exports = {
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 module.exports.normalizePath(connection, a) === module.exports.normalizePath(connection, b);
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 = module.exports.parseEnvelope(attribute);
339
+ map.envelope = tools.parseEnvelope(attribute);
340
340
  break;
341
341
 
342
342
  case 'bodystructure':
343
- map.bodyStructure = module.exports.parseBodystructure(attribute);
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 = module.exports.getFlagColor(map.flags);
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: module.exports.processName(libmime.decodeWords(getStrValue(addr[0]))),
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 = this.getStructuredParams(node[i]);
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 = this.getStructuredParams(node[i]);
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 = module.exports.parseEnvelope([].concat(node[i] || []));
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
- } else if (/^text\//.test(curNode.type)) {
675
- // text/* adds additional line count values
674
+ }
676
675
 
677
- // line count
678
- if (node[i]) {
679
- curNode.lineCount = Number((node[i] || {}).value || 0) || 0;
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 = this.getStructuredParams(node[i][1]);
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 = module.exports.formatDate(value).replace(/^0/, ''); //starts with date-day-fixed with leading 0 replaced by SP
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 client class for accessing IMAP mailboxes
8
- * @param options - IMAP connection options
9
- * @param options.host - Hostname of the IMAP server
10
- * @param options.port - Port number for the IMAP server
11
- * @param [options.secure = false] - Should the connection be established immediately and directly over TLS? Typically on port 993.
12
- * @param [options.doSTARTTLS] - Should the connection be established using STARTTLS?
13
- * * If `true`, the connection is first established as unencrypted and then upgraded to TLS using STARTTLS, before authentication.
14
- * If the server does not advertize the `STARTTLS` `CAPABILITY`, or the upgrade fails for other reasons, then the connection fails.
15
- * Note: The combination `secure=true` (direct TLS) and `doSTARTTLS=true` is invalid.
16
- * * If `false`, then STARTTLS will not be used, even if the server advertizes it in IMAP `CAPABILITY`.
17
- * This helps with servers that have a broken TLS configuration.
18
- * If `doSTARTTLS=false` and `secure=false`, then a plain unencrypted socket is used.
19
- * Be sure to clearly warn the user about the consequences.
20
- * * If `undefined` (default) and `secure=false` (default), the connection is upgraded using STARTTLS before authentication, /only if possible/ .
21
- * If not possible, the connection will use an unencrypted plain socket.
22
- * This can mean TLS is used under normal circumstances, but a serious attacker can force an unencrypted connection and steal passwords,
23
- * called "downgrade attack". This can lead to a false sense of security. Be sure to warn the user.
24
- * @param [options.servername] - Servername for SNI (or when host is set to an IP address)
25
- * @param [options.disableCompression = false] - if `true` then client does not try to use COMPRESS=DEFLATE extension
26
- * @param options.auth - Authentication options. Authentication is requested automatically during <code>connect()</code>
27
- * @param options.auth.user - Usename
28
- * @param [options.auth.pass] - Password, if using regular authentication
29
- * @param [options.auth.accessToken] - OAuth2 Access Token, if using OAuth2 authentication
30
- * @param [options.clientInfo] - Client identification info
31
- * @param [options.disableAutoIdle = false] - if `true` then IDLE is not started automatically. Useful if you only need to perform specific tasks over the connection
32
- * @param [options.tls] - Additional TLS options (see [Node.js TLS connect](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback) for all available options)
33
- * @param [options.tls.rejectUnauthorized = true] - if `false` then client accepts self-signed and expired certificates from the server
34
- * @param [options.tls.minVersion = TLSv1.2] - To improvde security you might need to use something newer, eg *'TLSv1.2'*
35
- * @param [options.tls.minDHSize = 1024] - Minimum size of the DH parameter in bits to accept a TLS connection
36
- * @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`
37
- * @param [options.logRaw = false] - If true then log data read from and written to socket encoded in base64
38
- * @param [options.emitLogs = false] - If `true` then in addition of sending data to logger, ImapFlow emits 'log' events with the same data
39
- * @param [options.verifyOnly = false] - If `true` then logs out automatically after successful authentication
40
- * @param [options.proxy] - Optional proxy URL. Supports HTTP CONNECT (`http://`, `https://`) and SOCKS (`socks://`, `socks4://`, `socks5://`) proxies
41
- * @param [options.qresync = false] - If true, then enables QRESYNC support. EXPUNGE notifications will include `uid` property instead of `seq`
42
- * @param [options.maxIdleTime] - If set, then breaks and restarts IDLE every maxIdleTime ms
43
- * @param [options.missingIdleCommand = "NOOP"] - Which command to use if server does not support IDLE
44
- * @param [options.disableBinary = false] - If true, then ignores the BINARY extension when making FETCH and APPEND calls
45
- * @param [options.disableAutoEnable] - Do not enable supported extensions by default
46
- * @param [options.connectionTimeout = 90000] - how many milliseconds to wait for the connection to establish (default is 90 seconds)
47
- * @param [options.greetingTimeout = 16000] - how many milliseconds to wait for the greeting after connection is established (default is 16 seconds)
48
- * @param [options.socketTimeout = 300000] - how many milliseconds of inactivity to allow (default is 5 minutes)
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