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 roles = require('../roles');
const util = require('util');
const imapTools = require('../../imap-core/lib/imap-tools');
const pwnedpasswords = require('pwnedpasswords');
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} [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 {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} [ip] IP address for the logs
*
@ -486,6 +493,21 @@ module.exports = (db, server, userHandler) => {
.falsy(['N', 'false', 'no', 'off', '0', 0, ''])
.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()
.empty('')
.trim()
@ -633,6 +655,28 @@ module.exports = (db, server, userHandler) => {
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 {
await checkPubKey(result.value.pubKey);
} catch (err) {

View file

@ -1191,7 +1191,7 @@ class UserHandler {
return callback(err);
}
let mailboxes = this.getMailboxes(data.language).map(mailbox => {
let mailboxes = this.getMailboxes(data.language, data.mailboxes).map(mailbox => {
mailbox.user = id;
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 defaultMailboxes = [
@ -2808,7 +2809,7 @@ class UserHandler {
let uidValidity = Math.floor(Date.now() / 1000);
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,
uidValidity,
uidNext: 1,

View file

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