This commit is contained in:
Andris Reinman 2018-10-01 13:28:27 +03:00
parent 06f269668e
commit bd5615e8ed
7 changed files with 56 additions and 11 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
define({ "name": "wildduck", "version": "1.0.0", "description": "WildDuck API docs", "title": "WildDuck API", "url": "https://api.wildduck.email", "sampleUrl": false, "defaultVersion": "0.0.0", "apidoc": "0.3.0", "generator": { "name": "apidoc", "time": "2018-09-28T09:22:47.027Z", "url": "http://apidocjs.com", "version": "0.17.6" } }); define({ "name": "wildduck", "version": "1.0.0", "description": "WildDuck API docs", "title": "WildDuck API", "url": "https://api.wildduck.email", "sampleUrl": false, "defaultVersion": "0.0.0", "apidoc": "0.3.0", "generator": { "name": "apidoc", "time": "2018-10-01T10:28:17.847Z", "url": "http://apidocjs.com", "version": "0.17.6" } });

View file

@ -1 +1 @@
{ "name": "wildduck", "version": "1.0.0", "description": "WildDuck API docs", "title": "WildDuck API", "url": "https://api.wildduck.email", "sampleUrl": false, "defaultVersion": "0.0.0", "apidoc": "0.3.0", "generator": { "name": "apidoc", "time": "2018-09-28T09:22:47.027Z", "url": "http://apidocjs.com", "version": "0.17.6" } } { "name": "wildduck", "version": "1.0.0", "description": "WildDuck API docs", "title": "WildDuck API", "url": "https://api.wildduck.email", "sampleUrl": false, "defaultVersion": "0.0.0", "apidoc": "0.3.0", "generator": { "name": "apidoc", "time": "2018-10-01T10:28:17.847Z", "url": "http://apidocjs.com", "version": "0.17.6" } }

View file

