Fix error when partially upding a filter

This commit is contained in:
Louis Laureys 2020-10-19 00:33:24 +02:00
parent 3271064044
commit 9dd3ed0e65

View file

@ -774,7 +774,7 @@ module.exports = (db, server) => {
* @apiParam {String} user Users unique ID.
* @apiParam {String} filter Filters unique ID.
* @apiParam {String} [name] Name of the Filter
* @apiParam {Object} query Rules that a message must match
* @apiParam {Object} [query] Rules that a message must match
* @apiParam {String} [query.from] Partial match for the From: header (case insensitive)
* @apiParam {String} [query.to] Partial match for the To:/Cc: headers (case insensitive)
* @apiParam {String} [query.subject] Partial match for the Subject: header (case insensitive)
@ -782,7 +782,7 @@ module.exports = (db, server) => {
* @apiParam {String} [query.text] Fulltext search against message text
* @apiParam {Boolean} [query.ha] Does a message have to have an attachment or not
* @apiParam {Number} [query.size] Message size in bytes. If the value is a positive number then message needs to be larger, if negative then message needs to be smaller than abs(size) value
* @apiParam {Object} action Action to take with a matching message
* @apiParam {Object} [action] Action to take with a matching message
* @apiParam {Boolean} [action.seen] If true then mark matching messages as Seen
* @apiParam {Boolean} [action.flag] If true then mark matching messages as Flagged
* @apiParam {Boolean} [action.delete] If true then do not store matching messages
@ -906,129 +906,133 @@ module.exports = (db, server) => {
hasChanges = true;
}
['from', 'to', 'subject', 'listId'].forEach(key => {
if (result.value.query[key]) {
$set['query.headers.' + key] = result.value.query[key].replace(/\s+/g, ' ');
hasChanges = true;
} else if (key in req.params.query) {
// delete empty values
$unset['query.headers.' + key] = true;
hasChanges = true;
}
});
if (result.value.query.text) {
$set['query.text'] = result.value.query.text.replace(/\s+/g, ' ');
hasChanges = true;
} else if ('text' in req.params.query) {
$unset['query.text'] = true;
hasChanges = true;
}
if (typeof result.value.query.ha === 'boolean') {
$set['query.ha'] = result.value.query.ha;
hasChanges = true;
} else if ('ha' in req.params.query) {
$unset['query.ha'] = true;
hasChanges = true;
}
if (result.value.query.size) {
$set['query.size'] = result.value.query.size;
hasChanges = true;
} else if ('size' in req.params.query) {
$unset['query.size'] = true;
hasChanges = true;
}
['seen', 'flag', 'delete', 'spam'].forEach(key => {
if (typeof result.value.action[key] === 'boolean') {
$set['action.' + key] = result.value.action[key];
hasChanges = true;
} else if (key in req.params.action) {
$unset['action.' + key] = true;
hasChanges = true;
}
});
let targets = result.value.action.targets;
if (targets) {
for (let i = 0, len = targets.length; i < len; i++) {
let target = targets[i];
if (!/^smtps?:/i.test(target) && !/^https?:/i.test(target) && target.indexOf('@') >= 0) {
// email
targets[i] = {
id: new ObjectID(),
type: 'mail',
value: target
};
} else if (/^smtps?:/i.test(target)) {
targets[i] = {
id: new ObjectID(),
type: 'relay',
value: target
};
} else if (/^https?:/i.test(target)) {
targets[i] = {
id: new ObjectID(),
type: 'http',
value: target
};
} else {
res.json({
error: 'Unknown target type "' + target + '"',
code: 'InputValidationError'
});
return next();
}
}
$set['action.targets'] = targets;
hasChanges = true;
} else if ('targets' in req.params.action) {
$unset['action.targets'] = true;
hasChanges = true;
}
if (result.value.action) {
if (!result.value.action.mailbox) {
if ('mailbox' in req.params.action) {
// clear target mailbox
$unset['action.mailbox'] = true;
if (req.params.query) {
['from', 'to', 'subject', 'listId'].forEach(key => {
if (result.value.query[key]) {
$set['query.headers.' + key] = result.value.query[key].replace(/\s+/g, ' ');
hasChanges = true;
} else if (key in req.params.query) {
// delete empty values
$unset['query.headers.' + key] = true;
hasChanges = true;
}
} else {
let mailboxData;
try {
mailboxData = await db.database.collection('mailboxes').findOne({
_id: new ObjectID(result.value.action.mailbox),
user
});
} catch (err) {
res.json({
error: 'MongoDB Error: ' + err.message,
code: 'InternalDatabaseError'
});
return next();
}
});
if (!mailboxData) {
res.json({
error: 'This mailbox does not exist',
code: 'NoSuchMailbox'
});
return next();
}
$set['action.mailbox'] = mailboxData._id;
if (result.value.query.text) {
$set['query.text'] = result.value.query.text.replace(/\s+/g, ' ');
hasChanges = true;
} else if ('text' in req.params.query) {
$unset['query.text'] = true;
hasChanges = true;
}
if (typeof result.value.query.ha === 'boolean') {
$set['query.ha'] = result.value.query.ha;
hasChanges = true;
} else if ('ha' in req.params.query) {
$unset['query.ha'] = true;
hasChanges = true;
}
if (result.value.query.size) {
$set['query.size'] = result.value.query.size;
hasChanges = true;
} else if ('size' in req.params.query) {
$unset['query.size'] = true;
hasChanges = true;
}
}
if (req.params.action) {
['seen', 'flag', 'delete', 'spam'].forEach(key => {
if (typeof result.value.action[key] === 'boolean') {
$set['action.' + key] = result.value.action[key];
hasChanges = true;
} else if (key in req.params.action) {
$unset['action.' + key] = true;
hasChanges = true;
}
});
let targets = result.value.action.targets;
if (targets) {
for (let i = 0, len = targets.length; i < len; i++) {
let target = targets[i];
if (!/^smtps?:/i.test(target) && !/^https?:/i.test(target) && target.indexOf('@') >= 0) {
// email
targets[i] = {
id: new ObjectID(),
type: 'mail',
value: target
};
} else if (/^smtps?:/i.test(target)) {
targets[i] = {
id: new ObjectID(),
type: 'relay',
value: target
};
} else if (/^https?:/i.test(target)) {
targets[i] = {
id: new ObjectID(),
type: 'http',
value: target
};
} else {
res.json({
error: 'Unknown target type "' + target + '"',
code: 'InputValidationError'
});
return next();
}
}
$set['action.targets'] = targets;
hasChanges = true;
} else if ('targets' in req.params.action) {
$unset['action.targets'] = true;
hasChanges = true;
}
if (result.value.action) {
if (!result.value.action.mailbox) {
if ('mailbox' in req.params.action) {
// clear target mailbox
$unset['action.mailbox'] = true;
hasChanges = true;
}
} else {
let mailboxData;
try {
mailboxData = await db.database.collection('mailboxes').findOne({
_id: new ObjectID(result.value.action.mailbox),
user
});
} catch (err) {
res.json({
error: 'MongoDB Error: ' + err.message,
code: 'InternalDatabaseError'
});
return next();
}
if (!mailboxData) {
res.json({
error: 'This mailbox does not exist',
code: 'NoSuchMailbox'
});
return next();
}
$set['action.mailbox'] = mailboxData._id;
hasChanges = true;
}
}
}
if (!hasChanges) {
res.json({
error: 'No changes'
success: true
});
return next();
}