diff --git a/src/mail.js b/src/mail.js index 30fe35fd4..0143361ac 100644 --- a/src/mail.js +++ b/src/mail.js @@ -23,13 +23,13 @@ exports = module.exports = { getMailboxes: getMailboxes, removeMailboxes: removeMailboxes, - getUserMailbox: getUserMailbox, - enableUserMailbox: enableUserMailbox, - disableUserMailbox: disableUserMailbox, + getMailbox: getMailbox, + addMailbox: addMailbox, + removeMailbox: removeMailbox, + listAliases: listAliases, getAliases: getAliases, - getUserAliases: getUserAliases, - setUserAliases: setUserAliases, + setAliases: setAliases, getLists: getLists, getList: getList, @@ -66,7 +66,6 @@ var assert = require('assert'), smtpTransport = require('nodemailer-smtp-transport'), sysinfo = require('./sysinfo.js'), user = require('./user.js'), - UserError = user.UserError, util = require('util'), _ = require('underscore'); @@ -884,85 +883,67 @@ function removeMailboxes(domain, callback) { }); } -function getUserMailbox(domain, userId, callback) { - assert.strictEqual(typeof domain, 'string'); - assert.strictEqual(typeof userId, 'string'); - assert.strictEqual(typeof callback, 'function'); - - user.get(userId, function (error, result) { - if (error && error.reason === UserError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such user')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); - if (!result.username) return callback(new MailError(MailError.NOT_FOUND, 'no such mailbox')); - - mailboxdb.getMailbox(result.username, domain, function (error, result) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such mailbox')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); - - callback(null, result); - }); - }); -} - -function enableUserMailbox(domain, userId, callback) { - assert.strictEqual(typeof domain, 'string'); - assert.strictEqual(typeof userId, 'string'); - assert.strictEqual(typeof callback, 'function'); - - user.get(userId, function (error, result) { - if (error && error.reason === UserError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such user')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR)); - if (!result.username) return callback(new MailError(MailError.NOT_FOUND, 'user has no username')); - - mailboxdb.add(result.username, domain, userId, mailboxdb.TYPE_USER, function (error) { - if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new MailError(MailError.ALREADY_EXISTS, 'mailbox already exists')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); - - callback(null); - }); - }); -} - -function disableUserMailbox(domain, userId, callback) { - assert.strictEqual(typeof domain, 'string'); - assert.strictEqual(typeof userId, 'string'); - assert.strictEqual(typeof callback, 'function'); - - user.get(userId, function (error, result) { - if (error && error.reason === UserError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such user')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); - if (!result.username) return callback(new MailError(MailError.NOT_FOUND, 'user has no username')); - - mailboxdb.del(result.username, domain, function (error) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such mailbox')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); - - callback(null); - }); - }); -} - -function getAliases(domain, callback) { +function getMailbox(name, domain, callback) { + assert.strictEqual(typeof name, 'string'); assert.strictEqual(typeof domain, 'string'); assert.strictEqual(typeof callback, 'function'); - mailboxdb.listAliases(domain, function (error, result) { + mailboxdb.getMailbox(name, domain, function (error, result) { + if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such mailbox')); if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); callback(null, result); }); } -function getUserAliases(domain, userId, callback) { +function addMailbox(name, domain, userId, callback) { + assert.strictEqual(typeof name, 'string'); assert.strictEqual(typeof domain, 'string'); assert.strictEqual(typeof userId, 'string'); assert.strictEqual(typeof callback, 'function'); - user.get(userId, function (error, result) { - if (error && error.reason === UserError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such user')); + mailboxdb.add(name, domain, userId, mailboxdb.TYPE_USER, function (error) { + if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new MailError(MailError.ALREADY_EXISTS, 'mailbox already exists')); if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); - if (!result.username) return callback(new MailError(MailError.NOT_FOUND, 'user has no username')); - mailboxdb.getAliasesForName(result.username, domain, function (error, aliases) { + callback(null); + }); +} + +function removeMailbox(name, domain, callback) { + assert.strictEqual(typeof domain, 'string'); + assert.strictEqual(typeof name, 'string'); + assert.strictEqual(typeof callback, 'function'); + + mailboxdb.del(name, domain, function (error) { + if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such mailbox')); + if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + + callback(null); + }); +} + +function listAliases(domain, callback) { + assert.strictEqual(typeof domain, 'string'); + assert.strictEqual(typeof callback, 'function'); + + mailboxdb.listAliases(domain, function (error, result) { + if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, error.message)); + if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + + callback(null, result); + }); +} + +function getAliases(name, domain, callback) { + assert.strictEqual(typeof name, 'string'); + assert.strictEqual(typeof domain, 'string'); + assert.strictEqual(typeof callback, 'function'); + + getMailbox(name, domain, function (error) { + if (error) return callback(error); + + mailboxdb.getAliasesForName(name, domain, function (error, aliases) { if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such mailbox')); if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); @@ -971,9 +952,9 @@ function getUserAliases(domain, userId, callback) { }); } -function setUserAliases(domain, userId, aliases, callback) { +function setAliases(name, domain, aliases, callback) { + assert.strictEqual(typeof name, 'string'); assert.strictEqual(typeof domain, 'string'); - assert.strictEqual(typeof userId, 'string'); assert(Array.isArray(aliases)); assert.strictEqual(typeof callback, 'function'); @@ -984,18 +965,12 @@ function setUserAliases(domain, userId, aliases, callback) { if (error) return callback(error); } - user.get(userId, function (error, result) { - if (error && error.reason === UserError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such user')); + mailboxdb.setAliasesForName(name, domain, aliases, function (error) { + if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new MailError(MailError.ALREADY_EXISTS, error.message)); + if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such mailbox')); if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); - if (!result.username) return callback(new MailError(MailError.NOT_FOUND, 'user has no username')); - mailboxdb.setAliasesForName(result.username, domain, aliases, function (error) { - if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new MailError(MailError.ALREADY_EXISTS, error.message)); - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such mailbox')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); - - callback(null); - }); + callback(null); }); } diff --git a/src/routes/mail.js b/src/routes/mail.js index 0f13412af..11563f944 100644 --- a/src/routes/mail.js +++ b/src/routes/mail.js @@ -18,13 +18,13 @@ exports = module.exports = { sendTestMail: sendTestMail, getMailboxes: getMailboxes, - getUserMailbox: getUserMailbox, - enableUserMailbox: enableUserMailbox, - disableUserMailbox: disableUserMailbox, + getMailbox: getMailbox, + addMailbox: addMailbox, + removeMailbox: removeMailbox, + listAliases: listAliases, getAliases: getAliases, - getUserAliases: getUserAliases, - setUserAliases: setUserAliases, + setAliases: setAliases, getLists: getLists, getList: getList, @@ -211,11 +211,11 @@ function getMailboxes(req, res, next) { }); } -function getUserMailbox(req, res, next) { +function getMailbox(req, res, next) { assert.strictEqual(typeof req.params.domain, 'string'); - assert.strictEqual(typeof req.params.userId, 'string'); + assert.strictEqual(typeof req.params.name, 'string'); - mail.getUserMailbox(req.params.domain, req.params.userId, function (error, result) { + mail.getMailbox(req.params.name, req.params.domain, function (error, result) { if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); if (error) return next(new HttpError(500, error)); @@ -223,11 +223,13 @@ function getUserMailbox(req, res, next) { }); } -function enableUserMailbox(req, res, next) { +function addMailbox(req, res, next) { assert.strictEqual(typeof req.params.domain, 'string'); - assert.strictEqual(typeof req.params.userId, 'string'); - mail.enableUserMailbox(req.params.domain, req.params.userId, function (error) { + if (typeof req.body.name !== 'string') return next(new HttpError(400, 'name must be a string')); + if (typeof req.body.userId !== 'string') return next(new HttpError(400, 'userId must be a string')); + + mail.addMailbox(req.body.name, req.params.domain, req.body.userId, function (error) { if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); if (error && error.reason === MailError.ALREADY_EXISTS) return next(new HttpSuccess(201, {})); if (error) return next(new HttpError(500, error)); @@ -236,33 +238,22 @@ function enableUserMailbox(req, res, next) { }); } -function disableUserMailbox(req, res, next) { +function removeMailbox(req, res, next) { assert.strictEqual(typeof req.params.domain, 'string'); - assert.strictEqual(typeof req.params.userId, 'string'); + assert.strictEqual(typeof req.params.name, 'string'); - mail.disableUserMailbox(req.params.domain, req.params.userId, function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpSuccess(201, {})); + mail.removeMailbox(req.params.name, req.params.domain, function (error) { + if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); if (error) return next(new HttpError(500, error)); next(new HttpSuccess(201, {})); }); } -function getAliases(req, res, next) { +function listAliases(req, res, next) { assert.strictEqual(typeof req.params.domain, 'string'); - mail.getAliases(req.params.domain, function (error, result) { - if (error) return next(new HttpError(500, error)); - - next(new HttpSuccess(200, { aliases: result })); - }); -} - -function getUserAliases(req, res, next) { - assert.strictEqual(typeof req.params.domain, 'string'); - assert.strictEqual(typeof req.params.userId, 'string'); - - mail.getUserAliases(req.params.domain, req.params.userId, function (error, result) { + mail.listAliases(req.params.domain, function (error, result) { if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); if (error) return next(new HttpError(500, error)); @@ -270,9 +261,21 @@ function getUserAliases(req, res, next) { }); } -function setUserAliases(req, res, next) { +function getAliases(req, res, next) { assert.strictEqual(typeof req.params.domain, 'string'); - assert.strictEqual(typeof req.params.userId, 'string'); + assert.strictEqual(typeof req.params.name, 'string'); + + mail.getAliases(req.params.name, req.params.domain, function (error, result) { + if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); + if (error) return next(new HttpError(500, error)); + + next(new HttpSuccess(200, { aliases: result })); + }); +} + +function setAliases(req, res, next) { + assert.strictEqual(typeof req.params.domain, 'string'); + assert.strictEqual(typeof req.params.name, 'string'); assert.strictEqual(typeof req.body, 'object'); if (!Array.isArray(req.body.aliases)) return next(new HttpError(400, 'aliases must be an array')); @@ -281,7 +284,7 @@ function setUserAliases(req, res, next) { if (typeof req.body.aliases[i] !== 'string') return next(new HttpError(400, 'alias must be a string')); } - mail.setUserAliases(req.params.domain, req.params.userId, req.body.aliases, function (error) { + mail.setAliases(req.params.name, req.params.domain, req.body.aliases, function (error) { if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); if (error && error.reason === MailError.ALREADY_EXISTS) return next(new HttpError(409, error.message)); if (error && error.reason === MailError.BAD_FIELD) return next(new HttpError(400, error.message)); diff --git a/src/routes/test/mail-test.js b/src/routes/test/mail-test.js index 73838c924..b9927c029 100644 --- a/src/routes/test/mail-test.js +++ b/src/routes/test/mail-test.js @@ -26,7 +26,7 @@ const DOMAIN_0 = { fallbackCertificate: null, tlsConfig: { provider: 'fallback' } }; -var USERNAME = 'superadmin', PASSWORD = 'Foobar?1337', EMAIL ='silly@me.com'; +var USERNAME = 'superadmin', PASSWORD = 'Foobar?1337', EMAIL ='silly@me.com', MAILBOX_NAME = 'superman'; const GROUP_NAME = 'maillistgroup', LIST_NAME = 'devs'; var token = null; var userId = ''; @@ -683,7 +683,8 @@ describe('Mail API', function () { }); it('add/enable succeeds', function (done) { - superagent.post(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/mailboxes/' + userId) + superagent.post(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/mailboxes') + .send({ name: MAILBOX_NAME, userId: userId }) .query({ access_token: token }) .end(function (err, res) { expect(res.statusCode).to.equal(201); @@ -692,7 +693,8 @@ describe('Mail API', function () { }); it('enable again succeeds if already enabled', function (done) { - superagent.post(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/mailboxes/' + userId) + superagent.post(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/mailboxes') + .send({ name: MAILBOX_NAME, userId: userId }) .query({ access_token: token }) .end(function (err, res) { expect(res.statusCode).to.equal(201); @@ -710,12 +712,12 @@ describe('Mail API', function () { }); it('get succeeds', function (done) { - superagent.get(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/mailboxes/' + userId) + superagent.get(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/mailboxes/' + MAILBOX_NAME) .query({ access_token: token }) .end(function (err, res) { expect(res.statusCode).to.equal(200); expect(res.body.mailbox).to.be.an('object'); - expect(res.body.mailbox.name).to.equal(USERNAME); + expect(res.body.mailbox.name).to.equal(MAILBOX_NAME); expect(res.body.mailbox.ownerId).to.equal(userId); expect(res.body.mailbox.ownerType).to.equal('user'); expect(res.body.mailbox.aliasTarget).to.equal(null); @@ -731,7 +733,7 @@ describe('Mail API', function () { expect(res.statusCode).to.equal(200); expect(res.body.mailboxes.length).to.eql(1); expect(res.body.mailboxes[0]).to.be.an('object'); - expect(res.body.mailboxes[0].name).to.equal(USERNAME); + expect(res.body.mailboxes[0].name).to.equal(MAILBOX_NAME); expect(res.body.mailboxes[0].ownerId).to.equal(userId); expect(res.body.mailboxes[0].ownerType).to.equal('user'); expect(res.body.mailboxes[0].aliasTarget).to.equal(null); @@ -740,21 +742,21 @@ describe('Mail API', function () { }); }); - it('disable succeeds even if not exist', function (done) { + it('disable fails even if not exist', function (done) { superagent.del(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/mailboxes/' + 'someuserdoesnotexist') .query({ access_token: token }) .end(function (err, res) { - expect(res.statusCode).to.equal(201); + expect(res.statusCode).to.equal(404); done(); }); }); it('disable succeeds', function (done) { - superagent.del(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/mailboxes/' + userId) + superagent.del(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/mailboxes/' + MAILBOX_NAME) .query({ access_token: token }) .end(function (err, res) { expect(res.statusCode).to.equal(201); - superagent.get(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/mailboxes/' + userId) + superagent.get(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/mailboxes/' + MAILBOX_NAME) .query({ access_token: token }) .end(function (err, res) { expect(res.statusCode).to.equal(404); @@ -790,7 +792,7 @@ describe('Mail API', function () { }); it('set fails if aliases is missing', function (done) { - superagent.put(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/aliases/' + userId) + superagent.put(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/aliases/' + MAILBOX_NAME) .query({ access_token: token }) .end(function (err, res) { expect(res.statusCode).to.equal(400); @@ -809,7 +811,7 @@ describe('Mail API', function () { }); it('set fails if aliases is the wrong type', function (done) { - superagent.put(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/aliases/' + userId) + superagent.put(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/aliases/' + MAILBOX_NAME) .send({ aliases: 'hello, there' }) .query({ access_token: token }) .end(function (err, res) { @@ -819,7 +821,7 @@ describe('Mail API', function () { }); it('set fails if user is not enabled', function (done) { - superagent.put(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/aliases/' + userId) + superagent.put(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/aliases/' + MAILBOX_NAME) .send({ aliases: ['hello', 'there'] }) .query({ access_token: token }) .end(function (err, res) { @@ -828,8 +830,9 @@ describe('Mail API', function () { }); }); - it('now enable the user', function (done) { - superagent.post(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/mailboxes/' + userId) + it('now add the mailbox', function (done) { + superagent.post(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/mailboxes') + .send({ name: MAILBOX_NAME, userId: userId }) .query({ access_token: token }) .end(function (err, res) { expect(res.statusCode).to.equal(201); @@ -838,7 +841,7 @@ describe('Mail API', function () { }); it('set succeeds', function (done) { - superagent.put(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/aliases/' + userId) + superagent.put(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/aliases/' + MAILBOX_NAME) .send({ aliases: ['hello', 'there'] }) .query({ access_token: token }) .end(function (err, res) { @@ -848,7 +851,7 @@ describe('Mail API', function () { }); it('get succeeds', function (done) { - superagent.get(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/aliases/' + userId) + superagent.get(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/aliases/' + MAILBOX_NAME) .query({ access_token: token }) .end(function (err, res) { expect(res.statusCode).to.equal(200); @@ -857,7 +860,27 @@ describe('Mail API', function () { }); }); - it('get succeeds if mailbox does not exist', function (done) { + it('listing succeeds', function (done) { + superagent.get(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/aliases') + .query({ access_token: token }) + .end(function (err, res) { + expect(res.statusCode).to.equal(200); + expect(res.body.aliases.length).to.eql(2); + expect(res.body.aliases[0].name).to.equal('hello'); + expect(res.body.aliases[0].ownerId).to.equal(userId); + expect(res.body.aliases[0].ownerType).to.equal('user'); + expect(res.body.aliases[0].aliasTarget).to.equal(MAILBOX_NAME); + expect(res.body.aliases[0].domain).to.equal(DOMAIN_0.domain); + expect(res.body.aliases[1].name).to.equal('there'); + expect(res.body.aliases[1].ownerId).to.equal(userId); + expect(res.body.aliases[1].ownerType).to.equal('user'); + expect(res.body.aliases[1].aliasTarget).to.equal(MAILBOX_NAME); + expect(res.body.aliases[1].domain).to.equal(DOMAIN_0.domain); + done(); + }); + }); + + it('get fails if mailbox does not exist', function (done) { superagent.get(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/aliases/' + 'someuserdoesnotexist') .query({ access_token: token }) .end(function (err, res) { diff --git a/src/server.js b/src/server.js index 4a7b0a443..2a47e384c 100644 --- a/src/server.js +++ b/src/server.js @@ -226,12 +226,12 @@ function initializeExpressSync() { router.post('/api/v1/mail/:domain/enable', settingsScope, routes.user.requireAdmin, routes.mail.setMailEnabled); router.post('/api/v1/mail/:domain/send_test_mail', settingsScope, routes.user.requireAdmin, routes.mail.sendTestMail); router.get ('/api/v1/mail/:domain/mailboxes', settingsScope, routes.user.requireAdmin, routes.mail.getMailboxes); - router.get ('/api/v1/mail/:domain/mailboxes/:userId', settingsScope, routes.user.requireAdmin, routes.mail.getUserMailbox); - router.post('/api/v1/mail/:domain/mailboxes/:userId', settingsScope, routes.user.requireAdmin, routes.mail.enableUserMailbox); - router.del ('/api/v1/mail/:domain/mailboxes/:userId', settingsScope, routes.user.requireAdmin, routes.mail.disableUserMailbox); - router.get ('/api/v1/mail/:domain/aliases', settingsScope, routes.user.requireAdmin, routes.mail.getAliases); - router.get ('/api/v1/mail/:domain/aliases/:userId', settingsScope, routes.user.requireAdmin, routes.mail.getUserAliases); - router.put ('/api/v1/mail/:domain/aliases/:userId', settingsScope, routes.user.requireAdmin, routes.mail.setUserAliases); + router.get ('/api/v1/mail/:domain/mailboxes/:name', settingsScope, routes.user.requireAdmin, routes.mail.getMailbox); + router.post('/api/v1/mail/:domain/mailboxes', settingsScope, routes.user.requireAdmin, routes.mail.addMailbox); + router.del ('/api/v1/mail/:domain/mailboxes/:name', settingsScope, routes.user.requireAdmin, routes.mail.removeMailbox); + router.get ('/api/v1/mail/:domain/aliases', settingsScope, routes.user.requireAdmin, routes.mail.listAliases); + router.get ('/api/v1/mail/:domain/aliases/:name', settingsScope, routes.user.requireAdmin, routes.mail.getAliases); + router.put ('/api/v1/mail/:domain/aliases/:name', settingsScope, routes.user.requireAdmin, routes.mail.setAliases); router.get ('/api/v1/mail/:domain/lists', settingsScope, routes.user.requireAdmin, routes.mail.getLists); router.post('/api/v1/mail/:domain/lists', settingsScope, routes.user.requireAdmin, routes.mail.addList); router.get ('/api/v1/mail/:domain/lists/:name', settingsScope, routes.user.requireAdmin, routes.mail.getList);