wildduck/lib/tasks/restore.js

117 lines
4.6 KiB
JavaScript
Raw Normal View History

2018-10-11 16:48:12 +08:00
'use strict';
const log = require('npmlog');
const db = require('../db');
module.exports = (taskData, options, callback) => {
const messageHandler = options.messageHandler;
let cursor = db.database.collection('archived').find({
user: taskData.user,
archived: {
$gte: taskData.start,
$lte: taskData.end
}
});
db.users.findOne({ _id: taskData.user }, (err, userData) => {
if (err) {
log.error('Tasks', 'task=restore id=%s user=%s error=%s', taskData._id, taskData.user, err.message);
return callback(err);
}
if (!userData) {
// no such user anymore
log.error('Tasks', 'task=restore id=%s user=%s error=%s', taskData._id, taskData.user, 'No such user');
return callback(null, true);
}
db.database
.collection('mailboxes')
.find({
user: taskData.user
})
.toArray((err, mailboxesList) => {
if (err) {
log.error('Tasks', 'task=restore id=%s user=%s error=%s', taskData._id, taskData.user, err.message);
return callback(err);
}
let mailboxes = new Map();
let trashMailbox;
let inboxMailbox;
mailboxes = (mailboxesList || []).forEach(mailboxData => {
mailboxes.set(mailboxData._id.toString(), mailboxData);
if (mailboxData.specialUse === '\\Trash') {
trashMailbox = mailboxData._id;
} else if (mailboxData.path === 'INBOX') {
inboxMailbox = mailboxData._id;
}
});
let processNext = () => {
cursor.next((err, messageData) => {
if (err) {
log.error('Tasks', 'task=restore id=%s user=%s error=%s', taskData._id, taskData.user, err.message);
return callback(err);
}
if (!messageData) {
return cursor.close(() => callback(null, true));
}
// move messages from Trash and non-existing mailboxes to INBOX
if (messageData.mailbox && (messageData.mailbox.equals(trashMailbox) || !mailboxes.has(messageData.mailbox.toString()))) {
messageData.mailbox = inboxMailbox;
}
delete messageData.archived;
delete messageData.exp;
delete messageData.rdate;
log.info(
'Tasks',
'task=restore id=%s user=%s message=%s action=restoring target=%s',
taskData._id,
taskData.user,
messageData._id,
messageData.mailbox
);
messageHandler.put(messageData, (err, response) => {
if (err) {
log.error('Tasks', 'task=restore id=%s user=%s message=%s error=%s', taskData._id, taskData.user, messageData._id, err.message);
return setTimeout(processNext, 5000);
} else if (!response) {
log.error(
'Tasks',
'task=restore id=%s user=%s message=%s error=%s',
taskData._id,
taskData.user,
messageData._id,
'Failed to restore message'
);
return setTimeout(processNext, 1000);
}
log.info(
'Tasks',
'task=restore id=%s user=%s message=%s mailbox=%s uid=%s',
taskData._id,
taskData.user,
messageData._id,
response.mailbox,
response.uid
);
return db.database.collection('archived').deleteOne({ _id: messageData._id }, () => processNext());
});
});
};
processNext();
});
});
};