allow custom metaData for messages

This commit is contained in:
Andris Reinman 2018-12-04 10:50:27 +02:00
parent cb5696ff03
commit 498552b859
6 changed files with 65 additions and 12 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
define({ "name": "wildduck", "version": "1.0.0", "description": "WildDuck API docs", "title": "WildDuck API", "url": "https://api.wildduck.email", "sampleUrl": false, "defaultVersion": "0.0.0", "apidoc": "0.3.0", "generator": { "name": "apidoc", "time": "2018-11-28T13:47:57.854Z", "url": "http://apidocjs.com", "version": "0.17.7" } });
define({ "name": "wildduck", "version": "1.0.0", "description": "WildDuck API docs", "title": "WildDuck API", "url": "https://api.wildduck.email", "sampleUrl": false, "defaultVersion": "0.0.0", "apidoc": "0.3.0", "generator": { "name": "apidoc", "time": "2018-12-04T08:49:05.903Z", "url": "http://apidocjs.com", "version": "0.17.7" } });

View file

@ -1 +1 @@
{ "name": "wildduck", "version": "1.0.0", "description": "WildDuck API docs", "title": "WildDuck API", "url": "https://api.wildduck.email", "sampleUrl": false, "defaultVersion": "0.0.0", "apidoc": "0.3.0", "generator": { "name": "apidoc", "time": "2018-11-28T13:47:57.854Z", "url": "http://apidocjs.com", "version": "0.17.7" } }
{ "name": "wildduck", "version": "1.0.0", "description": "WildDuck API docs", "title": "WildDuck API", "url": "https://api.wildduck.email", "sampleUrl": false, "defaultVersion": "0.0.0", "apidoc": "0.3.0", "generator": { "name": "apidoc", "time": "2018-12-04T08:49:05.903Z", "url": "http://apidocjs.com", "version": "0.17.7" } }

View file

