imapflow 1.0.171 → 1.0.172
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 +7 -0
- package/lib/commands/authenticate.js +4 -3
- package/lib/imap-flow.js +107 -47
- package/lib/types.d.ts +153 -79
- package/package.json +3 -3
- package/test/imap-parser-test.js +177 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.172](https://github.com/postalsys/imapflow/compare/v1.0.171...v1.0.172) (2025-01-03)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **password-auth:** Added option auth.loginMethod to set specific authentication method ('LOGIN', 'AUTH=PLAIN', 'AUTH=LOGIN') ([ce3c339](https://github.com/postalsys/imapflow/commit/ce3c33908f5ad445b1a2fdcf2dfcbd4859413cf7))
|
|
9
|
+
|
|
3
10
|
## [1.0.171](https://github.com/postalsys/imapflow/compare/v1.0.170...v1.0.171) (2024-12-05)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -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/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
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "imapflow",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.172",
|
|
4
4
|
"description": "IMAP Client for Node",
|
|
5
5
|
"main": "./lib/imap-flow.js",
|
|
6
6
|
"scripts": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@babel/eslint-plugin": "7.25.9",
|
|
33
33
|
"@babel/plugin-syntax-class-properties": "7.12.13",
|
|
34
34
|
"@babel/preset-env": "7.26.0",
|
|
35
|
-
"@types/node": "22.10.
|
|
35
|
+
"@types/node": "22.10.5",
|
|
36
36
|
"eslint": "8.57.0",
|
|
37
37
|
"eslint-config-nodemailer": "1.2.0",
|
|
38
38
|
"eslint-config-prettier": "9.1.0",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"libqp": "2.1.1",
|
|
54
54
|
"mailsplit": "5.4.2",
|
|
55
55
|
"nodemailer": "6.9.16",
|
|
56
|
-
"pino": "9.
|
|
56
|
+
"pino": "9.6.0",
|
|
57
57
|
"socks": "2.8.3"
|
|
58
58
|
}
|
|
59
59
|
}
|
package/test/imap-parser-test.js
CHANGED
|
@@ -1006,7 +1006,6 @@ module.exports['IMAP Parser, subfolder square bracket'] = test =>
|
|
|
1006
1006
|
module.exports['IMAP Parser, FETCH with full range'] = test =>
|
|
1007
1007
|
asyncWrapper(test, async test => {
|
|
1008
1008
|
let parsed = await parser('* 32 FETCH (UID 32 RFC822.SIZE 3991 BODY[2.MIME] "(* 61B literal *)" BODY[2]<0.65536> "(* 6B literal *)")');
|
|
1009
|
-
console.log(JSON.stringify(parsed.attributes));
|
|
1010
1009
|
test.deepEqual(parsed.attributes, [
|
|
1011
1010
|
{
|
|
1012
1011
|
type: 'ATOM',
|
|
@@ -1061,3 +1060,180 @@ module.exports['IMAP Parser, FETCH with full range'] = test =>
|
|
|
1061
1060
|
]
|
|
1062
1061
|
]);
|
|
1063
1062
|
});
|
|
1063
|
+
|
|
1064
|
+
module.exports['IMAP Parser, FETCH with BODYSTRUCTURE'] = test =>
|
|
1065
|
+
asyncWrapper(test, async test => {
|
|
1066
|
+
let parsed = await parser(
|
|
1067
|
+
'* 1013 FETCH (UID 2986 MODSEQ (4960) BODYSTRUCTURE (("text" "plain" ("charset" "us-ascii") NIL NIL "7bit" 16 1 NIL NIL NIL NIL)("message" "rfc822" ("name" "Tellimuse Microsoft 365 Business Standard arve vaatamine.eml") NIL NIL "7bit" 370684 ("Mon, 16 Dec 2024 03:28:28 +0000" "Tellimuse Microsoft 365 Business Standard arve vaatamine" (("Microsoft" NIL "microsoft-noreply" "microsoft.com")) (("Microsoft" NIL "microsoft-noreply" "microsoft.com")) (("Microsoft" NIL "microsoft-noreply" "microsoft.com")) ((NIL NIL "andris.reinman" "gmail.com")) NIL NIL NIL "<58710631-775f-4c07-96ff-28a776f44d90@az.eastus2.microsoft.com>") ((("text" "plain" ("charset" "utf-8") NIL NIL "quoted-printable" 2866 80 NIL NIL NIL NIL)("text" "html" ("charset" "utf-8") NIL NIL "quoted-printable" 78392 1770 NIL NIL NIL NIL) "alternative" ("boundary" "=-EcWGOW6mwE+0T4lm385OWw==") NIL NIL NIL)("application" "octet-stream" ("name" "52482541500.pdf") NIL NIL "base64" 279430 NIL ("attachment" ("filename" "52482541500.pdf")) NIL NIL) "mixed" ("boundary" "=-1wJq2CLBJ6H+Zk2GPX9FKw==") NIL NIL NIL) 5580 NIL ("attachment" ("filename" "Tellimuse Microsoft 365 Business Standard arve vaatamine.eml")) NIL NIL) "mixed" ("boundary" "Apple-Mail=_F700EE9B-43B1-4EF1-95EE-CAA13391B333") NIL NIL NIL))'
|
|
1068
|
+
);
|
|
1069
|
+
|
|
1070
|
+
test.deepEqual(parsed.attributes, [
|
|
1071
|
+
{ type: 'ATOM', value: 'FETCH' },
|
|
1072
|
+
[
|
|
1073
|
+
{ type: 'ATOM', value: 'UID' },
|
|
1074
|
+
{ type: 'ATOM', value: '2986' },
|
|
1075
|
+
{ type: 'ATOM', value: 'MODSEQ' },
|
|
1076
|
+
[{ type: 'ATOM', value: '4960' }],
|
|
1077
|
+
{ type: 'ATOM', value: 'BODYSTRUCTURE' },
|
|
1078
|
+
[
|
|
1079
|
+
[
|
|
1080
|
+
{ type: 'STRING', value: 'text' },
|
|
1081
|
+
{ type: 'STRING', value: 'plain' },
|
|
1082
|
+
[
|
|
1083
|
+
{ type: 'STRING', value: 'charset' },
|
|
1084
|
+
{ type: 'STRING', value: 'us-ascii' }
|
|
1085
|
+
],
|
|
1086
|
+
null,
|
|
1087
|
+
null,
|
|
1088
|
+
{ type: 'STRING', value: '7bit' },
|
|
1089
|
+
{ type: 'ATOM', value: '16' },
|
|
1090
|
+
{ type: 'ATOM', value: '1' },
|
|
1091
|
+
null,
|
|
1092
|
+
null,
|
|
1093
|
+
null,
|
|
1094
|
+
null
|
|
1095
|
+
],
|
|
1096
|
+
[
|
|
1097
|
+
{ type: 'STRING', value: 'message' },
|
|
1098
|
+
{ type: 'STRING', value: 'rfc822' },
|
|
1099
|
+
[
|
|
1100
|
+
{ type: 'STRING', value: 'name' },
|
|
1101
|
+
{ type: 'STRING', value: 'Tellimuse Microsoft 365 Business Standard arve vaatamine.eml' }
|
|
1102
|
+
],
|
|
1103
|
+
null,
|
|
1104
|
+
null,
|
|
1105
|
+
{ type: 'STRING', value: '7bit' },
|
|
1106
|
+
{ type: 'ATOM', value: '370684' },
|
|
1107
|
+
[
|
|
1108
|
+
{ type: 'STRING', value: 'Mon, 16 Dec 2024 03:28:28 +0000' },
|
|
1109
|
+
{ type: 'STRING', value: 'Tellimuse Microsoft 365 Business Standard arve vaatamine' },
|
|
1110
|
+
[
|
|
1111
|
+
[
|
|
1112
|
+
{ type: 'STRING', value: 'Microsoft' },
|
|
1113
|
+
null,
|
|
1114
|
+
{ type: 'STRING', value: 'microsoft-noreply' },
|
|
1115
|
+
{ type: 'STRING', value: 'microsoft.com' }
|
|
1116
|
+
]
|
|
1117
|
+
],
|
|
1118
|
+
[
|
|
1119
|
+
[
|
|
1120
|
+
{ type: 'STRING', value: 'Microsoft' },
|
|
1121
|
+
null,
|
|
1122
|
+
{ type: 'STRING', value: 'microsoft-noreply' },
|
|
1123
|
+
{ type: 'STRING', value: 'microsoft.com' }
|
|
1124
|
+
]
|
|
1125
|
+
],
|
|
1126
|
+
[
|
|
1127
|
+
[
|
|
1128
|
+
{ type: 'STRING', value: 'Microsoft' },
|
|
1129
|
+
null,
|
|
1130
|
+
{ type: 'STRING', value: 'microsoft-noreply' },
|
|
1131
|
+
{ type: 'STRING', value: 'microsoft.com' }
|
|
1132
|
+
]
|
|
1133
|
+
],
|
|
1134
|
+
[[null, null, { type: 'STRING', value: 'andris.reinman' }, { type: 'STRING', value: 'gmail.com' }]],
|
|
1135
|
+
null,
|
|
1136
|
+
null,
|
|
1137
|
+
null,
|
|
1138
|
+
{ type: 'STRING', value: '<58710631-775f-4c07-96ff-28a776f44d90@az.eastus2.microsoft.com>' }
|
|
1139
|
+
],
|
|
1140
|
+
[
|
|
1141
|
+
[
|
|
1142
|
+
[
|
|
1143
|
+
{ type: 'STRING', value: 'text' },
|
|
1144
|
+
{ type: 'STRING', value: 'plain' },
|
|
1145
|
+
[
|
|
1146
|
+
{ type: 'STRING', value: 'charset' },
|
|
1147
|
+
{ type: 'STRING', value: 'utf-8' }
|
|
1148
|
+
],
|
|
1149
|
+
null,
|
|
1150
|
+
null,
|
|
1151
|
+
{ type: 'STRING', value: 'quoted-printable' },
|
|
1152
|
+
{ type: 'ATOM', value: '2866' },
|
|
1153
|
+
{ type: 'ATOM', value: '80' },
|
|
1154
|
+
null,
|
|
1155
|
+
null,
|
|
1156
|
+
null,
|
|
1157
|
+
null
|
|
1158
|
+
],
|
|
1159
|
+
[
|
|
1160
|
+
{ type: 'STRING', value: 'text' },
|
|
1161
|
+
{ type: 'STRING', value: 'html' },
|
|
1162
|
+
[
|
|
1163
|
+
{ type: 'STRING', value: 'charset' },
|
|
1164
|
+
{ type: 'STRING', value: 'utf-8' }
|
|
1165
|
+
],
|
|
1166
|
+
null,
|
|
1167
|
+
null,
|
|
1168
|
+
{ type: 'STRING', value: 'quoted-printable' },
|
|
1169
|
+
{ type: 'ATOM', value: '78392' },
|
|
1170
|
+
{ type: 'ATOM', value: '1770' },
|
|
1171
|
+
null,
|
|
1172
|
+
null,
|
|
1173
|
+
null,
|
|
1174
|
+
null
|
|
1175
|
+
],
|
|
1176
|
+
{ type: 'STRING', value: 'alternative' },
|
|
1177
|
+
[
|
|
1178
|
+
{ type: 'STRING', value: 'boundary' },
|
|
1179
|
+
{ type: 'STRING', value: '=-EcWGOW6mwE+0T4lm385OWw==' }
|
|
1180
|
+
],
|
|
1181
|
+
null,
|
|
1182
|
+
null,
|
|
1183
|
+
null
|
|
1184
|
+
],
|
|
1185
|
+
[
|
|
1186
|
+
{ type: 'STRING', value: 'application' },
|
|
1187
|
+
{ type: 'STRING', value: 'octet-stream' },
|
|
1188
|
+
[
|
|
1189
|
+
{ type: 'STRING', value: 'name' },
|
|
1190
|
+
{ type: 'STRING', value: '52482541500.pdf' }
|
|
1191
|
+
],
|
|
1192
|
+
null,
|
|
1193
|
+
null,
|
|
1194
|
+
{ type: 'STRING', value: 'base64' },
|
|
1195
|
+
{ type: 'ATOM', value: '279430' },
|
|
1196
|
+
null,
|
|
1197
|
+
[
|
|
1198
|
+
{ type: 'STRING', value: 'attachment' },
|
|
1199
|
+
[
|
|
1200
|
+
{ type: 'STRING', value: 'filename' },
|
|
1201
|
+
{ type: 'STRING', value: '52482541500.pdf' }
|
|
1202
|
+
]
|
|
1203
|
+
],
|
|
1204
|
+
null,
|
|
1205
|
+
null
|
|
1206
|
+
],
|
|
1207
|
+
{ type: 'STRING', value: 'mixed' },
|
|
1208
|
+
[
|
|
1209
|
+
{ type: 'STRING', value: 'boundary' },
|
|
1210
|
+
{ type: 'STRING', value: '=-1wJq2CLBJ6H+Zk2GPX9FKw==' }
|
|
1211
|
+
],
|
|
1212
|
+
null,
|
|
1213
|
+
null,
|
|
1214
|
+
null
|
|
1215
|
+
],
|
|
1216
|
+
{ type: 'ATOM', value: '5580' },
|
|
1217
|
+
null,
|
|
1218
|
+
[
|
|
1219
|
+
{ type: 'STRING', value: 'attachment' },
|
|
1220
|
+
[
|
|
1221
|
+
{ type: 'STRING', value: 'filename' },
|
|
1222
|
+
{ type: 'STRING', value: 'Tellimuse Microsoft 365 Business Standard arve vaatamine.eml' }
|
|
1223
|
+
]
|
|
1224
|
+
],
|
|
1225
|
+
null,
|
|
1226
|
+
null
|
|
1227
|
+
],
|
|
1228
|
+
{ type: 'STRING', value: 'mixed' },
|
|
1229
|
+
[
|
|
1230
|
+
{ type: 'STRING', value: 'boundary' },
|
|
1231
|
+
{ type: 'STRING', value: 'Apple-Mail=_F700EE9B-43B1-4EF1-95EE-CAA13391B333' }
|
|
1232
|
+
],
|
|
1233
|
+
null,
|
|
1234
|
+
null,
|
|
1235
|
+
null
|
|
1236
|
+
]
|
|
1237
|
+
]
|
|
1238
|
+
]);
|
|
1239
|
+
});
|