@ -12,6 +12,7 @@ const libmime = require('libmime');
const consts = require('../consts'); const consts = require('../consts');
const roles = require('../roles'); const roles = require('../roles');
const util = require('util'); const util = require('util');
const imapTools = require('../../imap-core/lib/imap-tools');
const pwnedpasswords = require('pwnedpasswords'); const pwnedpasswords = require('pwnedpasswords');
module.exports = (db, server, userHandler) => { module.exports = (db, server, userHandler) => {
@ -340,6 +341,12 @@ module.exports = (db, server, userHandler) => {
* @apiParam {Number} [imapMaxDownload] How many bytes can be downloaded via IMAP during 24 hour * @apiParam {Number} [imapMaxDownload] How many bytes can be downloaded via IMAP during 24 hour
* @apiParam {Number} [pop3MaxDownload] How many bytes can be downloaded via POP3 during 24 hour * @apiParam {Number} [pop3MaxDownload] How many bytes can be downloaded via POP3 during 24 hour
* @apiParam {Number} [receivedMax] How many messages can be received from MX during 1 hour * @apiParam {Number} [receivedMax] How many messages can be received from MX during 1 hour
* @apiParam {Object} [mailboxes] Optional names for special mailboxes
* @apiParam {String} [mailboxes.sent="Sent Mail"] Path of Sent Mail folder
* @apiParam {String} [mailboxes.junk="Junk"] Path of spam folder
* @apiParam {String} [mailboxes.drafts="Drafts"] Path of drafts folder
* @apiParam {String} [mailboxes.trash="Trash"] Path of trash folder
* @apiParam {String} reference.mailbox Mailbox ID
* @apiParam {String} [sess] Session identifier for the logs * @apiParam {String} [sess] Session identifier for the logs
* @apiParam {String} [ip] IP address for the logs * @apiParam {String} [ip] IP address for the logs
* *
@ -486,6 +493,21 @@ module.exports = (db, server, userHandler) => {
.falsy(['N', 'false', 'no', 'off', '0', 0, '']) .falsy(['N', 'false', 'no', 'off', '0', 0, ''])
.default(false), .default(false),
mailboxes: Joi.object().keys({
sent: Joi.string()
.empty('')
.regex(/\/{2,}|\/$/g, { invert: true }),
trash: Joi.string()
.empty('')
.regex(/\/{2,}|\/$/g, { invert: true }),
junk: Joi.string()
.empty('')
.regex(/\/{2,}|\/$/g, { invert: true }),
drafts: Joi.string()
.empty('')
.regex(/\/{2,}|\/$/g, { invert: true })
}),
pubKey: Joi.string() pubKey: Joi.string()
.empty('') .empty('')
.trim() .trim()
@ -633,6 +655,28 @@ module.exports = (db, server, userHandler) => {
return next(); return next();
} }
if (result.value.mailboxes) {
let seen = new Set(['INBOX']);
for (let key of ['sent', 'junk', 'trash', 'drafts']) {
if (!result.value.mailboxes[key]) {
continue;
}
result.value.mailboxes[key] = imapTools.normalizeMailbox(result.value.mailboxes[key]);
if (seen.has(result.value.mailboxes[key])) {
res.json({
error: 'Duplicate mailbox name: ' + result.value.mailboxes[key],
code: 'InputValidationError'
});
return next();
}
seen.add(result.value.mailboxes[key]);
// rename key to use specialUse format ("seen"->"\\Seen")
delete result.value.mailboxes[key];
result.value.mailboxes[key.replace(/^./, c => '\\' + c.toUpperCase())] = result.value.mailboxes[key];
}
}
try { try {
await checkPubKey(result.value.pubKey); await checkPubKey(result.value.pubKey);
} catch (err) { } catch (err) {

View file

@ -1191,7 +1191,7 @@ class UserHandler {
return callback(err); return callback(err);
} }
let mailboxes = this.getMailboxes(data.language).map(mailbox => { let mailboxes = this.getMailboxes(data.language, data.mailboxes).map(mailbox => {
mailbox.user = id; mailbox.user = id;
if (['\\Trash', '\\Junk'].includes(mailbox.specialUse)) { if (['\\Trash', '\\Junk'].includes(mailbox.specialUse)) {
@ -2784,7 +2784,8 @@ class UserHandler {
}); });
} }
getMailboxes(language) { getMailboxes(language, defaults) {
defaults = defaults || {};
let translation = mailboxTranslations.hasOwnProperty(language) ? mailboxTranslations[language] : mailboxTranslations.en; let translation = mailboxTranslations.hasOwnProperty(language) ? mailboxTranslations[language] : mailboxTranslations.en;
let defaultMailboxes = [ let defaultMailboxes = [
@ -2808,7 +2809,7 @@ class UserHandler {
let uidValidity = Math.floor(Date.now() / 1000); let uidValidity = Math.floor(Date.now() / 1000);
return defaultMailboxes.map(mailbox => ({ return defaultMailboxes.map(mailbox => ({
path: mailbox.path === 'INBOX' ? 'INBOX' : translation[mailbox.specialUse || mailbox.path] || mailbox.path, path: mailbox.path === 'INBOX' ? 'INBOX' : defaults[mailbox.specialUse] || translation[mailbox.specialUse || mailbox.path] || mailbox.path,
specialUse: mailbox.specialUse, specialUse: mailbox.specialUse,
uidValidity, uidValidity,
uidNext: 1, uidNext: 1,

View file

@ -1,6 +1,6 @@
{ {
"name": "wildduck", "name": "wildduck",
"version": "1.4.21", "version": "1.4.22",
"description": "IMAP/POP3 server built with Node.js and MongoDB", "description": "IMAP/POP3 server built with Node.js and MongoDB",
"main": "server.js", "main": "server.js",
"scripts": { "scripts": {
@ -19,8 +19,8 @@
"ajv": "6.5.4", "ajv": "6.5.4",
"apidoc": "0.17.6", "apidoc": "0.17.6",
"browserbox": "0.9.1", "browserbox": "0.9.1",
"chai": "4.1.2", "chai": "4.2.0",
"eslint": "5.6.0", "eslint": "5.6.1",
"eslint-config-nodemailer": "1.2.0", "eslint-config-nodemailer": "1.2.0",
"eslint-config-prettier": "3.1.0", "eslint-config-prettier": "3.1.0",
"grunt": "1.0.3", "grunt": "1.0.3",
@ -49,7 +49,7 @@
"ioredfour": "1.0.2-ioredis-02", "ioredfour": "1.0.2-ioredis-02",
"ioredis": "4.0.0", "ioredis": "4.0.0",
"isemail": "3.1.3", "isemail": "3.1.3",
"joi": "13.6.0", "joi": "13.7.0",
"js-yaml": "3.12.0", "js-yaml": "3.12.0",
"key-fingerprint": "1.1.0", "key-fingerprint": "1.1.0",
"libbase64": "1.0.3", "libbase64": "1.0.3",