Skip to content

Commit 1dc422f

Browse files
authored
fix(search-apply): ZMS-275: search-apply allow to delete found messages (#881)
* search-apply allow to delete found messages in Trash and Junk folders * fix comment, refactor description * allow search and apply delete in Drafts folder too * search-apply do not allow other fields in API if delete true, refactor search-apply task, improve readability * search-apply task refactor, allow to delete in any mailbox * if moving to same mailbox then update message data instead
1 parent a38a704 commit 1dc422f

File tree

2 files changed

+106
-47
lines changed

2 files changed

+106
-47
lines changed

lib/api/messages.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,21 @@ module.exports = (db, server, messageHandler, userHandler, storageHandler, setti
984984
.keys({
985985
moveTo: Joi.string().hex().lowercase().length(24).description('ID of the target Mailbox if you want to move messages'),
986986
seen: booleanSchema.description('State of the \\Seen flag'),
987-
flagged: booleanSchema.description('State of the \\Flagged flag')
987+
flagged: booleanSchema.description('State of the \\Flagged flag'),
988+
delete: booleanSchema.default(false).description('If true then delete all found messages')
989+
})
990+
.custom((value, helpers) => {
991+
// If delete is set to true then any other field is disallowed to be set
992+
if (value.delete === true) {
993+
const otherKeys = Object.keys(value).filter(key => key !== 'delete' && value[key] !== undefined);
994+
if (otherKeys.length > 0) {
995+
return helpers.error('object.deleteOnly', { keys: otherKeys });
996+
}
997+
}
998+
return value;
999+
})
1000+
.messages({
1001+
'object.deleteOnly': `When 'delete' is true, no other fields ({{#keys}}) can be set`
9881002
})
9891003
.required()
9901004
.description('Define actions to take with matching messages')

lib/tasks/search-apply.js

Lines changed: 91 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ let run = async (task, data, options) => {
1818
const user = new ObjectId(data.user);
1919

2020
const action = data.action || {};
21+
let updateAction = false;
22+
2123
if (action.moveTo) {
2224
action.moveTo = new ObjectId(action.moveTo);
25+
updateAction = 'move';
2326
}
2427

2528
let query;
@@ -35,21 +38,29 @@ let run = async (task, data, options) => {
3538
}
3639

3740
try {
38-
// getMailboxAsync throws if mailbox is missing or wrong owner
39-
const mailboxData = action.moveTo ? await messageHandler.getMailboxAsync({ mailbox: action.moveTo }) : false;
40-
4141
let updates = {};
4242
for (let key of ['seen', 'flagged']) {
4343
if (key in action) {
4444
updates[key] = action[key];
4545
}
4646
}
4747

48+
if (Object.keys(updates).length) {
49+
updateAction = 'update';
50+
}
51+
52+
if (action.delete) {
53+
updateAction = 'delete';
54+
}
55+
56+
// getMailboxAsync throws if mailbox is missing or wrong owner
57+
const mailboxData = updateAction === 'move' ? await messageHandler.getMailboxAsync({ mailbox: action.moveTo }) : false;
58+
4859
let cursor = await db.database.collection('messages').find(filter);
4960

5061
let messageData;
5162

52-
if (!action.moveTo && !Object.keys(updates).length) {
63+
if (!updateAction) {
5364
// nothing to do here
5465
return;
5566
}
@@ -59,48 +70,82 @@ let run = async (task, data, options) => {
5970
continue;
6071
}
6172

62-
if (action.moveTo && action.moveTo.toString() !== messageData.mailbox.toString()) {
63-
try {
64-
await messageHandler.moveAsync({
65-
user,
66-
source: {
67-
user: messageData.user,
68-
mailbox: messageData.mailbox
69-
},
70-
destination: {
71-
mailbox: mailboxData._id
72-
},
73-
updates: Object.keys(updates).length ? updates : false,
74-
messageQuery: messageData.uid
75-
});
76-
updated++;
77-
} catch (err) {
78-
errors++;
79-
log.error(
80-
'Tasks',
81-
'task=search-apply id=%s user=%s query=%s message=%s error=%s',
82-
task._id,
83-
data.user,
84-
JSON.stringify(query),
85-
messageData._id,
86-
err.message
87-
);
88-
}
89-
} else if (Object.keys(updates).length) {
90-
try {
91-
updated += await updateMessage(user, messageData.mailbox, messageData.uid, updates);
92-
} catch (err) {
93-
errors++;
94-
log.error(
95-
'Tasks',
96-
'task=search-apply id=%s user=%s query=%s message=%s error=%s',
97-
task._id,
98-
data.user,
99-
JSON.stringify(query),
100-
messageData._id,
101-
err.message
102-
);
103-
}
73+
if (updateAction === 'move' && action.moveTo.toString() === messageData.mailbox.toString()) {
74+
updateAction = 'update';
75+
}
76+
77+
switch (updateAction) {
78+
case 'move':
79+
try {
80+
await messageHandler.moveAsync({
81+
user,
82+
source: {
83+
user: messageData.user,
84+
mailbox: messageData.mailbox
85+
},
86+
destination: {
87+
mailbox: mailboxData._id
88+
},
89+
updates: Object.keys(updates).length ? updates : false,
90+
messageQuery: messageData.uid
91+
});
92+
updated++;
93+
} catch (err) {
94+
errors++;
95+
log.error(
96+
'Tasks',
97+
'task=search-apply id=%s user=%s query=%s message=%s error=%s',
98+
task._id,
99+
data.user,
100+
JSON.stringify(query),
101+
messageData._id,
102+
err.message
103+
);
104+
}
105+
106+
break;
107+
case 'update':
108+
try {
109+
updated += await updateMessage(user, messageData.mailbox, messageData.uid, updates);
110+
} catch (err) {
111+
errors++;
112+
log.error(
113+
'Tasks',
114+
'task=search-apply id=%s user=%s query=%s message=%s error=%s',
115+
task._id,
116+
data.user,
117+
JSON.stringify(query),
118+
messageData._id,
119+
err.message
120+
);
121+
}
122+
break;
123+
case 'delete':
124+
// delete found messages
125+
// allow delete of searched messages only in Trash, Junk, and Drafts folders
126+
try {
127+
await messageHandler.delAsync({
128+
user,
129+
mailbox: { user, mailbox: messageData.mailbox },
130+
messageData,
131+
archive: !messageData.flags.includes('\\Draft')
132+
});
133+
updated++;
134+
} catch (err) {
135+
errors++;
136+
log.error(
137+
'Tasks',
138+
'task=search-apply id=%s user=%s query=%s message=%s error=%s',
139+
task._id,
140+
data.user,
141+
JSON.stringify(query),
142+
messageData._id,
143+
err.message
144+
);
145+
}
146+
break;
147+
default:
148+
break;
104149
}
105150
}
106151
await cursor.close();

0 commit comments

Comments
 (0)