imapflow 2.0.0 → 2.0.2
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/dist/cjs/commands/list.js +4 -2
- package/dist/cjs/imap-flow.js +9 -1
- package/dist/cjs/package-info.d.ts +1 -1
- package/dist/cjs/package-info.js +1 -1
- package/dist/cjs/types.d.ts +1 -1
- package/dist/esm/commands/list.js +4 -2
- package/dist/esm/imap-flow.js +10 -2
- package/dist/esm/package-info.d.ts +1 -1
- package/dist/esm/package-info.js +1 -1
- package/dist/esm/types.d.ts +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.0.2](https://github.com/postalsys/imapflow/compare/v2.0.1...v2.0.2) (2026-09-10)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* skip LSUB once a server has rejected ENABLE over the IMAP4rev2 it advertises ([1c4bca2](https://github.com/postalsys/imapflow/commit/1c4bca2349ed05d5cb61a85abb4152630ceb3d73))
|
|
9
|
+
|
|
10
|
+
## [2.0.1](https://github.com/postalsys/imapflow/compare/v2.0.0...v2.0.1) (2026-09-10)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* stop acting on an IMAP4rev2 advertisement once the server rejects ENABLE over it ([227355f](https://github.com/postalsys/imapflow/commit/227355fee56a10913af8feb8e52a74364eb90ca2))
|
|
16
|
+
|
|
3
17
|
## [2.0.0](https://github.com/postalsys/imapflow/compare/v1.7.8...v2.0.0) (2026-09-07)
|
|
4
18
|
|
|
5
19
|
|
|
@@ -53,8 +53,10 @@ async function list(connection, reference, mailbox, options) {
|
|
|
53
53
|
// advertisement alone (not hasCapability/isRev2Active): the staged retry below
|
|
54
54
|
// handles servers that advertise but reject RETURN options, so the wider gate
|
|
55
55
|
// is safe for anything it covers, while gates without a retry ladder stay
|
|
56
|
-
// conservative.
|
|
57
|
-
|
|
56
|
+
// conservative. The rev2 advertisement stops counting once the session has
|
|
57
|
+
// been told not to act on it (skipRev2), because the ladder costs one rejected
|
|
58
|
+
// command per stage and a server that has disowned rev2 may not grant that many.
|
|
59
|
+
let supportsExtendedList = connection.capabilities.has('LIST-EXTENDED') || (connection.capabilities.has('IMAP4rev2') && !connection.skipRev2);
|
|
58
60
|
// RETURN options for the LIST command. Servers occasionally advertise the
|
|
59
61
|
// extensions but still reject RETURN options - the staged retry below then
|
|
60
62
|
// re-runs the LIST with fewer options and latches a skip flag for the option
|
package/dist/cjs/imap-flow.js
CHANGED
|
@@ -290,6 +290,7 @@ class ImapFlow extends node_events_1.EventEmitter {
|
|
|
290
290
|
this.skipListStatusArgs = false;
|
|
291
291
|
this.skipListAuxArgs = false;
|
|
292
292
|
this.skipLsub = false;
|
|
293
|
+
this.skipRev2 = !!this.options.disableIMAP4rev2;
|
|
293
294
|
// Named error handler for proper cleanup. Certain error codes represent
|
|
294
295
|
// expected socket/network issues (buffer exhaustion, connection reset, broken pipe,
|
|
295
296
|
// timeout, unreachable host) that just need a silent connection close rather
|
|
@@ -1190,9 +1191,16 @@ class ImapFlow extends node_events_1.EventEmitter {
|
|
|
1190
1191
|
// ENABLE call is used so the enabled set is built in one round trip.
|
|
1191
1192
|
/** @internal */
|
|
1192
1193
|
async autoEnable() {
|
|
1193
|
-
let enableList = ['CONDSTORE', 'UTF8=ACCEPT'].concat(this.options.qresync ? 'QRESYNC' : []).concat(this.
|
|
1194
|
+
let enableList = ['CONDSTORE', 'UTF8=ACCEPT'].concat(this.options.qresync ? 'QRESYNC' : []).concat(this.skipRev2 ? [] : 'IMAP4rev2');
|
|
1194
1195
|
let enableResult = await this.run('ENABLE', enableList);
|
|
1195
1196
|
if (enableResult === false && enableList.includes('IMAP4rev2')) {
|
|
1197
|
+
if (this.capabilities.has('IMAP4rev2') && !(0, tools_js_1.isRev2Active)(this)) {
|
|
1198
|
+
// The one command that would have made this a rev2 session was
|
|
1199
|
+
// rejected, so it stays an IMAP4rev1 session (RFC 9051 Appendix A)
|
|
1200
|
+
// with an advertisement the server does not implement - see skipRev2
|
|
1201
|
+
this.skipRev2 = true;
|
|
1202
|
+
this.skipLsub = true;
|
|
1203
|
+
}
|
|
1196
1204
|
// RFC 5161 requires servers to ignore unknown ENABLE arguments, but a
|
|
1197
1205
|
// broken implementation may reject the whole command over IMAP4rev2 -
|
|
1198
1206
|
// retry without it so CONDSTORE/QRESYNC are not lost as collateral
|
package/dist/cjs/package-info.js
CHANGED
package/dist/cjs/types.d.ts
CHANGED
|
@@ -97,7 +97,7 @@ export interface ImapFlowOptions {
|
|
|
97
97
|
disableBinary?: boolean | undefined;
|
|
98
98
|
/** If true, do not enable supported extensions */
|
|
99
99
|
disableAutoEnable?: boolean | undefined;
|
|
100
|
-
/** If true, do not enable IMAP4rev2 mode even if the server
|
|
100
|
+
/** If true, do not enable IMAP4rev2 mode even if the server advertises it, and do not treat the advertisement as support for anything IMAP4rev2 implies, such as the extended LIST syntax */
|
|
101
101
|
disableIMAP4rev2?: boolean | undefined;
|
|
102
102
|
/**
|
|
103
103
|
* How long to wait for a usable transport, covering DNS resolution, proxy negotiation and the
|
|
@@ -50,8 +50,10 @@ export default async function list(connection, reference, mailbox, options) {
|
|
|
50
50
|
// advertisement alone (not hasCapability/isRev2Active): the staged retry below
|
|
51
51
|
// handles servers that advertise but reject RETURN options, so the wider gate
|
|
52
52
|
// is safe for anything it covers, while gates without a retry ladder stay
|
|
53
|
-
// conservative.
|
|
54
|
-
|
|
53
|
+
// conservative. The rev2 advertisement stops counting once the session has
|
|
54
|
+
// been told not to act on it (skipRev2), because the ladder costs one rejected
|
|
55
|
+
// command per stage and a server that has disowned rev2 may not grant that many.
|
|
56
|
+
let supportsExtendedList = connection.capabilities.has('LIST-EXTENDED') || (connection.capabilities.has('IMAP4rev2') && !connection.skipRev2);
|
|
55
57
|
// RETURN options for the LIST command. Servers occasionally advertise the
|
|
56
58
|
// extensions but still reject RETURN options - the staged retry below then
|
|
57
59
|
// re-runs the LIST with fewer options and latches a skip flag for the option
|
package/dist/esm/imap-flow.js
CHANGED
|
@@ -21,7 +21,7 @@ import { proxyConnection, detachEarlyErrorHandler } from './proxy-connection.js'
|
|
|
21
21
|
import { ConnectionDeadline } from './connection-deadline.js';
|
|
22
22
|
import { AuthenticationFailure } from './errors.js';
|
|
23
23
|
import imapCommands from './imap-commands.js';
|
|
24
|
-
import { comparePaths, updateCapabilities, getFolderTree, formatMessageResponse, getDecoder, packMessageRange, normalizePath, expandRange, getColorFlags, hasCapability, logConnectionError, unrefTimer, clearTimer, parseUintValue, isUnsafeKey, getStringList, buildConnectionError, guardedPromise, guardedReject, MAX_UINT32_DIGITS } from './tools.js';
|
|
24
|
+
import { comparePaths, updateCapabilities, getFolderTree, formatMessageResponse, getDecoder, packMessageRange, normalizePath, expandRange, getColorFlags, hasCapability, isRev2Active, logConnectionError, unrefTimer, clearTimer, parseUintValue, isUnsafeKey, getStringList, buildConnectionError, guardedPromise, guardedReject, MAX_UINT32_DIGITS } from './tools.js';
|
|
25
25
|
export { AuthenticationFailure } from './errors.js';
|
|
26
26
|
const GREETING_TIMEOUT = 16 * 1000;
|
|
27
27
|
const UPGRADE_TIMEOUT = 10 * 1000;
|
|
@@ -250,6 +250,7 @@ export class ImapFlow extends EventEmitter {
|
|
|
250
250
|
this.skipListStatusArgs = false;
|
|
251
251
|
this.skipListAuxArgs = false;
|
|
252
252
|
this.skipLsub = false;
|
|
253
|
+
this.skipRev2 = !!this.options.disableIMAP4rev2;
|
|
253
254
|
// Named error handler for proper cleanup. Certain error codes represent
|
|
254
255
|
// expected socket/network issues (buffer exhaustion, connection reset, broken pipe,
|
|
255
256
|
// timeout, unreachable host) that just need a silent connection close rather
|
|
@@ -1150,9 +1151,16 @@ export class ImapFlow extends EventEmitter {
|
|
|
1150
1151
|
// ENABLE call is used so the enabled set is built in one round trip.
|
|
1151
1152
|
/** @internal */
|
|
1152
1153
|
async autoEnable() {
|
|
1153
|
-
let enableList = ['CONDSTORE', 'UTF8=ACCEPT'].concat(this.options.qresync ? 'QRESYNC' : []).concat(this.
|
|
1154
|
+
let enableList = ['CONDSTORE', 'UTF8=ACCEPT'].concat(this.options.qresync ? 'QRESYNC' : []).concat(this.skipRev2 ? [] : 'IMAP4rev2');
|
|
1154
1155
|
let enableResult = await this.run('ENABLE', enableList);
|
|
1155
1156
|
if (enableResult === false && enableList.includes('IMAP4rev2')) {
|
|
1157
|
+
if (this.capabilities.has('IMAP4rev2') && !isRev2Active(this)) {
|
|
1158
|
+
// The one command that would have made this a rev2 session was
|
|
1159
|
+
// rejected, so it stays an IMAP4rev1 session (RFC 9051 Appendix A)
|
|
1160
|
+
// with an advertisement the server does not implement - see skipRev2
|
|
1161
|
+
this.skipRev2 = true;
|
|
1162
|
+
this.skipLsub = true;
|
|
1163
|
+
}
|
|
1156
1164
|
// RFC 5161 requires servers to ignore unknown ENABLE arguments, but a
|
|
1157
1165
|
// broken implementation may reject the whole command over IMAP4rev2 -
|
|
1158
1166
|
// retry without it so CONDSTORE/QRESYNC are not lost as collateral
|
package/dist/esm/package-info.js
CHANGED
package/dist/esm/types.d.ts
CHANGED
|
@@ -97,7 +97,7 @@ export interface ImapFlowOptions {
|
|
|
97
97
|
disableBinary?: boolean | undefined;
|
|
98
98
|
/** If true, do not enable supported extensions */
|
|
99
99
|
disableAutoEnable?: boolean | undefined;
|
|
100
|
-
/** If true, do not enable IMAP4rev2 mode even if the server
|
|
100
|
+
/** If true, do not enable IMAP4rev2 mode even if the server advertises it, and do not treat the advertisement as support for anything IMAP4rev2 implies, such as the extended LIST syntax */
|
|
101
101
|
disableIMAP4rev2?: boolean | undefined;
|
|
102
102
|
/**
|
|
103
103
|
* How long to wait for a usable transport, covering DNS resolution, proxy negotiation and the
|