Added message DELETE Api call

This commit is contained in:
Andris Reinman 2017-07-21 16:29:57 +03:00
parent 13469f5b74
commit 7ae401740c
2 changed files with 187 additions and 9 deletions

123
api.js
View file

@ -10,6 +10,7 @@ const tools = require('./lib/tools');
const consts = require('./lib/consts');
const UserHandler = require('./lib/user-handler');
const MailboxHandler = require('./lib/mailbox-handler');
const MessageHandler = require('./lib/message-handler');
const ImapNotifier = require('./lib/imap-notifier');
const db = require('./lib/db');
const MongoPaging = require('mongo-cursor-pagination');
@ -44,6 +45,7 @@ const server = restify.createServer(serverOptions);
let userHandler;
let mailboxHandler;
let messageHandler;
let notifier;
// disable compression for EventSource response
@ -1894,14 +1896,14 @@ server.get('/users/:user/mailboxes/:mailbox/messages/:message', (req, res, next)
if (parsedHeader['list-id'] || parsedHeader['list-unsubscribe']) {
let listId = parsedHeader['list-id'];
if (listId) {
listId = addressparser(listId);
listId = addressparser(listId.toString());
decodeAddresses(listId);
listId = listId.shift();
}
let listUnsubscribe = parsedHeader['list-unsubscribe'];
if (listUnsubscribe) {
listUnsubscribe = addressparser(listUnsubscribe);
listUnsubscribe = addressparser(listUnsubscribe.toString());
decodeAddresses(listUnsubscribe);
}
@ -1959,6 +1961,7 @@ server.put('/users/:user/mailboxes/:mailbox/messages/:message', (req, res, next)
const schema = Joi.object().keys({
user: Joi.string().hex().lowercase().length(24).required(),
mailbox: Joi.string().hex().lowercase().length(24).required(),
newMailbox: Joi.string().hex().lowercase().length(24),
message: Joi.string().regex(/^[0-9a-f]{24}:\d{1,10}/).lowercase().required(),
seen: Joi.boolean().truthy(['Y', 'true', 'yes', 1]),
deleted: Joi.boolean().truthy(['Y', 'true', 'yes', 1]),
@ -1982,9 +1985,45 @@ server.put('/users/:user/mailboxes/:mailbox/messages/:message', (req, res, next)
let messageparts = result.value.message.split(':');
let user = new ObjectID(result.value.user);
let mailbox = new ObjectID(result.value.mailbox);
let newMailbox = result.value.newMailbox ? new ObjectID(result.value.newMailbox) : false;
let message = new ObjectID(messageparts[0]);
let uid = Number(messageparts[1]);
if (newMailbox) {
return messageHandler.move(
{
user,
source: { user, mailbox },
destination: { user, mailbox: newMailbox },
updates: result.value,
returnIds: true,
messages: [uid]
},
(err, result, info) => {
if (err) {
res.json({
error: err.message
});
return next();
}
if (!info || !info.destinationUid || !info.destinationUid.length) {
res.json({
error: 'Could not move message, check if message exists'
});
return next();
}
res.json({
success: true,
mailbox: newMailbox,
id: info && info.destinationUid && info.destinationUid[0]
});
return next();
}
);
}
let updates = { $set: {} };
let update = false;
let addFlags = [];
@ -2149,6 +2188,85 @@ server.put('/users/:user/mailboxes/:mailbox/messages/:message', (req, res, next)
});
});
server.del('/users/:user/mailboxes/:mailbox/messages/:message', (req, res, next) => {
res.charSet('utf-8');
const schema = Joi.object().keys({
user: Joi.string().hex().lowercase().length(24).required(),
mailbox: Joi.string().hex().lowercase().length(24).required(),
message: Joi.string().regex(/^[0-9a-f]{24}:\d{1,10}/).lowercase().required()
});
const result = Joi.validate(req.params, schema, {
abortEarly: false,
convert: true
});
if (result.error) {
res.json({
error: result.error.message
});
return next();
}
let messageparts = result.value.message.split(':');
let user = new ObjectID(result.value.user);
let mailbox = new ObjectID(result.value.mailbox);
let message = new ObjectID(messageparts[0]);
let uid = Number(messageparts[1]);
db.database.collection('messages').findOne({
_id: message,
mailbox,
uid
}, {
fields: {
_id: true,
mailbox: true,
uid: true,
size: true,
map: true,
magic: true,
unseen: true
}
}, (err, messageData) => {
if (err) {
res.json({
error: err.message
});
return next();
}
if (!messageData) {
res.json({
error: 'Message was not found'
});
return next();
}
return messageHandler.del(
{
user,
mailbox: { user, mailbox },
message: messageData
},
(err, result, info) => {
if (err) {
res.json({
error: err.message
});
return next();
}
res.json({
success: true
});
return next();
}
);
});
});
server.get('/users/:user/updates', (req, res, next) => {
res.charSet('utf-8');
@ -2477,6 +2595,7 @@ module.exports = done => {
});
userHandler = new UserHandler({ database: db.database, users: db.users, redis: db.redis });
mailboxHandler = new MailboxHandler({ database: db.database, users: db.users, redis: db.redis, notifier });
messageHandler = new MessageHandler({ database: db.database, gridfs: db.gridfs, redis: db.redis });
server.on('error', err => {
if (!started) {

View file

@ -38,6 +38,9 @@ class MessageHandler {
return setImmediate(() => callback(null, options.mailbox));
}
query._id = options.mailbox;
if (options.user) {
query.user = options.user;
}
} else {
query.user = options.user;
if (options.specialUse) {
@ -463,8 +466,8 @@ class MessageHandler {
del(options, callback) {
let message = options.message;
this.getMailbox(
{
mailbox: options.mailbox || message.mailbox
options.mailbox || {
mailbox: message.mailbox
},
(err, mailbox) => {
if (err) {
@ -621,7 +624,12 @@ class MessageHandler {
let messageId = message._id;
let messageUid = message.uid;
sourceUid.unshift(messageUid);
if (options.returnIds) {
sourceUid.unshift(message._id);
} else {
sourceUid.unshift(messageUid);
}
this.database.collection('mailboxes').findOneAndUpdate({
_id: target._id
}, {
@ -639,12 +647,16 @@ class MessageHandler {
return cursor.close(() => done(new Error('Mailbox disappeared')));
}
let uidNext = item.value.uidNext;
destinationUid.unshift(uidNext);
// set new id
message._id = new ObjectID();
let uidNext = item.value.uidNext;
if (options.returnIds) {
destinationUid.unshift(message._id);
} else {
destinationUid.unshift(uidNext);
}
// set new mailbox
message.mailbox = target._id;
@ -675,6 +687,53 @@ class MessageHandler {
junk = -1;
}
Object.keys(options.updates || []).forEach(key => {
switch (key) {
case 'seen':
case 'deleted':
{
let fname = '\\' + key.charAt(0).toUpperCase() + key.substr(1);
if (!options.updates[key] && !message.flags.includes(fname)) {
// add missing flag
message.flags.push(fname);
} else if (options.updates[key] && message.flags.includes(fname)) {
// remove non-needed flag
let flags = new Set(message.flags);
flags.delete(fname);
message.flags = Array.from(flags);
}
message['un' + key] = options.updates[key];
}
break;
case 'flagged':
case 'draft':
{
let fname = '\\' + key.charAt(0).toUpperCase() + key.substr(1);
if (options.updates[key] && !message.flags.includes(fname)) {
// add missing flag
message.flags.push(fname);
} else if (!options.updates[key] && message.flags.includes(fname)) {
// remove non-needed flag
let flags = new Set(message.flags);
flags.delete(fname);
message.flags = Array.from(flags);
}
message[key] = options.updates[key];
}
break;
case 'expires':
{
if (options.updates.expires) {
message.exp = true;
message.rdate = options.updates.expires.getTime();
} else {
message.exp = false;
}
}
break;
}
});
if (options.markAsSeen) {
message.unseen = false;
if (!message.flags.includes('\\Seen')) {