Allow setting default retention to all mailboxes

This commit is contained in:
Andris Reinman 2017-05-22 10:03:30 +03:00
parent 383bc4d4cb
commit 8d03e37ac7
5 changed files with 63 additions and 22 deletions

View file

@ -179,6 +179,7 @@ Arguments
- **username** is the username of the user. This is not an email address but authentication username, use only letters and numbers - **username** is the username of the user. This is not an email address but authentication username, use only letters and numbers
- **password** is the password for the user - **password** is the password for the user
- **quota** (optional) is the maximum storage in bytes allowed for this user. If not set then the default value is used - **quota** (optional) is the maximum storage in bytes allowed for this user. If not set then the default value is used
- **retention** (optional) is the default retention time in ms for mailboxes. Messages in Trash and Junk folders have a maximum retention time of 30 days.
**Example** **Example**

View file

@ -1,5 +1,7 @@
'use strict'; 'use strict';
const os = require('os');
module.exports = { module.exports = {
log: { log: {
level: 'silly' level: 'silly'
@ -95,5 +97,7 @@ module.exports = {
maxRecipients: 2000, maxRecipients: 2000,
// default forwarded messages for 24h (can be overriden per user) // default forwarded messages for 24h (can be overriden per user)
maxForwards: 2000 maxForwards: 2000,
emailDomain: os.hostname()
}; };

44
imap.js
View file

@ -195,21 +195,34 @@ server.onCreate = function (path, session, callback) {
return callback(null, 'ALREADYEXISTS'); return callback(null, 'ALREADYEXISTS');
} }
mailbox = { db.database.collection('users').findOne({
user: session.user.id, _id: session.user.id
path, }, {
uidValidity: Math.floor(Date.now() / 1000), fields: {
uidNext: 1, retention: true
modifyIndex: 0, }
subscribed: true, }, (err, user) => {
flags: []
};
db.database.collection('mailboxes').insertOne(mailbox, err => {
if (err) { if (err) {
return callback(err); return callback(err);
} }
return callback(null, true);
mailbox = {
user: session.user.id,
path,
uidValidity: Math.floor(Date.now() / 1000),
uidNext: 1,
modifyIndex: 0,
subscribed: true,
flags: [],
retention: user.retention
};
db.database.collection('mailboxes').insertOne(mailbox, err => {
if (err) {
return callback(err);
}
return callback(null, true);
});
}); });
}); });
}; };
@ -1005,8 +1018,9 @@ server.onCopy = function (path, update, session, callback) {
message.mailbox = target._id; message.mailbox = target._id;
message.uid = uidNext; message.uid = uidNext;
message.exp = ['\\Trash', '\\Junk'].includes(target.specialUse); // retention settings
message.rdate = new Date(); message.exp = !!target.retention;
message.rdate = Date.now() + (target.retention || 0);
if (!message.meta) { if (!message.meta) {
message.meta = {}; message.meta = {};
@ -1778,7 +1792,7 @@ function clearExpiredMessages() {
let cursor = db.database.collection('messages').find({ let cursor = db.database.collection('messages').find({
exp: true, exp: true,
rdate: { rdate: {
$lte: new Date(Date.now() - config.imap.retention * 24 * 3600 * 1000) $lte: Date.now()
} }
}).project({ }).project({
_id: true, _id: true,

View file

@ -246,9 +246,9 @@ class MessageHandler {
_id: id, _id: id,
// if true then expirest after rdate + retention // if true then expirest after rdate + retention
exp: ['\\Trash', '\\Junk'].includes(mailbox.specialUse), exp: !!mailbox.retention,
rdate: Date.now() + (mailbox.retention || 0),
rdate: new Date(),
idate, idate,
hdate, hdate,
flags, flags,
@ -630,9 +630,9 @@ class MessageHandler {
// this will be changed later by the notification system // this will be changed later by the notification system
modseq: 0, modseq: 0,
// if exp=true, then remove message after rdate + retention ploicy // retention settings
exp: ['\\Trash', '\\Junk'].includes(target.specialUse), exp: !!target.retention,
rdate: new Date() rdate: Date.now() + (target.retention || 0)
} }
}; };

View file

@ -13,6 +13,7 @@ const base32 = require('base32.js');
const MAX_STORAGE = 1 * (1024 * 1024 * 1024); const MAX_STORAGE = 1 * (1024 * 1024 * 1024);
const MAX_RECIPIENTS = 2000; const MAX_RECIPIENTS = 2000;
const MAX_FORWARDS = 2000; const MAX_FORWARDS = 2000;
const JUNK_RETENTION = 30 * 24 * 3600 * 1000;
const mailboxTranslations = { const mailboxTranslations = {
en: { en: {
@ -48,6 +49,11 @@ class UserHandler {
meta = {}; meta = {};
} }
if (!password) {
// do not allow signing in without a password
return callback(null, false);
}
let checkAddress = next => { let checkAddress = next => {
if (username.indexOf('@') < 0) { if (username.indexOf('@') < 0) {
// assume regular username // assume regular username
@ -206,8 +212,14 @@ class UserHandler {
return callback(err); return callback(err);
} }
let retention = Number(data.retention) || 0;
let junkRetention = JUNK_RETENTION;
if (retention < 0) {
retention = 0;
}
// Insert // Insert
let hash = bcrypt.hashSync(data.password, 11); let hash = data.password ? bcrypt.hashSync(data.password, 11) : '';
this.database.collection('users').insertOne({ this.database.collection('users').insertOne({
username: data.username, username: data.username,
name: data.name, name: data.name,
@ -230,6 +242,9 @@ class UserHandler {
filters: [], filters: [],
// default retention for user mailboxes
retention,
created: new Date(), created: new Date(),
// until setup value is not true, this account is not usable // until setup value is not true, this account is not usable
@ -244,6 +259,13 @@ class UserHandler {
let mailboxes = this.getMailboxes(data.language).map(mailbox => { let mailboxes = this.getMailboxes(data.language).map(mailbox => {
mailbox.user = user; mailbox.user = user;
if (['\\Trash', '\\Junk'].includes(mailbox.specialUse)) {
mailbox.retention = retention ? Math.min(retention, junkRetention) : junkRetention;
} else {
mailbox.retention = retention;
}
return mailbox; return mailbox;
}); });