Include flags in select

This commit is contained in:
Andris Reinman 2017-03-30 13:25:42 +03:00
parent 5f7bc1aa74
commit c92753265d
6 changed files with 79 additions and 66 deletions

12
api.js
View file

@ -103,7 +103,8 @@ server.post('/user/create', (req, res, next) => {
uidValidity,
uidNext: 1,
modifyIndex: 0,
subscribed: true
subscribed: true,
flags: []
}, {
user,
path: 'Sent Mail',
@ -111,7 +112,8 @@ server.post('/user/create', (req, res, next) => {
uidValidity,
uidNext: 1,
modifyIndex: 0,
subscribed: true
subscribed: true,
flags: []
}, {
user,
path: 'Trash',
@ -119,7 +121,8 @@ server.post('/user/create', (req, res, next) => {
uidValidity,
uidNext: 1,
modifyIndex: 0,
subscribed: true
subscribed: true,
flags: []
}, {
user,
path: 'Junk',
@ -127,7 +130,8 @@ server.post('/user/create', (req, res, next) => {
uidValidity,
uidNext: 1,
modifyIndex: 0,
subscribed: true
subscribed: true,
flags: []
}], {
w: 1,
ordered: false

View file

@ -74,27 +74,17 @@ module.exports = {
};
this.state = 'Selected';
let flagList = imapTools.systemFlagsFormatted.concat(folder.flags || []);
// * FLAGS (\Answered \Flagged \Draft \Deleted \Seen)
this.send(imapHandler.compiler({
tag: '*',
command: 'FLAGS',
attributes: [
[{
flagList.map(flag => ({
type: 'atom',
value: '\\Answered'
}, {
type: 'atom',
value: '\\Flagged'
}, {
type: 'atom',
value: '\\Draft'
}, {
type: 'atom',
value: '\\Deleted'
}, {
type: 'atom',
value: '\\Seen'
}]
value: flag
}))
]
}));
@ -110,25 +100,13 @@ module.exports = {
type: 'atom',
value: 'PERMANENTFLAGS'
},
[{
flagList.map(flag => ({
type: 'atom',
value: '\\Answered'
}, {
type: 'atom',
value: '\\Flagged'
}, {
type: 'atom',
value: '\\Draft'
}, {
type: 'atom',
value: '\\Deleted'
}, {
type: 'atom',
value: '\\Seen'
}, {
value: flag
})).concat({
type: 'text',
value: '\\*'
}]
})
]
}, {
type: 'text',

View file

@ -95,7 +95,7 @@ module.exports = {
for (let i = flags.length - 1; i >= 0; i--) {
if (flags[i].charAt(0) === '\\') {
if (imapTools.systemFlags.indexOf(flags[i].toLowerCase()) < 0) {
if (!imapTools.systemFlags.includes(flags[i].toLowerCase())) {
return callback(new Error('Invalid system flag argument for STORE'));
} else {
// fix flag case

View file

@ -476,7 +476,7 @@ class IMAPConnection extends EventEmitter {
}
}
if (existsResponse) {
if (existsResponse && !changed) {
// send cached EXISTS response
this.writeStream.write(existsResponse);
existsResponse = false;

View file

@ -5,6 +5,7 @@ const utf7 = require('utf7').imap;
const libmime = require('libmime');
const punycode = require('punycode');
module.exports.systemFlagsFormatted = ['\\Answered', '\\Flagged', '\\Draft', '\\Deleted', '\\Seen'];
module.exports.systemFlags = ['\\answered', '\\flagged', '\\draft', '\\deleted', '\\seen'];
module.exports.fetchSchema = {

34
imap.js
View file

@ -9,6 +9,7 @@ const imapHandler = IMAPServerModule.imapHandler;
const bcrypt = require('bcryptjs');
const ObjectID = require('mongodb').ObjectID;
const Indexer = require('./imap-core/lib/indexer/indexer');
const imapTools = require('./imap-core/lib/imap-tools');
const fs = require('fs');
const setupIndexes = require('./indexes.json');
const MessageHandler = require('./lib/message-handler');
@ -161,7 +162,8 @@ server.onCreate = function (path, session, callback) {
uidValidity: Math.floor(Date.now() / 1000),
uidNext: 1,
modifyIndex: 0,
subscribed: true
subscribed: true,
flags: []
};
db.database.collection('mailboxes').insertOne(mailbox, err => {
@ -422,6 +424,9 @@ server.onStore = function (path, update, session, callback) {
return callback(null, 'NONEXISTENT');
}
let mailboxFlags = imapTools.systemFlags.concat(mailbox.flags || []).map(flag => flag.trim().toLowerCase());
let newFlags = [];
let cursor = db.database.collection('messages').find({
mailbox: mailbox._id,
uid: {
@ -509,6 +514,13 @@ server.onStore = function (path, update, session, callback) {
break;
}
message.flags.forEach(flag => {
// limit mailbox flags by 100
if (!mailboxFlags.includes(flag.trim().toLowerCase()) && mailboxFlags.length + newFlags.length < 100) {
newFlags.push(flag);
}
});
if (!update.silent) {
session.writeStream.write(session.formatResponse('FETCH', message.uid, {
uid: update.isUid ? message.uid : false,
@ -516,6 +528,24 @@ server.onStore = function (path, update, session, callback) {
}));
}
let updateMailboxFlags = next => {
if (!newFlags.length) {
return next();
}
// found some new flags not yet set for mailbox
return db.database.collection('mailboxes').findOneAndUpdate({
_id: mailbox._id
}, {
$addToSet: {
flags: {
$each: newFlags
}
}
}, {}, next);
};
updateMailboxFlags(() => {
if (updated) {
db.database.collection('messages').findOneAndUpdate({
_id: message._id
@ -544,7 +574,7 @@ server.onStore = function (path, update, session, callback) {
} else {
processNext();
}
});
});
};