mirror of
https://github.com/nodemailer/wildduck.git
synced 2024-09-20 07:16:05 +08:00
v1.35.1
This commit is contained in:
parent
a65d708f12
commit
64c47ec587
1
api.js
1
api.js
|
@ -490,7 +490,6 @@ module.exports = done => {
|
|||
users: db.users,
|
||||
redis: db.redis,
|
||||
messageHandler,
|
||||
authlogExpireDays: config.log.authlogExpireDays,
|
||||
loggelf: message => loggelf(message)
|
||||
});
|
||||
|
||||
|
|
|
@ -51,7 +51,8 @@ processes=1
|
|||
# changing this value only affects new entries
|
||||
# set to false to not log authentication events
|
||||
# set to 0 to keep the logs infinitely
|
||||
authlogExpireDays=30
|
||||
# NB! Removed. Use const:authlog:time setting instead
|
||||
#authlogExpireDays=30
|
||||
|
||||
[log.gelf]
|
||||
enabled=false
|
||||
|
|
1
imap.js
1
imap.js
|
@ -227,7 +227,6 @@ module.exports = done => {
|
|||
database: db.database,
|
||||
users: db.users,
|
||||
redis: db.redis,
|
||||
authlogExpireDays: config.log.authlogExpireDays,
|
||||
loggelf: message => loggelf(message)
|
||||
});
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@ module.exports = {
|
|||
// merge similar authlog events into 6 hour buckets instead of storing each separately
|
||||
// this is mostly needed for IMAP clients that make crazy amout of connections and thus logins
|
||||
AUTHLOG_BUCKET: 6 * 3600 * 1000,
|
||||
AUTHLOG_TIME: 30 * 24 * 3600 * 1000,
|
||||
|
||||
// start processing tasks 5 minues after startup
|
||||
TASK_STARTUP_INTERVAL: 1 * 60 * 1000,
|
||||
|
|
|
@ -39,6 +39,15 @@ const SETTING_KEYS = [
|
|||
type: 'number',
|
||||
constKey: 'MAX_FORWARDS',
|
||||
schema: Joi.number()
|
||||
},
|
||||
|
||||
{
|
||||
key: 'const:authlog:time',
|
||||
name: 'Auth log time',
|
||||
description: 'Time in ms after authentication log entries will be purged',
|
||||
type: 'duration',
|
||||
constKey: 'AUTHLOG_TIME',
|
||||
schema: Joi.number()
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -189,6 +198,7 @@ class SettingsHandler {
|
|||
name: keyInfo.name,
|
||||
description: keyInfo.description,
|
||||
default: keyInfo.constKey ? consts[keyInfo.constKey] : undefined,
|
||||
type: keyInfo.type,
|
||||
custom: true
|
||||
});
|
||||
} catch (err) {
|
||||
|
@ -207,6 +217,7 @@ class SettingsHandler {
|
|||
name: row.name,
|
||||
description: row.description,
|
||||
default: row.constKey ? consts[row.constKey] : undefined,
|
||||
type: row.type,
|
||||
custom: false
|
||||
});
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ const UserCache = require('./user-cache');
|
|||
const isemail = require('isemail');
|
||||
const util = require('util');
|
||||
const TaskHandler = require('./task-handler');
|
||||
const { SettingsHandler } = require('./settings-handler');
|
||||
const { encrypt, decrypt } = require('./encrypt');
|
||||
|
||||
const {
|
||||
|
@ -60,12 +61,7 @@ class UserHandler {
|
|||
this.flushUserCache = util.promisify(this.userCache.flush.bind(this.userCache));
|
||||
|
||||
this.taskHandler = new TaskHandler({ database: this.database });
|
||||
|
||||
if (!('authlogExpireDays' in options)) {
|
||||
this.authlogExpireDays = 30;
|
||||
} else {
|
||||
this.authlogExpireDays = options.authlogExpireDays;
|
||||
}
|
||||
this.settingsHandler = new SettingsHandler({ db: this.database });
|
||||
}
|
||||
|
||||
resolveAddress(address, options, callback) {
|
||||
|
@ -3343,8 +3339,10 @@ class UserHandler {
|
|||
}
|
||||
|
||||
async logAuthEvent(user, entry) {
|
||||
let authlogTime = await this.settingsHandler.get('const:authlog:time', {});
|
||||
|
||||
// only log auth events if we have a valid user id and logging is not disabled
|
||||
if (!user || !tools.isId(user) || this.authlogExpireDays === false) {
|
||||
if (!user || !tools.isId(user) || !authlogTime) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3354,10 +3352,8 @@ class UserHandler {
|
|||
entry.action = entry.action || 'authentication';
|
||||
entry.created = now;
|
||||
|
||||
if (typeof this.authlogExpireDays === 'number' && this.authlogExpireDays !== 0) {
|
||||
// this entry expires in set days
|
||||
entry.expires = new Date(Date.now() + Math.abs(this.authlogExpireDays) * 24 * 3600 * 1000);
|
||||
}
|
||||
// this entry expires in set days
|
||||
entry.expires = new Date(Date.now() + authlogTime);
|
||||
|
||||
// key is for merging similar events
|
||||
entry.key = crypto
|
||||
|
|
1
lmtp.js
1
lmtp.js
|
@ -247,7 +247,6 @@ module.exports = done => {
|
|||
database: db.database,
|
||||
users: db.users,
|
||||
redis: db.redis,
|
||||
authlogExpireDays: config.log.authlogExpireDays,
|
||||
loggelf: message => loggelf(message)
|
||||
});
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "wildduck",
|
||||
"version": "1.35.0",
|
||||
"version": "1.35.1",
|
||||
"description": "IMAP/POP3 server built with Node.js and MongoDB",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
|
|
1
pop3.js
1
pop3.js
|
@ -464,7 +464,6 @@ module.exports = done => {
|
|||
database: db.database,
|
||||
users: db.users,
|
||||
redis: db.redis,
|
||||
authlogExpireDays: config.log.authlogExpireDays,
|
||||
loggelf: message => loggelf(message)
|
||||
});
|
||||
|
||||
|
|
|
@ -19,6 +19,159 @@
|
|||
return document.getElementById('accessToken').value.trim();
|
||||
}
|
||||
|
||||
function formatDuration(value) {
|
||||
value = Number(value);
|
||||
|
||||
let parts = [];
|
||||
|
||||
let days = Math.floor(value / (24 * 3600 * 1000));
|
||||
value = value - days * 24 * 3600 * 1000;
|
||||
if (days) {
|
||||
parts.push(`${days}d`);
|
||||
}
|
||||
|
||||
let hours = Math.floor(value / (3600 * 1000));
|
||||
value = value - hours * 3600 * 1000;
|
||||
if (hours) {
|
||||
parts.push(`${hours}h`);
|
||||
}
|
||||
|
||||
let minutes = Math.floor(value / (60 * 1000));
|
||||
value = value - minutes * 60 * 1000;
|
||||
if (minutes) {
|
||||
parts.push(`${minutes}m`);
|
||||
}
|
||||
|
||||
let seconds = Math.floor(value / 1000);
|
||||
value = value - seconds * 1000;
|
||||
if (seconds) {
|
||||
parts.push(`${seconds}s`);
|
||||
}
|
||||
|
||||
let ms = value;
|
||||
if (ms || !parts.length) {
|
||||
parts.push(`${ms}ms`);
|
||||
}
|
||||
|
||||
return parts.join(' ');
|
||||
}
|
||||
|
||||
function formatSize(value) {
|
||||
value = Number(value);
|
||||
|
||||
let parts = [];
|
||||
|
||||
let gb = Math.floor(value / (1024 * 1024 * 1024));
|
||||
value = value - gb * 1024 * 1024 * 1024;
|
||||
if (gb) {
|
||||
parts.push(`${gb}GB`);
|
||||
}
|
||||
|
||||
let mb = Math.floor(value / (1024 * 1024));
|
||||
value = value - mb * 1024 * 1024;
|
||||
if (mb) {
|
||||
parts.push(`${mb}MB`);
|
||||
}
|
||||
|
||||
let kb = Math.floor(value / 1024);
|
||||
value = value - kb * 1024;
|
||||
if (kb) {
|
||||
parts.push(`${kb}kB`);
|
||||
}
|
||||
|
||||
let b = value;
|
||||
if (b || !parts.length) {
|
||||
parts.push(`${b}B`);
|
||||
}
|
||||
|
||||
return parts.join(' ');
|
||||
}
|
||||
|
||||
function formatNumber(value, type) {
|
||||
switch (type) {
|
||||
case 'duration':
|
||||
return formatDuration(value);
|
||||
case 'size':
|
||||
return formatSize(value);
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
function parseSize(value) {
|
||||
// remove unneeded spaces
|
||||
value = value.toString().replace(/(\d)[\s\.]+(?=\d|g|m|k|b)/gi, '$1');
|
||||
|
||||
let result = 0;
|
||||
|
||||
let parts = value.split(/\s+/);
|
||||
for (let part of parts) {
|
||||
part.replace(/(\d+)(g|m|k|b)?/i, (o, num, unit) => {
|
||||
switch ((unit || '').toString().toLowerCase()) {
|
||||
case 'g':
|
||||
result += Number(num) * 1024 * 1024 * 1024;
|
||||
break;
|
||||
case 'm':
|
||||
result += Number(num) * 1024 * 1024;
|
||||
break;
|
||||
case 'k':
|
||||
result += Number(num) * 1024;
|
||||
break;
|
||||
case 'b':
|
||||
default:
|
||||
result += Number(num);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseDuration(value) {
|
||||
// remove unneeded spaces
|
||||
value = value.toString().replace(/(\d)[\s\.]+(?=\d|d|h|ms|m|s)/gi, '$1');
|
||||
|
||||
let result = 0;
|
||||
|
||||
let parts = value.split(/\s+/);
|
||||
for (let part of parts) {
|
||||
part.replace(/(\d+)(d|h|ms|m|s)?/i, (o, num, unit) => {
|
||||
switch ((unit || '').toString().toLowerCase()) {
|
||||
case 'd':
|
||||
result += Number(num) * 24 * 3600 * 1000;
|
||||
break;
|
||||
case 'h':
|
||||
result += Number(num) * 3600 * 1000;
|
||||
break;
|
||||
case 'm':
|
||||
result += Number(num) * 60 * 1000;
|
||||
break;
|
||||
case 's':
|
||||
result += Number(num) * 1000;
|
||||
break;
|
||||
case 'ms':
|
||||
default:
|
||||
result += Number(num);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseNumber(value, type) {
|
||||
switch (type) {
|
||||
case 'duration':
|
||||
return parseDuration(value);
|
||||
case 'size':
|
||||
return parseSize(value);
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
function addSettingsRow(tableElm, setting) {
|
||||
let trElm = document.createElement('tr');
|
||||
|
||||
|
@ -38,7 +191,7 @@
|
|||
|
||||
if (setting.default) {
|
||||
let defaultTextElm = document.createElement('code');
|
||||
defaultTextElm.textContent = setting.default;
|
||||
defaultTextElm.textContent = formatNumber(setting.default, setting.type);
|
||||
defaultTdElm.title = setting.description;
|
||||
defaultTdElm.appendChild(defaultTextElm);
|
||||
} else {
|
||||
|
@ -54,7 +207,7 @@
|
|||
valueInputElm.setAttribute('placeholder', 'Value');
|
||||
valueInputElm.setAttribute('autocomplete', 'off');
|
||||
valueInputElm.setAttribute('data-lpignore', 'true');
|
||||
valueInputElm.value = setting.value || '';
|
||||
valueInputElm.value = formatNumber(setting.value || '', setting.type);
|
||||
valueTdElm.appendChild(valueInputElm);
|
||||
|
||||
let btnInputElm = document.createElement('button');
|
||||
|
@ -73,7 +226,7 @@
|
|||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
value: valueInputElm.value
|
||||
value: parseNumber(valueInputElm.value, setting.type)
|
||||
})
|
||||
})
|
||||
.then(res => {
|
||||
|
@ -175,6 +328,13 @@
|
|||
<tbody id="settings-table"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ul>
|
||||
<li>Duration: <code>XXd XXh XXm XXs XXms</code></li>
|
||||
<li>Size: <code>XXGB XXMB XXkB XXB</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -70,9 +70,6 @@ interfaces=[\"feeder\"]
|
|||
# defaults to os.hostname()
|
||||
hostname=\"$HOSTNAME\"
|
||||
|
||||
# How long to keep auth records in log
|
||||
authlogExpireDays=30
|
||||
|
||||
# SRS settings for forwarded emails
|
||||
|
||||
[wildduck.srs]
|
||||
|
|
Loading…
Reference in a new issue