diff --git a/lib/api/filters.js b/lib/api/filters.js index 95e15a1..3f02e09 100644 --- a/lib/api/filters.js +++ b/lib/api/filters.js @@ -525,7 +525,7 @@ module.exports = (db, server) => { .empty(''), size: Joi.number().empty('') }) - .required(), + .default({}), action: Joi.object() .keys({ seen: Joi.boolean() @@ -560,7 +560,7 @@ module.exports = (db, server) => { ) .empty('') }) - .required() + .default({}) }); const result = Joi.validate(req.params, schema, { @@ -591,35 +591,27 @@ module.exports = (db, server) => { filterData.name = result.value.name; } - let hasQuery = false; - let hasAction = false; - ['from', 'to', 'subject'].forEach(key => { if (result.value.query[key]) { filterData.query.headers[key] = result.value.query[key].replace(/\s+/g, ' '); - hasQuery = true; } }); if (result.value.query.text) { filterData.query.text = result.value.query.text.replace(/\s+/g, ' '); - hasQuery = true; } if (typeof result.value.query.ha === 'boolean') { filterData.query.ha = result.value.query.ha; - hasQuery = true; } if (result.value.query.size) { filterData.query.size = result.value.query.size; - hasQuery = true; } ['seen', 'flag', 'delete', 'spam'].forEach(key => { if (typeof result.value.action[key] === 'boolean') { filterData.action[key] = result.value.action[key]; - hasAction = true; } }); @@ -657,7 +649,6 @@ module.exports = (db, server) => { } filterData.action.targets = targets; - hasAction = true; } let checkFilterMailbox = done => { @@ -684,27 +675,12 @@ module.exports = (db, server) => { return next(); } filterData.action.mailbox = mailboxData._id; - hasAction = true; done(); } ); }; checkFilterMailbox(() => { - if (!hasQuery) { - res.json({ - error: 'Empty filter query' - }); - return next(); - } - - if (!hasAction) { - res.json({ - error: 'Empty filter action' - }); - return next(); - } - db.users.collection('users').findOne( { _id: user @@ -826,62 +802,66 @@ module.exports = (db, server) => { .max(255) .empty(''), - query: Joi.object().keys({ - from: Joi.string() - .trim() - .max(255) - .empty(''), - to: Joi.string() - .trim() - .max(255) - .empty(''), - subject: Joi.string() - .trim() - .max(255) - .empty(''), - text: Joi.string() - .trim() - .max(255) - .empty(''), - ha: Joi.boolean() - .truthy(['Y', 'true', 'yes', 'on', 1]) - .falsy(['N', 'false', 'no', 'off', 0, '']) - .empty(''), - size: Joi.number().empty('') - }), - action: Joi.object().keys({ - seen: Joi.boolean() - .truthy(['Y', 'true', 'yes', 'on', 1]) - .falsy(['N', 'false', 'no', 'off', 0, '']) - .empty(''), - flag: Joi.boolean() - .truthy(['Y', 'true', 'yes', 'on', 1]) - .falsy(['N', 'false', 'no', 'off', 0, '']) - .empty(''), - delete: Joi.boolean() - .truthy(['Y', 'true', 'yes', 'on', 1]) - .falsy(['N', 'false', 'no', 'off', 0, '']) - .empty(''), - spam: Joi.boolean() - .truthy(['Y', 'true', 'yes', 'on', 1]) - .falsy(['N', 'false', 'no', 'off', 0, '']) - .empty(''), - mailbox: Joi.string() - .hex() - .lowercase() - .length(24) - .empty(''), - targets: Joi.array() - .items( - Joi.string().email(), - Joi.string().uri({ - scheme: [/smtps?/, /https?/], - allowRelative: false, - relativeOnly: false - }) - ) - .empty('') - }) + query: Joi.object() + .keys({ + from: Joi.string() + .trim() + .max(255) + .empty(''), + to: Joi.string() + .trim() + .max(255) + .empty(''), + subject: Joi.string() + .trim() + .max(255) + .empty(''), + text: Joi.string() + .trim() + .max(255) + .empty(''), + ha: Joi.boolean() + .truthy(['Y', 'true', 'yes', 'on', 1]) + .falsy(['N', 'false', 'no', 'off', 0, '']) + .empty(''), + size: Joi.number().empty('') + }) + .default({}), + action: Joi.object() + .keys({ + seen: Joi.boolean() + .truthy(['Y', 'true', 'yes', 'on', 1]) + .falsy(['N', 'false', 'no', 'off', 0, '']) + .empty(''), + flag: Joi.boolean() + .truthy(['Y', 'true', 'yes', 'on', 1]) + .falsy(['N', 'false', 'no', 'off', 0, '']) + .empty(''), + delete: Joi.boolean() + .truthy(['Y', 'true', 'yes', 'on', 1]) + .falsy(['N', 'false', 'no', 'off', 0, '']) + .empty(''), + spam: Joi.boolean() + .truthy(['Y', 'true', 'yes', 'on', 1]) + .falsy(['N', 'false', 'no', 'off', 0, '']) + .empty(''), + mailbox: Joi.string() + .hex() + .lowercase() + .length(24) + .empty(''), + targets: Joi.array() + .items( + Joi.string().email(), + Joi.string().uri({ + scheme: [/smtps?/, /https?/], + allowRelative: false, + relativeOnly: false + }) + ) + .empty('') + }) + .default({}) }); const result = Joi.validate(req.params, schema, { @@ -910,93 +890,89 @@ module.exports = (db, server) => { hasChanges = true; } - if (result.value.query) { - ['from', 'to', 'subject'].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, ' '); + ['from', 'to', 'subject'].forEach(key => { + if (result.value.query[key]) { + $set['query.headers.' + key] = result.value.query[key].replace(/\s+/g, ' '); hasChanges = true; - } else if ('text' in req.params.query) { - $unset['query.text'] = true; + } else if (key in req.params.query) { + // delete empty values + $unset['query.headers.' + key] = 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 (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 (result.value.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; - } - }); + 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; + } - let targets = result.value.action.targets; + 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 (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; + ['seen', 'flag', 'delete', 'spam'].forEach(key => { + if (typeof result.value.action[key] === 'boolean') { + $set['action.' + key] = result.value.action[key]; hasChanges = true; - } else if ('targets' in req.params.action) { - $unset['action.targets'] = 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; } let checkFilterMailbox = done => {