mirror of
https://github.com/nodemailer/wildduck.git
synced 2024-09-20 15:26:03 +08:00
allow to set user specific IMAP max connections
This commit is contained in:
parent
01463cf386
commit
39bd87ebaa
|
@ -352,6 +352,7 @@ module.exports = (db, server, userHandler) => {
|
||||||
* @apiParam {Number} [imapMaxUpload] How many bytes can be uploaded via IMAP during 24 hour
|
* @apiParam {Number} [imapMaxUpload] How many bytes can be uploaded via IMAP during 24 hour
|
||||||
* @apiParam {Number} [imapMaxDownload] How many bytes can be downloaded via IMAP during 24 hour
|
* @apiParam {Number} [imapMaxDownload] How many bytes can be downloaded via IMAP during 24 hour
|
||||||
* @apiParam {Number} [pop3MaxDownload] How many bytes can be downloaded via POP3 during 24 hour
|
* @apiParam {Number} [pop3MaxDownload] How many bytes can be downloaded via POP3 during 24 hour
|
||||||
|
* @apiParam {Number} [imapMaxConnections] How many parallel IMAP connections are alowed
|
||||||
* @apiParam {Number} [receivedMax] How many messages can be received from MX during 60 seconds
|
* @apiParam {Number} [receivedMax] How many messages can be received from MX during 60 seconds
|
||||||
* @apiParam {Object} [mailboxes] Optional names for special mailboxes
|
* @apiParam {Object} [mailboxes] Optional names for special mailboxes
|
||||||
* @apiParam {String} [mailboxes.sent="Sent Mail"] Path of Sent Mail folder
|
* @apiParam {String} [mailboxes.sent="Sent Mail"] Path of Sent Mail folder
|
||||||
|
@ -486,6 +487,9 @@ module.exports = (db, server, userHandler) => {
|
||||||
pop3MaxDownload: Joi.number()
|
pop3MaxDownload: Joi.number()
|
||||||
.min(0)
|
.min(0)
|
||||||
.default(0),
|
.default(0),
|
||||||
|
imapMaxConnections: Joi.number()
|
||||||
|
.min(0)
|
||||||
|
.default(0),
|
||||||
receivedMax: Joi.number()
|
receivedMax: Joi.number()
|
||||||
.min(0)
|
.min(0)
|
||||||
.default(0),
|
.default(0),
|
||||||
|
@ -909,6 +913,8 @@ module.exports = (db, server, userHandler) => {
|
||||||
* @apiSuccess {Number} limits.pop3Download.allowed How many bytes per 24 hours can be downloaded via POP3. Only message contents are counted, not protocol overhead.
|
* @apiSuccess {Number} limits.pop3Download.allowed How many bytes per 24 hours can be downloaded via POP3. Only message contents are counted, not protocol overhead.
|
||||||
* @apiSuccess {Number} limits.pop3Download.used How many bytes are downloaded during current 24 hour period
|
* @apiSuccess {Number} limits.pop3Download.used How many bytes are downloaded during current 24 hour period
|
||||||
* @apiSuccess {Number} limits.pop3Download.ttl Time until the end of current 24 hour period
|
* @apiSuccess {Number} limits.pop3Download.ttl Time until the end of current 24 hour period
|
||||||
|
* @apiSuccess {Number} limits.imapMaxConnections.allowed How many parallel IMAP connections are permitted
|
||||||
|
* @apiSuccess {Number} limits.imapMaxConnections.used How many parallel IMAP connections are currenlty in use
|
||||||
*
|
*
|
||||||
* @apiSuccess {String[]} tags List of tags associated with the User
|
* @apiSuccess {String[]} tags List of tags associated with the User
|
||||||
* @apiSuccess {String[]} disabledScopes Disabled scopes for this user
|
* @apiSuccess {String[]} disabledScopes Disabled scopes for this user
|
||||||
|
@ -1062,6 +1068,8 @@ module.exports = (db, server, userHandler) => {
|
||||||
.get('pdw:' + userData._id.toString())
|
.get('pdw:' + userData._id.toString())
|
||||||
.ttl('pdw:' + userData._id.toString())
|
.ttl('pdw:' + userData._id.toString())
|
||||||
|
|
||||||
|
.hget('lim:imap', userData._id.toString())
|
||||||
|
|
||||||
.exec();
|
.exec();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// ignore
|
// ignore
|
||||||
|
@ -1089,6 +1097,8 @@ module.exports = (db, server, userHandler) => {
|
||||||
let pop3Download = Number(response && response[10] && response[10][1]) || 0;
|
let pop3Download = Number(response && response[10] && response[10][1]) || 0;
|
||||||
let pop3DownloadTtl = Number(response && response[11] && response[11][1]) || 0;
|
let pop3DownloadTtl = Number(response && response[11] && response[11][1]) || 0;
|
||||||
|
|
||||||
|
let imapMaxConnections = Number(response && response[12] && response[12][1]) || 0;
|
||||||
|
|
||||||
let keyInfo;
|
let keyInfo;
|
||||||
try {
|
try {
|
||||||
keyInfo = await getKeyInfo(userData.pubKey);
|
keyInfo = await getKeyInfo(userData.pubKey);
|
||||||
|
@ -1161,6 +1171,11 @@ module.exports = (db, server, userHandler) => {
|
||||||
allowed: Number(userData.pop3MaxDownload) || (config.pop3.maxDownloadMB || 10000) * 1024 * 1024,
|
allowed: Number(userData.pop3MaxDownload) || (config.pop3.maxDownloadMB || 10000) * 1024 * 1024,
|
||||||
used: pop3Download,
|
used: pop3Download,
|
||||||
ttl: pop3DownloadTtl >= 0 ? pop3DownloadTtl : false
|
ttl: pop3DownloadTtl >= 0 ? pop3DownloadTtl : false
|
||||||
|
},
|
||||||
|
|
||||||
|
imapMaxConnections: {
|
||||||
|
allowed: Number(userData.imapMaxConnections) || config.imap.maxConnections,
|
||||||
|
used: imapMaxConnections
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1210,6 +1225,7 @@ module.exports = (db, server, userHandler) => {
|
||||||
* @apiParam {Number} [imapMaxUpload] How many bytes can be uploaded via IMAP during 24 hour
|
* @apiParam {Number} [imapMaxUpload] How many bytes can be uploaded via IMAP during 24 hour
|
||||||
* @apiParam {Number} [imapMaxDownload] How many bytes can be downloaded via IMAP during 24 hour
|
* @apiParam {Number} [imapMaxDownload] How many bytes can be downloaded via IMAP during 24 hour
|
||||||
* @apiParam {Number} [pop3MaxDownload] How many bytes can be downloaded via POP3 during 24 hour
|
* @apiParam {Number} [pop3MaxDownload] How many bytes can be downloaded via POP3 during 24 hour
|
||||||
|
* @apiParam {Number} [imapMaxConnections] How many parallel IMAP connections are alowed
|
||||||
* @apiParam {Number} [receivedMax] How many messages can be received from MX during 60 seconds
|
* @apiParam {Number} [receivedMax] How many messages can be received from MX during 60 seconds
|
||||||
* @apiParam {Boolean} [disable2fa] If true, then disables 2FA for this user
|
* @apiParam {Boolean} [disable2fa] If true, then disables 2FA for this user
|
||||||
* @apiParam {String[]} disabledScopes List of scopes that are disabled for this user ("imap", "pop3", "smtp")
|
* @apiParam {String[]} disabledScopes List of scopes that are disabled for this user ("imap", "pop3", "smtp")
|
||||||
|
@ -1319,6 +1335,8 @@ module.exports = (db, server, userHandler) => {
|
||||||
imapMaxUpload: Joi.number().min(0),
|
imapMaxUpload: Joi.number().min(0),
|
||||||
imapMaxDownload: Joi.number().min(0),
|
imapMaxDownload: Joi.number().min(0),
|
||||||
pop3MaxDownload: Joi.number().min(0),
|
pop3MaxDownload: Joi.number().min(0),
|
||||||
|
imapMaxConnections: Joi.number().min(0),
|
||||||
|
|
||||||
receivedMax: Joi.number().min(0),
|
receivedMax: Joi.number().min(0),
|
||||||
|
|
||||||
disable2fa: Joi.boolean()
|
disable2fa: Joi.boolean()
|
||||||
|
|
|
@ -1382,6 +1382,8 @@ class UserHandler {
|
||||||
imapMaxUpload: data.imapMaxUpload || 0,
|
imapMaxUpload: data.imapMaxUpload || 0,
|
||||||
imapMaxDownload: data.imapMaxDownload || 0,
|
imapMaxDownload: data.imapMaxDownload || 0,
|
||||||
pop3MaxDownload: data.pop3MaxDownload || 0,
|
pop3MaxDownload: data.pop3MaxDownload || 0,
|
||||||
|
imapMaxConnections: data.imapMaxConnections || 0,
|
||||||
|
|
||||||
receivedMax: data.receivedMax || 0,
|
receivedMax: data.receivedMax || 0,
|
||||||
|
|
||||||
targets: [].concat(data.targets || []),
|
targets: [].concat(data.targets || []),
|
||||||
|
@ -2831,6 +2833,7 @@ class UserHandler {
|
||||||
['receivedMax', 'rl:rcpt']
|
['receivedMax', 'rl:rcpt']
|
||||||
]);
|
]);
|
||||||
let flushKeys = [];
|
let flushKeys = [];
|
||||||
|
let flushHKeys = [];
|
||||||
|
|
||||||
Object.keys(data).forEach(key => {
|
Object.keys(data).forEach(key => {
|
||||||
if (['user', 'existingPassword', 'hashedPassword', 'allowUnsafe', 'ip', 'sess'].includes(key)) {
|
if (['user', 'existingPassword', 'hashedPassword', 'allowUnsafe', 'ip', 'sess'].includes(key)) {
|
||||||
|
@ -2840,6 +2843,9 @@ class UserHandler {
|
||||||
if (resetKeys.has(key)) {
|
if (resetKeys.has(key)) {
|
||||||
flushKeys.push(resetKeys.get(key) + ':' + user);
|
flushKeys.push(resetKeys.get(key) + ':' + user);
|
||||||
}
|
}
|
||||||
|
if (key === 'imapMaxConnections') {
|
||||||
|
flushHKeys.push({ key: 'lim:imap', value: user.toString() });
|
||||||
|
}
|
||||||
|
|
||||||
if (key === 'password') {
|
if (key === 'password') {
|
||||||
if (!data[key]) {
|
if (!data[key]) {
|
||||||
|
@ -3042,11 +3048,17 @@ class UserHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we need to reset any ttl counters
|
// check if we need to reset any ttl counters
|
||||||
if (flushKeys.length) {
|
if (flushKeys.length || flushHKeys.length) {
|
||||||
let flushreq = this.redis.multi();
|
let flushreq = this.redis.multi();
|
||||||
|
|
||||||
flushKeys.forEach(key => {
|
flushKeys.forEach(key => {
|
||||||
flushreq = flushreq.del(key);
|
flushreq = flushreq.del(key);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
flushHKeys.forEach(entry => {
|
||||||
|
flushreq = flushreq.hdel(entry.key, entry.value);
|
||||||
|
});
|
||||||
|
|
||||||
// just call the operations and hope for the best, no problems if fails
|
// just call the operations and hope for the best, no problems if fails
|
||||||
flushreq.exec(() => false);
|
flushreq.exec(() => false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
"author": "Andris Reinman",
|
"author": "Andris Reinman",
|
||||||
"license": "EUPL-1.1+",
|
"license": "EUPL-1.1+",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"ajv": "6.8.1",
|
"ajv": "6.9.1",
|
||||||
"apidoc": "0.17.7",
|
"apidoc": "0.17.7",
|
||||||
"browserbox": "0.9.1",
|
"browserbox": "0.9.1",
|
||||||
"chai": "4.2.0",
|
"chai": "4.2.0",
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
"node-forge": "0.8.0",
|
"node-forge": "0.8.0",
|
||||||
"nodemailer": "5.1.1",
|
"nodemailer": "5.1.1",
|
||||||
"npmlog": "4.1.2",
|
"npmlog": "4.1.2",
|
||||||
"openpgp": "4.4.6",
|
"openpgp": "4.4.7",
|
||||||
"pem": "1.14.1",
|
"pem": "1.14.1",
|
||||||
"pwnedpasswords": "1.0.4",
|
"pwnedpasswords": "1.0.4",
|
||||||
"qrcode": "1.3.3",
|
"qrcode": "1.3.3",
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
"utf7": "1.0.2",
|
"utf7": "1.0.2",
|
||||||
"uuid": "3.3.2",
|
"uuid": "3.3.2",
|
||||||
"wild-config": "1.4.0",
|
"wild-config": "1.4.0",
|
||||||
"yargs": "12.0.5"
|
"yargs": "13.1.0"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
Loading…
Reference in a new issue