@ -97,6 +97,10 @@ module.exports = (db, server, messageHandler) => {
.falsy(['N', 'false', 'no', 'off', '0', 0, ''])
.allow(false)
),
metaData: Joi.string()
.empty('')
.trim()
.max(1024 * 1024),
sess: Joi.string().max(255),
ip: Joi.string().ip({
version: ['ipv4', 'ipv6'],
@ -117,6 +121,21 @@ module.exports = (db, server, messageHandler) => {
return next();
}
if (result.value.metaData) {
try {
let value = JSON.parse(result.value.metaData);
if (!value || typeof value !== 'object') {
throw new Error('Not an object');
}
} catch (err) {
res.json({
error: 'metaData value must be valid JSON object string',
code: 'InputValidationError'
});
return next();
}
}
// permissions check
if (req.user && req.user === result.value.user) {
req.validate(roles.can(req.role).updateOwn('messages'));
@ -1030,6 +1049,7 @@ module.exports = (db, server, messageHandler) => {
* @apiSuccess {Object} contentType Parsed Content-Type header. Usually needed to identify encrypted messages and such
* @apiSuccess {String} contentType.value MIME type of the message, eg. "multipart/mixed"
* @apiSuccess {Object} contentType.params An object with Content-Type params as key-value pairs
* @apiSuccess {String} metaData JSON formatted custom metadata object set for this message
*
* @apiError error Description of the error
*
@ -1091,7 +1111,8 @@ module.exports = (db, server, messageHandler) => {
* "params": {
* "boundary": "=-qYxqvD9rbH0PNeExagh1"
* }
* }
* },
* "metaData": "{}"
* }
*
* @apiErrorExample {json} Error-Response:
@ -1332,11 +1353,11 @@ module.exports = (db, server, messageHandler) => {
text: messageData.text,
forwardTargets: messageData.forwardTargets,
attachments: messageData.attachments || [],
meta: messageData.meta || {},
references: (parsedHeader.references || '')
.toString()
.split(/\s+/)
.filter(ref => ref)
.filter(ref => ref),
metaData: messageData.meta.custom || '{}'
};
let parsedContentType = parsedHeader['content-type'];
@ -1685,6 +1706,7 @@ module.exports = (db, server, messageHandler) => {
* @apiParam {Boolean} flagged State of the \Flagged flag
* @apiParam {Boolean} draft State of the \Draft flag
* @apiParam {Datestring} expires Either expiration date or <code>false</code> to turn of autoexpiration
* @apiParam {String} [metaData] Optional metadata, must be JSON formatted object
*
* @apiSuccess {Boolean} success Indicates successful response
* @apiSuccess {Object[]} id If messages were moved then lists new ID values. Array entry is an array with first element pointing to old ID and second to new ID
@ -1883,9 +1905,9 @@ module.exports = (db, server, messageHandler) => {
* @apiParam {Object[]} [bcc] Addresses for the Bcc: header
* @apiParam {String} [bcc.name] Name of the recipient
* @apiParam {String} bcc.address Address of the recipient
* @apiParam {String} subject Message subject. If not then resolved from Reference message
* @apiParam {String} text Plaintext message
* @apiParam {String} html HTML formatted message
* @apiParam {String} [subject] Message subject. If not then resolved from Reference message
* @apiParam {String} [text] Plaintext message
* @apiParam {String} [html] HTML formatted message
* @apiParam {Object[]} [headers] Custom headers for the message. If reference message is set then In-Reply-To and References headers are set automaticall y
* @apiParam {String} headers.key Header key ('X-Mailer')
* @apiParam {String} headers.value Header value ('My Awesome Mailing Service')
@ -1894,6 +1916,7 @@ module.exports = (db, server, messageHandler) => {
* @apiParam {String} [attachments.filename] Attachment filename
* @apiParam {String} [attachments.contentType] MIME type for the attachment file
* @apiParam {String} [attachments.cid] Content-ID value if you want to reference to this attachment from HTML formatted message
* @apiParam {String} [metaData] Optional metadata, must be JSON formatted object
* @apiParam {String} [sess] Session identifier for the logs
* @apiParam {String} [ip] IP address for the logs
*
@ -2067,6 +2090,11 @@ module.exports = (db, server, messageHandler) => {
})
),
metaData: Joi.string()
.empty('')
.trim()
.max(1024 * 1024),
sess: Joi.string().max(255),
ip: Joi.string().ip({
version: ['ipv4', 'ipv6'],
@ -2105,6 +2133,21 @@ module.exports = (db, server, messageHandler) => {
return next();
}
if (result.value.metaData) {
try {
let value = JSON.parse(result.value.metaData);
if (!value || typeof value !== 'object') {
throw new Error('Not an object');
}
} catch (err) {
res.json({
error: 'metaData value must be valid JSON object string',
code: 'InputValidationError'
});
return next();
}
}
// permissions check
if (req.user && req.user === result.value.user) {
req.validate(roles.can(req.role).createOwn('messages'));
@ -2174,7 +2217,7 @@ module.exports = (db, server, messageHandler) => {
to: result.value.to || [],
cc: result.value.cc || [],
bcc: result.value.bcc || [],
subject: result.value.subject,
subject: result.value.subject || '',
text: result.value.text || '',
html: result.value.html || '',
headers: result.value.headers || [],
@ -2224,7 +2267,8 @@ module.exports = (db, server, messageHandler) => {
from: '',
origin: result.value.ip || '127.0.0.1',
transtype: 'UPLOAD',
time: date
time: date,
custom: result.value.metaData || ''
},
session: result.value.session,
date,

View file

@ -848,6 +848,10 @@ class MessageHandler {
}
}
break;
case 'metaData':
message.meta = message.meta || {};
message.meta.custom = options.updates.metaData;
break;
}
});
@ -1334,6 +1338,11 @@ class MessageHandler {
}
update = true;
break;
case 'metaData':
updates.$set['meta.custom'] = changes.metaData;
update = true;
break;
}
});