imapflow 1.0.98 → 1.0.101
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 +8 -0
- package/README.md +4 -2
- package/lib/commands/append.js +24 -0
- package/lib/commands/list.js +7 -1
- package/lib/commands/status.js +10 -0
- package/lib/imap-flow.js +17 -3
- package/lib/search-compiler.js +4 -0
- package/lib/types.d.ts +1 -1
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
- 1.0.100 - 2022-06-17
|
|
4
|
+
|
|
5
|
+
- Emit new message notification if appending to currently opened folder
|
|
6
|
+
|
|
7
|
+
- 1.0.99 - 2022-06-05
|
|
8
|
+
|
|
9
|
+
- Check if folder exists on failed status command
|
|
10
|
+
|
|
3
11
|
- 1.0.98 - 2022-05-30
|
|
4
12
|
|
|
5
13
|
- Fixed an issue with envelope parsing where literal values were returned as Buffers
|
package/README.md
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
# ImapFlow
|
|
2
2
|
|
|
3
|
+
ImapFlow is a modern and easy-to-use IMAP client library for Node.js.
|
|
4
|
+
|
|
3
5
|
---
|
|
4
6
|
|
|
5
|
-
> Managing IMAP
|
|
7
|
+
> Managing an IMAP connection is cool, but if you are only looking for an easy way to integrate email accounts, then ImapFlow was built for [EmailEngine Email API](https://emailengine.app/). It's a self-hosted software that converts all IMAP accounts to easy-to-use REST interfaces.
|
|
6
8
|
|
|
7
9
|
---
|
|
8
10
|
|
|
9
11
|
The focus for ImapFlow is to provide easy to use API over IMAP. Using ImapFlow does not expect knowledge about specific IMAP details. A general understanding is good enough.
|
|
10
12
|
|
|
11
|
-
IMAP extensions are handled in the background, so for example, you can always request `labels` value from a {@link FetchQueryObject|fetch()} call, but if the IMAP server does not support `X-GM-EXT1` extension, then `labels` value is not included in the response.
|
|
13
|
+
IMAP extensions are handled in the background, so, for example, you can always request `labels` value from a {@link FetchQueryObject|fetch()} call, but if the IMAP server does not support `X-GM-EXT1` extension, then `labels` value is not included in the response.
|
|
12
14
|
|
|
13
15
|
## Source
|
|
14
16
|
|
package/lib/commands/append.js
CHANGED
|
@@ -62,6 +62,18 @@ module.exports = async (connection, destination, content, flags, idate) => {
|
|
|
62
62
|
? {
|
|
63
63
|
EXISTS: async untagged => {
|
|
64
64
|
map.seq = Number(untagged.command);
|
|
65
|
+
|
|
66
|
+
if (expectExists) {
|
|
67
|
+
let prevCount = connection.mailbox.exists;
|
|
68
|
+
if (map.seq !== prevCount) {
|
|
69
|
+
connection.mailbox.exists = map.seq;
|
|
70
|
+
connection.emit('exists', {
|
|
71
|
+
path: connection.mailbox.path,
|
|
72
|
+
count: map.seq,
|
|
73
|
+
prevCount
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
65
77
|
}
|
|
66
78
|
}
|
|
67
79
|
: false
|
|
@@ -95,6 +107,18 @@ module.exports = async (connection, destination, content, flags, idate) => {
|
|
|
95
107
|
untagged: {
|
|
96
108
|
EXISTS: async untagged => {
|
|
97
109
|
map.seq = Number(untagged.command);
|
|
110
|
+
|
|
111
|
+
if (expectExists) {
|
|
112
|
+
let prevCount = connection.mailbox.exists;
|
|
113
|
+
if (map.seq !== prevCount) {
|
|
114
|
+
connection.mailbox.exists = map.seq;
|
|
115
|
+
connection.emit('exists', {
|
|
116
|
+
path: connection.mailbox.path,
|
|
117
|
+
count: map.seq,
|
|
118
|
+
prevCount
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
98
122
|
}
|
|
99
123
|
},
|
|
100
124
|
comment: 'Sequence not found from APPEND output'
|
package/lib/commands/list.js
CHANGED
|
@@ -4,7 +4,9 @@ const { decodePath, encodePath, normalizePath } = require('../tools.js');
|
|
|
4
4
|
const { specialUse } = require('../special-use');
|
|
5
5
|
|
|
6
6
|
// Lists mailboxes from server
|
|
7
|
-
module.exports = async (connection, reference, mailbox) => {
|
|
7
|
+
module.exports = async (connection, reference, mailbox, options) => {
|
|
8
|
+
options = options || {};
|
|
9
|
+
|
|
8
10
|
let listCommand = connection.capabilities.has('XLIST') && !connection.capabilities.has('SPECIAL-USE') ? 'XLIST' : 'LIST';
|
|
9
11
|
|
|
10
12
|
let response;
|
|
@@ -64,6 +66,10 @@ module.exports = async (connection, reference, mailbox) => {
|
|
|
64
66
|
let normalizedReference = normalizePath(connection, reference || '');
|
|
65
67
|
await runList(normalizedReference, normalizePath(connection, mailbox || '', true));
|
|
66
68
|
|
|
69
|
+
if (options.listOnly) {
|
|
70
|
+
return entries;
|
|
71
|
+
}
|
|
72
|
+
|
|
67
73
|
if (normalizedReference && !entries.find(entry => entry.specialUse === '\\Inbox')) {
|
|
68
74
|
// INBOX was most probably not included in the listing if namespace was used
|
|
69
75
|
await runList('', 'INBOX');
|
package/lib/commands/status.js
CHANGED
|
@@ -126,6 +126,16 @@ module.exports = async (connection, path, query) => {
|
|
|
126
126
|
response.next();
|
|
127
127
|
return map;
|
|
128
128
|
} catch (err) {
|
|
129
|
+
if (err.responseStatus === 'NO') {
|
|
130
|
+
let folders = await connection.run('LIST', '', path, { listOnly: true });
|
|
131
|
+
if (folders && !folders.length) {
|
|
132
|
+
let error = new Error(`Mailbox doesn't exist: ${path}`);
|
|
133
|
+
error.code = 'NotFound';
|
|
134
|
+
error.response = err;
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
129
139
|
connection.log.warn({ err, cid: connection.id });
|
|
130
140
|
return false;
|
|
131
141
|
}
|
package/lib/imap-flow.js
CHANGED
|
@@ -121,7 +121,7 @@ class ImapFlow extends EventEmitter {
|
|
|
121
121
|
* @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
|
|
122
122
|
* @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)
|
|
123
123
|
* @param {Boolean} [options.tls.rejectUnauthorized=true] if `false` then client accepts self-signed and expired certificates from the server
|
|
124
|
-
* @param {String} [options.tls.minVersion=TLSv1
|
|
124
|
+
* @param {String} [options.tls.minVersion=TLSv1] To improvde security you might need to use something newer, eg *'TLSv1.2'*
|
|
125
125
|
* @param {Number} [options.tls.minDHSize=1024] Minimum size of the DH parameter in bits to accept a TLS connection
|
|
126
126
|
* @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
|
|
127
127
|
* @param {Boolean} [options.logRaw=false] If true then log data read from and written to socket encoded in base64
|
|
@@ -731,7 +731,8 @@ class ImapFlow extends EventEmitter {
|
|
|
731
731
|
socket: this.socket,
|
|
732
732
|
servername: this.servername,
|
|
733
733
|
port: this.port,
|
|
734
|
-
minVersion: 'TLSv1'
|
|
734
|
+
minVersion: 'TLSv1',
|
|
735
|
+
minDHSize: 1024
|
|
735
736
|
},
|
|
736
737
|
this.options.tls || {}
|
|
737
738
|
);
|
|
@@ -1140,7 +1141,8 @@ class ImapFlow extends EventEmitter {
|
|
|
1140
1141
|
host: this.host,
|
|
1141
1142
|
servername: this.servername,
|
|
1142
1143
|
port: this.port,
|
|
1143
|
-
minVersion: 'TLSv1'
|
|
1144
|
+
minVersion: 'TLSv1',
|
|
1145
|
+
minDHSize: 1024
|
|
1144
1146
|
},
|
|
1145
1147
|
this.options.tls || {}
|
|
1146
1148
|
);
|
|
@@ -2501,6 +2503,17 @@ class ImapFlow extends EventEmitter {
|
|
|
2501
2503
|
this.currentLockId = lockId;
|
|
2502
2504
|
return resolve({ path, release });
|
|
2503
2505
|
} catch (err) {
|
|
2506
|
+
if (err.responseStatus === 'NO') {
|
|
2507
|
+
try {
|
|
2508
|
+
let folders = await this.run('LIST', '', path, { listOnly: true });
|
|
2509
|
+
if (!folders || !folders.length) {
|
|
2510
|
+
err.mailboxMissing = true;
|
|
2511
|
+
}
|
|
2512
|
+
} catch (E) {
|
|
2513
|
+
this.log.trace({ msg: 'Failed to verify failed mailbox', path, err: E });
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2504
2517
|
this.log.trace({ msg: 'Failed to acquire mailbox lock', path, lockId });
|
|
2505
2518
|
reject(err);
|
|
2506
2519
|
await this.processLocks(true);
|
|
@@ -2531,6 +2544,7 @@ class ImapFlow extends EventEmitter {
|
|
|
2531
2544
|
*/
|
|
2532
2545
|
async getMailboxLock(path, options) {
|
|
2533
2546
|
options = options || {};
|
|
2547
|
+
|
|
2534
2548
|
path = normalizePath(this, path);
|
|
2535
2549
|
|
|
2536
2550
|
let lockId = ++this.lockCounter;
|
package/lib/search-compiler.js
CHANGED
|
@@ -120,6 +120,10 @@ module.exports.searchCompiler = (connection, query) => {
|
|
|
120
120
|
case 'GMRAW':
|
|
121
121
|
if (connection.capabilities.has('X-GM-EXT-1')) {
|
|
122
122
|
setOpt(attributes, 'X-GM-RAW', params[term]);
|
|
123
|
+
} else {
|
|
124
|
+
let error = new Error('Server does not support X-GM-EXT-1 extension required for X-GM-RAW');
|
|
125
|
+
error.code = 'MissingServerExtension';
|
|
126
|
+
throw error;
|
|
123
127
|
}
|
|
124
128
|
break;
|
|
125
129
|
|
package/lib/types.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ declare module "imapflow" {
|
|
|
20
20
|
* @param [options.disableAutoIdle = false] - if `true` then IDLE is not started automatically. Useful if you only need to perform specific tasks over the connection
|
|
21
21
|
* @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)
|
|
22
22
|
* @param [options.tls.rejectUnauthorized = true] - if `false` then client accepts self-signed and expired certificates from the server
|
|
23
|
-
* @param [options.tls.minVersion = TLSv1
|
|
23
|
+
* @param [options.tls.minVersion = TLSv1] - To improvde security you might need to use something newer, eg *'TLSv1.2'*
|
|
24
24
|
* @param [options.tls.minDHSize = 1024] - Minimum size of the DH parameter in bits to accept a TLS connection
|
|
25
25
|
* @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
|
|
26
26
|
* @param [options.logRaw = false] - If true then log data read from and written to socket encoded in base64
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "imapflow",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.101",
|
|
4
4
|
"description": "IMAP Client for Node",
|
|
5
5
|
"main": "./lib/imap-flow.js",
|
|
6
6
|
"scripts": {
|
|
@@ -27,20 +27,20 @@
|
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://imapflow.com/",
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@babel/eslint-parser": "7.18.
|
|
31
|
-
"@babel/eslint-plugin": "7.
|
|
30
|
+
"@babel/eslint-parser": "7.18.9",
|
|
31
|
+
"@babel/eslint-plugin": "7.18.10",
|
|
32
32
|
"@babel/plugin-syntax-class-properties": "7.12.13",
|
|
33
|
-
"@babel/preset-env": "7.18.
|
|
34
|
-
"@types/node": "
|
|
33
|
+
"@babel/preset-env": "7.18.10",
|
|
34
|
+
"@types/node": "18.6.5",
|
|
35
35
|
"braintree-jsdoc-template": "3.3.0",
|
|
36
|
-
"eslint": "8.
|
|
36
|
+
"eslint": "8.21.0",
|
|
37
37
|
"eslint-config-nodemailer": "1.2.0",
|
|
38
38
|
"eslint-config-prettier": "8.5.0",
|
|
39
39
|
"grunt": "1.5.3",
|
|
40
40
|
"grunt-cli": "1.4.3",
|
|
41
41
|
"grunt-contrib-nodeunit": "4.0.0",
|
|
42
42
|
"grunt-eslint": "24.0.0",
|
|
43
|
-
"jsdoc": "3.6.
|
|
43
|
+
"jsdoc": "3.6.11",
|
|
44
44
|
"st": "3.0.0",
|
|
45
45
|
"tsd-jsdoc": "2.5.0"
|
|
46
46
|
},
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"libmime": "5.1.0",
|
|
52
52
|
"libqp": "1.1.0",
|
|
53
53
|
"mailsplit": "5.3.2",
|
|
54
|
-
"nodemailer": "6.7.
|
|
55
|
-
"pino": "
|
|
56
|
-
"socks": "2.
|
|
54
|
+
"nodemailer": "6.7.7",
|
|
55
|
+
"pino": "8.4.0",
|
|
56
|
+
"socks": "2.7.0"
|
|
57
57
|
}
|
|
58
58
|
}
|