diff --git a/src/mail.js b/src/mail.js index ea8401a7e..c61b681e1 100644 --- a/src/mail.js +++ b/src/mail.js @@ -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'); @@ -903,17 +902,16 @@ function addMailbox(name, domain, userId, callback) { assert.strictEqual(typeof userId, 'string'); assert.strictEqual(typeof callback, 'function'); - // sanity check if the group exists - user.get(userId, function (error) { - if (error && error.reason === UserError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such user')); + name = name.toLowerCase(); + + var error = validateName(name); + if (error) return callback(error); + + mailboxdb.addMailbox(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)); - mailboxdb.addMailbox(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)); - - callback(null); - }); + callback(null); }); } @@ -923,6 +921,11 @@ function updateMailbox(name, domain, userId, callback) { assert.strictEqual(typeof userId, 'string'); assert.strictEqual(typeof callback, 'function'); + name = name.toLowerCase(); + + var error = validateName(name); + if (error) return callback(error); + mailboxdb.updateMailbox(name, domain, userId, mailboxdb.TYPE_USER, 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)); @@ -1019,13 +1022,25 @@ function getList(domain, listName, callback) { }); } -function addList(domain, listName, members, callback) { +function addList(name, domain, members, callback) { assert.strictEqual(typeof domain, 'string'); - assert.strictEqual(typeof listName, 'string'); + assert.strictEqual(typeof name, 'string'); assert(Array.isArray(members)); assert.strictEqual(typeof callback, 'function'); - mailboxdb.addGroup(listName, domain, members, function (error) { + name = name.toLowerCase(); + + var error = validateName(name); + if (error) return callback(error); + + for (var i = 0; i < members.length; i++) { + members[i] = members[i].toLowerCase(); + + error = validateName(members[i]); + if (error) return callback(error); + } + + mailboxdb.addGroup(name, domain, members, function (error) { if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new MailError(MailError.ALREADY_EXISTS, 'list already exits')); if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); @@ -1039,6 +1054,18 @@ function updateList(name, domain, members, callback) { assert(Array.isArray(members)); assert.strictEqual(typeof callback, 'function'); + name = name.toLowerCase(); + + var error = validateName(name); + if (error) return callback(error); + + for (var i = 0; i < members.length; i++) { + members[i] = members[i].toLowerCase(); + + error = validateName(members[i]); + if (error) return callback(error); + } + mailboxdb.updateList(name, domain, members, 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)); diff --git a/src/routes/mail.js b/src/routes/mail.js index 12aff79af..23e763290 100644 --- a/src/routes/mail.js +++ b/src/routes/mail.js @@ -233,6 +233,7 @@ function addMailbox(req, res, next) { 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 && error.reason === MailError.BAD_FIELD) return next(new HttpError(400, error.message)); if (error) return next(new HttpError(500, error)); next(new HttpSuccess(201, {})); @@ -247,6 +248,7 @@ function updateMailbox(req, res, next) { mail.updateMailbox(req.params.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.BAD_FIELD) return next(new HttpError(400, error.message)); if (error) return next(new HttpError(500, error)); next(new HttpSuccess(204)); @@ -343,9 +345,10 @@ function addList(req, res, next) { if (typeof req.body.members[i] !== 'string') return next(new HttpError(400, 'member must be a string')); } - mail.addList(req.params.domain, req.body.name, req.body.members, function (error) { + mail.addList(req.body.name, req.params.domain, req.body.members, 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, 'list already exists')); + if (error && error.reason === MailError.BAD_FIELD) return next(new HttpError(400, error.message)); if (error) return next(new HttpError(500, error)); next(new HttpSuccess(201, {})); @@ -364,6 +367,7 @@ function updateList(req, res, next) { mail.updateList(req.params.name, req.params.domain, req.body.members, function (error) { if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); + if (error && error.reason === MailError.BAD_FIELD) return next(new HttpError(400, error.message)); if (error) return next(new HttpError(500, error)); next(new HttpSuccess(204)); diff --git a/src/routes/test/mail-test.js b/src/routes/test/mail-test.js index 1beb49645..742dbdb9e 100644 --- a/src/routes/test/mail-test.js +++ b/src/routes/test/mail-test.js @@ -30,7 +30,6 @@ var USERNAME = 'superadmin', PASSWORD = 'Foobar?1337', EMAIL ='silly@me.com', MA const GROUP_NAME = 'maillistgroup', LIST_NAME = 'devs'; var token = null; var userId = ''; -var groupObject = null; function setup(done) { config._reset(); @@ -673,16 +672,6 @@ describe('Mail API', function () { }); }); - it('add fails if user does not exist', function (done) { - superagent.post(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/mailboxes') - .send({ name: MAILBOX_NAME, userId: userId + 'oops' }) - .query({ access_token: token }) - .end(function (err, res) { - expect(res.statusCode).to.equal(404); - done(); - }); - }); - it('add/enable succeeds', function (done) { superagent.post(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/mailboxes') .send({ name: MAILBOX_NAME, userId: userId }) @@ -902,25 +891,6 @@ describe('Mail API', function () { expect(res.statusCode).to.equal(201); done(); }); - }, - function (done) { - superagent.post(SERVER_URL + '/api/v1/groups') - .query({ access_token: token }) - .send({ name: GROUP_NAME}) - .end(function (error, result) { - expect(result.statusCode).to.equal(201); - groupObject = result.body; - done(); - }); - }, - function (done) { - superagent.put(SERVER_URL + '/api/v1/users/' + userId + '/groups') - .query({ access_token: token }) - .send({ groupIds: [ 'admin', groupObject.id ]}) - .end(function (error, result) { - expect(result.statusCode).to.equal(204); - done(); - }); } ], done); }); @@ -958,19 +928,29 @@ describe('Mail API', function () { }); }); - it('add fails with non-existing groupId', function (done) { + it('add fails without members array', function (done) { superagent.post(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/lists') - .send({ name: LIST_NAME, groupId: 'doesnotexist' }) + .send({ name: LIST_NAME }) .query({ access_token: token }) .end(function (err, res) { - expect(res.statusCode).to.equal(404); + expect(res.statusCode).to.equal(400); + done(); + }); + }); + + it('cannot add reserved group', function (done) { + superagent.post(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/lists') + .send({ name: LIST_NAME, members: [ 'Admin', USERNAME ]}) + .query({ access_token: token }) + .end(function (err, res) { + expect(res.statusCode).to.equal(400); done(); }); }); it('add succeeds', function (done) { superagent.post(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/lists') - .send({ name: LIST_NAME, groupId: groupObject.id }) + .send({ name: LIST_NAME, members: [ 'admin2', USERNAME ]}) .query({ access_token: token }) .end(function (err, res) { expect(res.statusCode).to.equal(201); @@ -980,7 +960,7 @@ describe('Mail API', function () { it('add twice fails', function (done) { superagent.post(SERVER_URL + '/api/v1/mail/' + DOMAIN_0.domain + '/lists') - .send({ name: LIST_NAME, groupId: groupObject.id }) + .send({ name: LIST_NAME, members: [ 'admin2', USERNAME ] }) .query({ access_token: token }) .end(function (err, res) { expect(res.statusCode).to.equal(409); @@ -1004,11 +984,11 @@ describe('Mail API', function () { expect(res.statusCode).to.equal(200); expect(res.body.list).to.be.an('object'); expect(res.body.list.name).to.equal(LIST_NAME); - expect(res.body.list.ownerId).to.equal(groupObject.id); + expect(res.body.list.ownerId).to.equal('admin'); expect(res.body.list.ownerType).to.equal('group'); expect(res.body.list.aliasTarget).to.equal(null); expect(res.body.list.domain).to.equal(DOMAIN_0.domain); - expect(res.body.list.members).to.eql([ 'superadmin' ]); + expect(res.body.list.members).to.eql([ 'admin2', 'superadmin' ]); done(); }); }); @@ -1021,10 +1001,11 @@ describe('Mail API', function () { expect(res.body.lists).to.be.an(Array); expect(res.body.lists.length).to.equal(1); expect(res.body.lists[0].name).to.equal(LIST_NAME); - expect(res.body.lists[0].ownerId).to.equal(groupObject.id); + expect(res.body.lists[0].ownerId).to.equal('admin'); expect(res.body.lists[0].ownerType).to.equal('group'); expect(res.body.lists[0].aliasTarget).to.equal(null); expect(res.body.lists[0].domain).to.equal(DOMAIN_0.domain); + expect(res.body.lists[0].members).to.eql([ 'admin2', 'superadmin' ]); done(); }); });