mirror of
https://github.com/nodemailer/wildduck.git
synced 2025-02-28 18:04:41 +08:00
v1.0.107
This commit is contained in:
parent
2daaa8127d
commit
0efcf316a5
8 changed files with 102 additions and 115 deletions
|
@ -1,3 +1,6 @@
|
|||
{
|
||||
"rules": {
|
||||
"indent": 0
|
||||
},
|
||||
"extends": "nodemailer"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
# Push messages to ZoneMTA queue for delivery
|
||||
# if `false` then no messages are sent
|
||||
enabled=true
|
||||
|
||||
# which ZoneMTA queue to use by default
|
||||
zone="default"
|
||||
|
||||
|
|
|
@ -1002,7 +1002,7 @@ module.exports = (db, server) => {
|
|||
* @apiParam {Number} [forwards] Daily allowed forwarding count for this address
|
||||
* @apiParam {Boolean} [allowWildcard=false] If <code>true</code> then address value can be in the form of <code>*@example.com</code>, otherwise using * is not allowed
|
||||
* @apiParam {Object} [autoreply] Autoreply information
|
||||
* @apiParam {Boolean} [autoreply.enabled] If true, then autoreply is enabled for this address
|
||||
* @apiParam {Boolean} [autoreply.status] If true, then autoreply is enabled for this address
|
||||
* @apiParam {String} [autoreply.start] Either a date string or boolean false to disable start time checks
|
||||
* @apiParam {String} [autoreply.end] Either a date string or boolean false to disable end time checks
|
||||
* @apiParam {String} [autoreply.subject] Autoreply subject line
|
||||
|
@ -1062,7 +1062,7 @@ module.exports = (db, server) => {
|
|||
.default(0),
|
||||
allowWildcard: Joi.boolean().truthy(['Y', 'true', 'yes', 1]),
|
||||
autoreply: Joi.object().keys({
|
||||
enabled: Joi.boolean()
|
||||
status: Joi.boolean()
|
||||
.truthy(['Y', 'true', 'yes', 1])
|
||||
.default(true),
|
||||
start: Joi.date()
|
||||
|
@ -1127,7 +1127,7 @@ module.exports = (db, server) => {
|
|||
}
|
||||
} else {
|
||||
result.value.autoreply = {
|
||||
enabled: false
|
||||
status: false
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1299,7 +1299,7 @@ module.exports = (db, server) => {
|
|||
* @apiParam {String[]} [targets] An array of forwarding targets. The value could either be an email address or a relay url to next MX server ("smtp://mx2.zone.eu:25"). If set then overwrites previous targets array
|
||||
* @apiParam {Number} [forwards] Daily allowed forwarding count for this address
|
||||
* @apiParam {Object} [autoreply] Autoreply information
|
||||
* @apiParam {Boolean} [autoreply.enabled] If true, then autoreply is enabled for this address
|
||||
* @apiParam {Boolean} [autoreply.status] If true, then autoreply is enabled for this address
|
||||
* @apiParam {String} [autoreply.start] Either a date string or boolean false to disable start time checks
|
||||
* @apiParam {String} [autoreply.end] Either a date string or boolean false to disable end time checks
|
||||
* @apiParam {String} [autoreply.subject] Autoreply subject line
|
||||
|
@ -1351,7 +1351,7 @@ module.exports = (db, server) => {
|
|||
.min(1),
|
||||
forwards: Joi.number().min(0),
|
||||
autoreply: Joi.object().keys({
|
||||
enabled: Joi.boolean().truthy(['Y', 'true', 'yes', 1]),
|
||||
status: Joi.boolean().truthy(['Y', 'true', 'yes', 1]),
|
||||
start: Joi.date()
|
||||
.empty('')
|
||||
.allow(false),
|
||||
|
@ -1708,7 +1708,7 @@ module.exports = (db, server) => {
|
|||
* @apiSuccess {Number} limits.forwards.used How many messages are forwarded during current 24 hour period
|
||||
* @apiSuccess {Number} limits.forwards.ttl Time until the end of current 24 hour period
|
||||
* @apiSuccess {Object} autoreply Autoreply information
|
||||
* @apiSuccess {Boolean} autoreply.enabled If true, then autoreply is enabled for this address
|
||||
* @apiSuccess {Boolean} autoreply.status If true, then autoreply is enabled for this address
|
||||
* @apiSuccess {String} autoreply.subject Autoreply subject line
|
||||
* @apiSuccess {String} autoreply.text Autoreply plaintext content
|
||||
* @apiSuccess {String} autoreply.html Autoreply HTML content
|
||||
|
@ -1818,7 +1818,7 @@ module.exports = (db, server) => {
|
|||
ttl: forwardsTtl >= 0 ? forwardsTtl : false
|
||||
}
|
||||
},
|
||||
autoreply: addressData.autoreply || { enabled: false },
|
||||
autoreply: addressData.autoreply || { status: false },
|
||||
created: addressData.created
|
||||
});
|
||||
|
||||
|
@ -1851,7 +1851,7 @@ module.exports = (db, server) => {
|
|||
* @apiSuccess {Number} limits.forwards.used How many messages are forwarded during current 24 hour period
|
||||
* @apiSuccess {Number} limits.forwards.ttl Time until the end of current 24 hour period
|
||||
* @apiSuccess {Object} autoreply Autoreply information
|
||||
* @apiSuccess {Boolean} autoreply.enabled If true, then autoreply is enabled for this address
|
||||
* @apiSuccess {Boolean} autoreply.status If true, then autoreply is enabled for this address
|
||||
* @apiSuccess {String} autoreply.subject Autoreply subject line
|
||||
* @apiSuccess {String} autoreply.text Autoreply plaintext content
|
||||
* @apiSuccess {String} autoreply.html Autoreply HTML content
|
||||
|
@ -1889,7 +1889,7 @@ module.exports = (db, server) => {
|
|||
* }
|
||||
* },
|
||||
* "autoreply": {
|
||||
* "enabled": false
|
||||
* "status": false
|
||||
* },
|
||||
* "created": "2017-10-24T11:19:10.911Z"
|
||||
* }
|
||||
|
@ -1995,7 +1995,7 @@ module.exports = (db, server) => {
|
|||
ttl: forwardsTtl >= 0 ? forwardsTtl : false
|
||||
}
|
||||
},
|
||||
autoreply: addressData.autoreply || { enabled: false },
|
||||
autoreply: addressData.autoreply || { status: false },
|
||||
created: addressData.created
|
||||
});
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ module.exports = (options, autoreplyData, callback) => {
|
|||
},
|
||||
headers: {
|
||||
'Auto-Submitted': 'auto-replied',
|
||||
'X-WD-Autoreply-For': (options.parentId || '').toString()
|
||||
'X-WD-Autoreply-For': (options.parentId || options.queueId).toString()
|
||||
},
|
||||
inReplyTo: headers.getFirst('Message-ID'),
|
||||
references: (headers.getFirst('Message-ID') + ' ' + headers.getFirst('References')).trim(),
|
||||
|
@ -104,18 +104,24 @@ module.exports = (options, autoreplyData, callback) => {
|
|||
}
|
||||
return callback(err, ...args);
|
||||
}
|
||||
options.db.database.collection('messagelog').insertOne(
|
||||
{
|
||||
id: args[0].id,
|
||||
messageId: args[0].messageId,
|
||||
parentId: options.parentId,
|
||||
action: 'AUTOREPLY',
|
||||
from: '',
|
||||
to: options.sender,
|
||||
created: new Date()
|
||||
},
|
||||
() => callback(err, args && args[0].id)
|
||||
);
|
||||
let logentry = {
|
||||
id: args[0].id,
|
||||
messageId: args[0].messageId,
|
||||
action: 'AUTOREPLY',
|
||||
from: '',
|
||||
to: options.sender,
|
||||
sender: options.recipient,
|
||||
created: new Date()
|
||||
};
|
||||
|
||||
if (options.parentId) {
|
||||
logentry.parentId = options.parentId;
|
||||
}
|
||||
if (options.queueId) {
|
||||
logentry.queueId = options.queueId;
|
||||
}
|
||||
|
||||
options.db.database.collection('messagelog').insertOne(logentry, () => callback(err, args && args[0].id));
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ class FilterHandler {
|
|||
this.spamChecks = options.spamChecks || tools.prepareSpamChecks(defaultSpamHeaderKeys);
|
||||
this.spamHeaderKeys = options.spamHeaderKeys || this.spamChecks.map(check => check.key);
|
||||
|
||||
this.senderEnabled = options.sender.enabled;
|
||||
this.maildrop = new Maildropper({
|
||||
db: this.db,
|
||||
zone: options.sender.zone,
|
||||
|
@ -329,10 +328,6 @@ class FilterHandler {
|
|||
};
|
||||
|
||||
let forwardMessage = done => {
|
||||
if (!this.senderEnabled) {
|
||||
return setImmediate(done);
|
||||
}
|
||||
|
||||
if (userData.forward && !filterActions.get('delete')) {
|
||||
// forward to default recipient only if the message is not deleted
|
||||
(Array.isArray(userData.forward) ? userData.forward : [].concat(userData.forward || [])).forEach(forward => {
|
||||
|
@ -397,10 +392,6 @@ class FilterHandler {
|
|||
};
|
||||
|
||||
let sendAutoreply = done => {
|
||||
if (!this.senderEnabled) {
|
||||
return setImmediate(done);
|
||||
}
|
||||
|
||||
// never reply to messages marked as spam
|
||||
if (!sender || !userData.autoreply || filterActions.get('spam')) {
|
||||
return setImmediate(done);
|
||||
|
|
|
@ -7,16 +7,10 @@ const Maildropper = require('./maildropper');
|
|||
let maildropper;
|
||||
|
||||
module.exports = (options, callback) => {
|
||||
if (!config.sender.enabled) {
|
||||
setImmediate(() => callback(null, false));
|
||||
return false;
|
||||
}
|
||||
|
||||
maildropper =
|
||||
maildropper ||
|
||||
new Maildropper({
|
||||
db,
|
||||
enabled: config.sender.enabled,
|
||||
zone: config.sender.zone,
|
||||
collection: config.sender.collection,
|
||||
gfs: config.sender.gfs
|
||||
|
|
|
@ -48,16 +48,22 @@ class UserHandler {
|
|||
let username = address.substr(0, address.indexOf('@')).replace(/\./g, '');
|
||||
let domain = address.substr(address.indexOf('@') + 1);
|
||||
|
||||
let fields = {
|
||||
user: true,
|
||||
targets: true
|
||||
};
|
||||
|
||||
Object.keys(options.fields || {}).forEach(key => {
|
||||
fields[key] = true;
|
||||
});
|
||||
|
||||
// try exact match
|
||||
this.users.collection('addresses').findOne(
|
||||
{
|
||||
addrview: username + '@' + domain
|
||||
},
|
||||
{
|
||||
fields: {
|
||||
user: true,
|
||||
targets: true
|
||||
}
|
||||
fields
|
||||
},
|
||||
(err, addressData) => {
|
||||
if (err) {
|
||||
|
@ -87,10 +93,7 @@ class UserHandler {
|
|||
addrview: username + '@' + aliasDomain
|
||||
},
|
||||
{
|
||||
fields: {
|
||||
user: true,
|
||||
targets: true
|
||||
}
|
||||
fields
|
||||
},
|
||||
done
|
||||
);
|
||||
|
@ -124,10 +127,7 @@ class UserHandler {
|
|||
this.users.collection('addresses').findOne(
|
||||
query,
|
||||
{
|
||||
fields: {
|
||||
user: true,
|
||||
targets: true
|
||||
}
|
||||
fields
|
||||
},
|
||||
(err, addressData) => {
|
||||
if (err) {
|
||||
|
@ -145,10 +145,7 @@ class UserHandler {
|
|||
addrview: address.substr(0, address.indexOf('@')).replace(/\./g, '') + '@*'
|
||||
},
|
||||
{
|
||||
fields: {
|
||||
user: true,
|
||||
targets: true
|
||||
}
|
||||
fields
|
||||
},
|
||||
(err, addressData) => {
|
||||
if (err) {
|
||||
|
@ -1246,15 +1243,15 @@ class UserHandler {
|
|||
let update =
|
||||
!userData.enabled2fa || typeof userData.enabled2fa === 'boolean'
|
||||
? {
|
||||
$set: {
|
||||
enabled2fa: ['totp']
|
||||
}
|
||||
}
|
||||
$set: {
|
||||
enabled2fa: ['totp']
|
||||
}
|
||||
}
|
||||
: {
|
||||
$addToSet: {
|
||||
enabled2fa: 'totp'
|
||||
}
|
||||
};
|
||||
$addToSet: {
|
||||
enabled2fa: 'totp'
|
||||
}
|
||||
};
|
||||
|
||||
// token was valid, update user settings
|
||||
return this.users.collection('users').findOneAndUpdate(
|
||||
|
@ -1328,19 +1325,19 @@ class UserHandler {
|
|||
let update =
|
||||
!userData.enabled2fa || typeof userData.enabled2fa === 'boolean'
|
||||
? {
|
||||
$set: {
|
||||
enabled2fa: [],
|
||||
seed: ''
|
||||
}
|
||||
}
|
||||
$set: {
|
||||
enabled2fa: [],
|
||||
seed: ''
|
||||
}
|
||||
}
|
||||
: {
|
||||
$pull: {
|
||||
enabled2fa: 'totp'
|
||||
},
|
||||
$set: {
|
||||
seed: ''
|
||||
}
|
||||
};
|
||||
$pull: {
|
||||
enabled2fa: 'totp'
|
||||
},
|
||||
$set: {
|
||||
seed: ''
|
||||
}
|
||||
};
|
||||
|
||||
return this.users.collection('users').findOneAndUpdate(
|
||||
{
|
||||
|
@ -1627,25 +1624,25 @@ class UserHandler {
|
|||
let update =
|
||||
!userData.enabled2fa || typeof userData.enabled2fa === 'boolean'
|
||||
? {
|
||||
$set: {
|
||||
enabled2fa: ['u2f'],
|
||||
u2fKeyHandle: result.keyHandle,
|
||||
u2fPubKey: result.publicKey,
|
||||
u2fCert: result.certificate,
|
||||
u2fDate: curDate
|
||||
}
|
||||
}
|
||||
$set: {
|
||||
enabled2fa: ['u2f'],
|
||||
u2fKeyHandle: result.keyHandle,
|
||||
u2fPubKey: result.publicKey,
|
||||
u2fCert: result.certificate,
|
||||
u2fDate: curDate
|
||||
}
|
||||
}
|
||||
: {
|
||||
$addToSet: {
|
||||
enabled2fa: 'u2f'
|
||||
},
|
||||
$set: {
|
||||
u2fKeyHandle: result.keyHandle,
|
||||
u2fPubKey: result.publicKey,
|
||||
u2fCert: result.certificate,
|
||||
u2fDate: curDate
|
||||
}
|
||||
};
|
||||
$addToSet: {
|
||||
enabled2fa: 'u2f'
|
||||
},
|
||||
$set: {
|
||||
u2fKeyHandle: result.keyHandle,
|
||||
u2fPubKey: result.publicKey,
|
||||
u2fCert: result.certificate,
|
||||
u2fDate: curDate
|
||||
}
|
||||
};
|
||||
|
||||
return this.users.collection('users').findOneAndUpdate(
|
||||
{
|
||||
|
@ -1719,23 +1716,23 @@ class UserHandler {
|
|||
let update =
|
||||
!userData.enabled2fa || typeof userData.enabled2fa === 'boolean'
|
||||
? {
|
||||
$set: {
|
||||
enabled2fa: [],
|
||||
u2fKeyHandle: '',
|
||||
u2fPubKey: '',
|
||||
u2fCert: ''
|
||||
}
|
||||
}
|
||||
$set: {
|
||||
enabled2fa: [],
|
||||
u2fKeyHandle: '',
|
||||
u2fPubKey: '',
|
||||
u2fCert: ''
|
||||
}
|
||||
}
|
||||
: {
|
||||
$pull: {
|
||||
enabled2fa: 'u2f'
|
||||
},
|
||||
$set: {
|
||||
u2fKeyHandle: '',
|
||||
u2fPubKey: '',
|
||||
u2fCert: ''
|
||||
}
|
||||
};
|
||||
$pull: {
|
||||
enabled2fa: 'u2f'
|
||||
},
|
||||
$set: {
|
||||
u2fKeyHandle: '',
|
||||
u2fPubKey: '',
|
||||
u2fCert: ''
|
||||
}
|
||||
};
|
||||
|
||||
return this.users.collection('users').findOneAndUpdate(
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "wildduck",
|
||||
"version": "1.0.106",
|
||||
"version": "1.0.107",
|
||||
"description": "IMAP server built with Node.js and MongoDB",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
|
@ -31,7 +31,7 @@
|
|||
"dependencies": {
|
||||
"addressparser": "1.0.1",
|
||||
"bcryptjs": "2.4.3",
|
||||
"bugsnag": "2.0.1",
|
||||
"bugsnag": "2.1.1",
|
||||
"generate-password": "1.3.0",
|
||||
"he": "1.1.1",
|
||||
"html-to-text": "3.3.0",
|
||||
|
@ -40,7 +40,7 @@
|
|||
"iconv-lite": "0.4.19",
|
||||
"ioredfour": "1.0.2-ioredis",
|
||||
"ioredis": "3.2.2",
|
||||
"joi": "13.0.2",
|
||||
"joi": "13.1.0",
|
||||
"js-yaml": "3.10.0",
|
||||
"key-fingerprint": "1.1.0",
|
||||
"libbase64": "1.0.2",
|
||||
|
|
Loading…
Reference in a new issue