Skip to content

Commit 9bd2e2f

Browse files
committed
message-handler refactoring + optimizations
1 parent d08eaed commit 9bd2e2f

File tree

1 file changed

+96
-94
lines changed

1 file changed

+96
-94
lines changed

Diff for: lib/message-handler.js

+96-94
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,11 @@ class MessageHandler {
196196
}
197197

198198
// get target mailbox data
199-
let mailboxData = await this.getMailboxAsync(options);
199+
// get target user data
200+
let [mailboxData, userData] = await Promise.all([this.getMailboxAsync(options), this.users.collection('users').findOne({ _id: options.user })]);
200201

201202
options.targetMailboxEncrypted = !!mailboxData.encryptMessages;
202203

203-
// get target user data
204-
const userData = await this.users.collection('users').findOne({ _id: options.user });
205-
206204
let prepared = options.prepared; // might be undefined
207205

208206
// check if already encrypted
@@ -308,10 +306,11 @@ class MessageHandler {
308306
// with err, with attachments
309307
try {
310308
await this.attachmentStorage.deleteMany(attachmentIds, maildata.magic);
311-
throw err;
312-
} catch (ignore) {
309+
} catch {
310+
// throw original error
313311
throw err;
314312
}
313+
throw err;
315314
};
316315

317316
try {
@@ -474,9 +473,9 @@ class MessageHandler {
474473
}
475474

476475
let rollback = async rollbackError => {
477-
let args;
476+
let r;
478477
try {
479-
args = await this.users.collection('users').findOneAndUpdate(
478+
r = await this.users.collection('users').findOneAndUpdate(
480479
{
481480
_id: mailboxData.user
482481
},
@@ -492,12 +491,11 @@ class MessageHandler {
492491
}
493492
}
494493
);
495-
} catch (ignore) {
496-
// ignore
494+
} catch {
495+
// some error, clean up immediately
496+
return cleanup(rollbackError);
497497
}
498498

499-
let r = args && args[1];
500-
501499
if (r && r.value) {
502500
this.loggelf({
503501
short_message: '[QUOTA] -',
@@ -598,63 +596,7 @@ class MessageHandler {
598596
let uidValidity = mailboxData.uidValidity;
599597
let uid = messageData.uid;
600598

601-
if (
602-
options.session &&
603-
options.session.selected &&
604-
options.session.selected.mailbox &&
605-
options.session.selected.mailbox.toString() === mailboxData._id.toString()
606-
) {
607-
options.session.writeStream.write(options.session.formatResponse('EXISTS', messageData.uid));
608-
}
609-
610-
let updateAddressRegister = async finishFunc => {
611-
let addresses = [];
612-
613-
if (messageData.junk || flags.includes('\\Draft')) {
614-
// skip junk and draft messages
615-
return finishFunc();
616-
}
617-
618-
let parsed = messageData.mimeTree && messageData.mimeTree.parsedHeader;
619-
620-
if (parsed) {
621-
let keyList = mailboxData.specialUse === '\\Sent' ? ['to', 'cc', 'bcc'] : ['from'];
622-
623-
for (const disallowedHeader of DISALLOWED_HEADERS_FOR_ADDRESS_REGISTER) {
624-
// if email contains headers that we do not want,
625-
// don't add any emails to address register
626-
if (parsed[disallowedHeader]) {
627-
return finishFunc();
628-
}
629-
}
630-
631-
for (let key of keyList) {
632-
if (parsed[key] && parsed[key].length) {
633-
for (let addr of parsed[key]) {
634-
if (/no-?reply/i.test(addr.address)) {
635-
continue;
636-
}
637-
if (!addresses.some(a => a.address === addr.address)) {
638-
addresses.push(addr);
639-
}
640-
}
641-
}
642-
}
643-
}
644-
645-
if (!addresses.length) {
646-
return finishFunc();
647-
}
648-
649-
try {
650-
await this.updateAddressRegister(mailboxData.user, addresses);
651-
return finishFunc();
652-
} catch (err) {
653-
return finishFunc(err);
654-
}
655-
};
656-
657-
return updateAddressRegister(
599+
const finishFunc = // finishFunc:
658600
async () =>
659601
new Promise(resolve => {
660602
this.notifier.addEntries(
@@ -681,45 +623,105 @@ class MessageHandler {
681623
.toArray();
682624

683625
let now = new Date();
626+
const auditPromises = [];
627+
684628
for (let auditData of audits) {
685629
if ((auditData.start && auditData.start > now) || (auditData.end && auditData.end < now)) {
686630
// audit not active
687631
continue;
688632
}
689-
await this.auditHandler.store(auditData._id, raw, {
690-
date: messageData.idate,
691-
msgid: messageData.msgid,
692-
header: messageData.mimeTree && messageData.mimeTree.parsedHeader,
693-
ha: messageData.ha,
694-
mailbox: mailboxData._id,
695-
mailboxPath: mailboxData.path,
696-
info: Object.assign({ queueId: messageData.outbound }, messageData.meta)
697-
});
633+
634+
auditPromises.push(
635+
this.auditHandler.store(auditData._id, raw, {
636+
date: messageData.idate,
637+
msgid: messageData.msgid,
638+
header: messageData.mimeTree && messageData.mimeTree.parsedHeader,
639+
ha: messageData.ha,
640+
mailbox: mailboxData._id,
641+
mailboxPath: mailboxData.path,
642+
info: Object.assign({ queueId: messageData.outbound }, messageData.meta)
643+
})
644+
);
698645
}
646+
647+
await Promise.all(auditPromises);
699648
};
700649

701-
let next = () =>
702-
cleanup(null, true, {
703-
uidValidity,
704-
uid,
705-
id: messageData._id.toString(),
706-
mailbox: mailboxData._id.toString(),
707-
mailboxPath: mailboxData.path,
708-
size,
709-
status: 'new'
710-
});
650+
// can safely cleanup, no err given. Returns pending promise, which is fine
651+
const cleanupRes = cleanup(null, true, {
652+
uidValidity,
653+
uid,
654+
id: messageData._id.toString(),
655+
mailbox: mailboxData._id.toString(),
656+
mailboxPath: mailboxData.path,
657+
size,
658+
status: 'new'
659+
});
711660

712-
// do not use more suitable .finally() as it is not supported in Node v8
661+
// do not use more suitable finally as it is not supported in Node v8
713662
try {
714663
await processAudits();
715-
resolve(next());
716-
} catch (ignore) {
717-
resolve(next());
664+
resolve(cleanupRes);
665+
} catch {
666+
resolve(cleanupRes);
718667
}
719668
}
720669
);
721-
})
722-
);
670+
});
671+
672+
if (
673+
options.session &&
674+
options.session.selected &&
675+
options.session.selected.mailbox &&
676+
options.session.selected.mailbox.toString() === mailboxData._id.toString()
677+
) {
678+
options.session.writeStream.write(options.session.formatResponse('EXISTS', messageData.uid));
679+
}
680+
681+
let addresses = [];
682+
683+
if (messageData.junk || flags.includes('\\Draft')) {
684+
// skip junk and draft messages
685+
return finishFunc();
686+
}
687+
688+
let parsed = messageData.mimeTree && messageData.mimeTree.parsedHeader;
689+
690+
if (parsed) {
691+
let keyList = mailboxData.specialUse === '\\Sent' ? ['to', 'cc', 'bcc'] : ['from'];
692+
693+
for (const disallowedHeader of DISALLOWED_HEADERS_FOR_ADDRESS_REGISTER) {
694+
// if email contains headers that we do not want,
695+
// don't add any emails to address register
696+
if (parsed[disallowedHeader]) {
697+
return finishFunc();
698+
}
699+
}
700+
701+
for (let key of keyList) {
702+
if (parsed[key] && parsed[key].length) {
703+
for (let addr of parsed[key]) {
704+
if (/no-?reply/i.test(addr.address)) {
705+
continue;
706+
}
707+
if (!addresses.some(a => a.address === addr.address)) {
708+
addresses.push(addr);
709+
}
710+
}
711+
}
712+
}
713+
}
714+
715+
if (!addresses.length) {
716+
return finishFunc();
717+
}
718+
719+
try {
720+
await this.updateAddressRegister(mailboxData.user, addresses);
721+
return finishFunc();
722+
} catch (err) {
723+
return finishFunc(err);
724+
}
723725
}
724726

725727
async updateQuotaAsync(user, inc, options) {

0 commit comments

Comments
 (0)