diff --git a/src/routes/index.js b/src/routes/index.js index 3da01ba40..1e112aacc 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -12,6 +12,7 @@ exports = module.exports = { graphs: require('./graphs.js'), groups: require('./groups.js'), oauth2: require('./oauth2.js'), + mail: require('./mail.js'), profile: require('./profile.js'), sysadmin: require('./sysadmin.js'), settings: require('./settings.js'), diff --git a/src/routes/mail.js b/src/routes/mail.js new file mode 100644 index 000000000..d2dc6efd2 --- /dev/null +++ b/src/routes/mail.js @@ -0,0 +1,17 @@ +'use strict'; + +exports = module.exports = { + getStatus: getStatus +}; + +var mail = require('../mail.js'), + HttpError = require('connect-lastmile').HttpError, + HttpSuccess = require('connect-lastmile').HttpSuccess; + +function getStatus(req, res, next) { + mail.getStatus(function (error, records) { + if (error) return next(new HttpError(500, error)); + + next(new HttpSuccess(200, records)); + }); +} diff --git a/src/routes/settings.js b/src/routes/settings.js index 052dfdd0e..86de14da2 100644 --- a/src/routes/settings.js +++ b/src/routes/settings.js @@ -10,8 +10,6 @@ exports = module.exports = { getCloudronAvatar: getCloudronAvatar, setCloudronAvatar: setCloudronAvatar, - getEmailStatus: getEmailStatus, - getBackupConfig: getBackupConfig, setBackupConfig: setBackupConfig, @@ -39,7 +37,6 @@ exports = module.exports = { var assert = require('assert'), certificates = require('../certificates.js'), CertificatesError = require('../certificates.js').CertificatesError, - mail = require('../mail.js'), HttpError = require('connect-lastmile').HttpError, HttpSuccess = require('connect-lastmile').HttpSuccess, safe = require('safetydance'), @@ -226,14 +223,6 @@ function getCloudronAvatar(req, res, next) { }); } -function getEmailStatus(req, res, next) { - mail.getStatus(function (error, records) { - if (error) return next(new HttpError(500, error)); - - next(new HttpSuccess(200, records)); - }); -} - function getBackupConfig(req, res, next) { settings.getBackupConfig(function (error, config) { if (error) return next(new HttpError(500, error)); diff --git a/src/routes/test/mail-test.js b/src/routes/test/mail-test.js new file mode 100644 index 000000000..b1e0976f9 --- /dev/null +++ b/src/routes/test/mail-test.js @@ -0,0 +1,305 @@ +'use strict'; + +/* global it:false */ +/* global describe:false */ +/* global before:false */ +/* global after:false */ + +var async = require('async'), + cloudron = require('../../cloudron.js'), + config = require('../../config.js'), + database = require('../../database.js'), + expect = require('expect.js'), + server = require('../../server.js'), + superagent = require('superagent'); + +var SERVER_URL = 'http://localhost:' + config.get('port'); + +var USERNAME = 'superadmin', PASSWORD = 'Foobar?1337', EMAIL ='silly@me.com'; +var token = null; + +function setup(done) { + config._reset(); + config.setFqdn('example-settings-test.com'); + config.setAdminFqdn('my.example-settings-test.com'); + + async.series([ + server.start.bind(null), + database._clear.bind(null), + + function createAdmin(callback) { + superagent.post(SERVER_URL + '/api/v1/cloudron/activate') + .query({ setupToken: 'somesetuptoken' }) + .send({ username: USERNAME, password: PASSWORD, email: EMAIL }) + .end(function (error, result) { + expect(result).to.be.ok(); + expect(result.statusCode).to.eql(201); + + // stash token for further use + token = result.body.token; + + callback(); + }); + } + ], done); +} + +function cleanup(done) { + database._clear(function (error) { + expect(!error).to.be.ok(); + + server.stop(done); + }); +} + +describe('Mail API', function () { + before(setup); + after(cleanup); + + describe('email DNS records', function () { + var resolve = null; + var dnsAnswerQueue = []; + var dkimDomain, spfDomain, mxDomain, dmarcDomain; + + this.timeout(10000); + + before(function (done) { + var dig = require('../../dig.js'); + + // replace dns resolveTxt() + resolve = dig.resolve; + dig.resolve = function (hostname, type, options, callback) { + expect(hostname).to.be.a('string'); + expect(callback).to.be.a('function'); + + if (!dnsAnswerQueue[hostname] || !(type in dnsAnswerQueue[hostname])) return callback(new Error('no mock answer')); + + callback(null, dnsAnswerQueue[hostname][type]); + }; + + dkimDomain = 'cloudron._domainkey.' + config.fqdn(); + spfDomain = config.fqdn(); + mxDomain = config.fqdn(); + dmarcDomain = '_dmarc.' + config.fqdn(); + + done(); + }); + + after(function (done) { + var dig = require('../../dig.js'); + + dig.resolve = resolve; + + done(); + }); + + it('does not fail when dns errors', function (done) { + superagent.get(SERVER_URL + '/api/v1/mail/status') + .query({ access_token: token }) + .end(function (err, res) { + expect(res.statusCode).to.equal(200); + done(); + }); + }); + + function clearDnsAnswerQueue() { + dnsAnswerQueue = { }; + dnsAnswerQueue[dkimDomain] = { }; + dnsAnswerQueue[spfDomain] = { }; + dnsAnswerQueue[mxDomain] = { }; + dnsAnswerQueue[dmarcDomain] = { }; + } + + it('succeeds with dns errors', function (done) { + clearDnsAnswerQueue(); + + superagent.get(SERVER_URL + '/api/v1/mail/status') + .query({ access_token: token }) + .end(function (err, res) { + expect(res.statusCode).to.equal(200); + + expect(res.body.dns.dkim).to.be.an('object'); + expect(res.body.dns.dkim.domain).to.eql(dkimDomain); + expect(res.body.dns.dkim.type).to.eql('TXT'); + expect(res.body.dns.dkim.value).to.eql(null); + expect(res.body.dns.dkim.expected).to.eql('"v=DKIM1; t=s; p=' + cloudron.readDkimPublicKeySync() + '"'); + expect(res.body.dns.dkim.status).to.eql(false); + + expect(res.body.dns.spf).to.be.an('object'); + expect(res.body.dns.spf.domain).to.eql(spfDomain); + expect(res.body.dns.spf.type).to.eql('TXT'); + expect(res.body.dns.spf.value).to.eql(null); + expect(res.body.dns.spf.expected).to.eql('"v=spf1 a:' + config.adminFqdn() + ' ~all"'); + expect(res.body.dns.spf.status).to.eql(false); + + expect(res.body.dns.dmarc).to.be.an('object'); + expect(res.body.dns.dmarc.type).to.eql('TXT'); + expect(res.body.dns.dmarc.value).to.eql(null); + expect(res.body.dns.dmarc.expected).to.eql('"v=DMARC1; p=reject; pct=100"'); + expect(res.body.dns.dmarc.status).to.eql(false); + + expect(res.body.dns.mx).to.be.an('object'); + expect(res.body.dns.mx.type).to.eql('MX'); + expect(res.body.dns.mx.value).to.eql(null); + expect(res.body.dns.mx.expected).to.eql('10 ' + config.mailFqdn() + '.'); + expect(res.body.dns.mx.status).to.eql(false); + + expect(res.body.dns.ptr).to.be.an('object'); + expect(res.body.dns.ptr.type).to.eql('PTR'); + // expect(res.body.ptr.value).to.eql(null); this will be anything random + expect(res.body.dns.ptr.expected).to.eql(config.mailFqdn() + '.'); + expect(res.body.dns.ptr.status).to.eql(false); + + done(); + }); + }); + + it('succeeds with "undefined" spf, dkim, dmarc, mx, ptr records', function (done) { + clearDnsAnswerQueue(); + + dnsAnswerQueue[dkimDomain].TXT = null; + dnsAnswerQueue[spfDomain].TXT = null; + dnsAnswerQueue[mxDomain].MX = null; + dnsAnswerQueue[dmarcDomain].TXT = null; + + superagent.get(SERVER_URL + '/api/v1/mail/status') + .query({ access_token: token }) + .end(function (err, res) { + expect(res.statusCode).to.equal(200); + + expect(res.body.dns.spf).to.be.an('object'); + expect(res.body.dns.spf.expected).to.eql('"v=spf1 a:' + config.adminFqdn() + ' ~all"'); + expect(res.body.dns.spf.status).to.eql(false); + expect(res.body.dns.spf.value).to.eql(null); + + expect(res.body.dns.dkim).to.be.an('object'); + expect(res.body.dns.dkim.expected).to.eql('"v=DKIM1; t=s; p=' + cloudron.readDkimPublicKeySync() + '"'); + expect(res.body.dns.dkim.status).to.eql(false); + expect(res.body.dns.dkim.value).to.eql(null); + + expect(res.body.dns.dmarc).to.be.an('object'); + expect(res.body.dns.dmarc.expected).to.eql('"v=DMARC1; p=reject; pct=100"'); + expect(res.body.dns.dmarc.status).to.eql(false); + expect(res.body.dns.dmarc.value).to.eql(null); + + expect(res.body.dns.mx).to.be.an('object'); + expect(res.body.dns.mx.status).to.eql(false); + expect(res.body.dns.mx.expected).to.eql('10 ' + config.mailFqdn() + '.'); + expect(res.body.dns.mx.value).to.eql(null); + + expect(res.body.dns.ptr).to.be.an('object'); + expect(res.body.dns.ptr.expected).to.eql(config.mailFqdn() + '.'); + expect(res.body.dns.ptr.status).to.eql(false); + // expect(res.body.ptr.value).to.eql(null); this will be anything random + + done(); + }); + }); + + it('succeeds with all different spf, dkim, dmarc, mx, ptr records', function (done) { + clearDnsAnswerQueue(); + + dnsAnswerQueue[mxDomain].MX = [ { priority: '20', exchange: config.mailFqdn() + '.' }, { priority: '30', exchange: config.mailFqdn() + '.'} ]; + dnsAnswerQueue[dmarcDomain].TXT = ['"v=DMARC2; p=reject; pct=100"']; + dnsAnswerQueue[dkimDomain].TXT = ['"v=DKIM2; t=s; p=' + cloudron.readDkimPublicKeySync() + '"']; + dnsAnswerQueue[spfDomain].TXT = ['"v=spf1 a:random.com ~all"']; + + superagent.get(SERVER_URL + '/api/v1/mail/status') + .query({ access_token: token }) + .end(function (err, res) { + expect(res.statusCode).to.equal(200); + + expect(res.body.dns.spf).to.be.an('object'); + expect(res.body.dns.spf.expected).to.eql('"v=spf1 a:' + config.adminFqdn() + ' a:random.com ~all"'); + expect(res.body.dns.spf.status).to.eql(false); + expect(res.body.dns.spf.value).to.eql('"v=spf1 a:random.com ~all"'); + + expect(res.body.dns.dkim).to.be.an('object'); + expect(res.body.dns.dkim.expected).to.eql('"v=DKIM1; t=s; p=' + cloudron.readDkimPublicKeySync() + '"'); + expect(res.body.dns.dkim.status).to.eql(false); + expect(res.body.dns.dkim.value).to.eql('"v=DKIM2; t=s; p=' + cloudron.readDkimPublicKeySync() + '"'); + + expect(res.body.dns.dmarc).to.be.an('object'); + expect(res.body.dns.dmarc.expected).to.eql('"v=DMARC1; p=reject; pct=100"'); + expect(res.body.dns.dmarc.status).to.eql(false); + expect(res.body.dns.dmarc.value).to.eql('"v=DMARC2; p=reject; pct=100"'); + + expect(res.body.dns.mx).to.be.an('object'); + expect(res.body.dns.mx.status).to.eql(false); + expect(res.body.dns.mx.expected).to.eql('10 ' + config.mailFqdn() + '.'); + expect(res.body.dns.mx.value).to.eql('20 ' + config.mailFqdn() + '. 30 ' + config.mailFqdn() + '.'); + + expect(res.body.dns.ptr).to.be.an('object'); + expect(res.body.dns.ptr.expected).to.eql(config.mailFqdn() + '.'); + expect(res.body.dns.ptr.status).to.eql(false); + // expect(res.body.ptr.value).to.eql(null); this will be anything random + + expect(res.body.relay).to.be.an('object'); + + done(); + }); + }); + + it('succeeds with existing embedded spf', function (done) { + clearDnsAnswerQueue(); + + dnsAnswerQueue[spfDomain].TXT = ['"v=spf1 a:example.com a:' + config.mailFqdn() + ' ~all"']; + + superagent.get(SERVER_URL + '/api/v1/mail/status') + .query({ access_token: token }) + .end(function (err, res) { + expect(res.statusCode).to.equal(200); + + expect(res.body.dns.spf).to.be.an('object'); + expect(res.body.dns.spf.domain).to.eql(spfDomain); + expect(res.body.dns.spf.type).to.eql('TXT'); + expect(res.body.dns.spf.value).to.eql('"v=spf1 a:example.com a:' + config.mailFqdn() + ' ~all"'); + expect(res.body.dns.spf.expected).to.eql('"v=spf1 a:example.com a:' + config.mailFqdn() + ' ~all"'); + expect(res.body.dns.spf.status).to.eql(true); + + done(); + }); + }); + + it('succeeds with all correct records', function (done) { + clearDnsAnswerQueue(); + + dnsAnswerQueue[mxDomain].MX = [ { priority: '10', exchange: config.mailFqdn() + '.' } ]; + dnsAnswerQueue[dmarcDomain].TXT = ['"v=DMARC1; p=reject; pct=100"']; + dnsAnswerQueue[dkimDomain].TXT = ['"v=DKIM1; t=s; p=' + cloudron.readDkimPublicKeySync() + '"']; + dnsAnswerQueue[spfDomain].TXT = ['"v=spf1 a:' + config.adminFqdn() + ' ~all"']; + + superagent.get(SERVER_URL + '/api/v1/mail/status') + .query({ access_token: token }) + .end(function (err, res) { + expect(res.statusCode).to.equal(200); + + expect(res.body.dns.dkim).to.be.an('object'); + expect(res.body.dns.dkim.domain).to.eql(dkimDomain); + expect(res.body.dns.dkim.type).to.eql('TXT'); + expect(res.body.dns.dkim.value).to.eql('"v=DKIM1; t=s; p=' + cloudron.readDkimPublicKeySync() + '"'); + expect(res.body.dns.dkim.expected).to.eql('"v=DKIM1; t=s; p=' + cloudron.readDkimPublicKeySync() + '"'); + expect(res.body.dns.dkim.status).to.eql(true); + + expect(res.body.dns.spf).to.be.an('object'); + expect(res.body.dns.spf.domain).to.eql(spfDomain); + expect(res.body.dns.spf.type).to.eql('TXT'); + expect(res.body.dns.spf.value).to.eql('"v=spf1 a:' + config.adminFqdn() + ' ~all"'); + expect(res.body.dns.spf.expected).to.eql('"v=spf1 a:' + config.adminFqdn() + ' ~all"'); + expect(res.body.dns.spf.status).to.eql(true); + + expect(res.body.dns.dmarc).to.be.an('object'); + expect(res.body.dns.dmarc.expected).to.eql('"v=DMARC1; p=reject; pct=100"'); + expect(res.body.dns.dmarc.status).to.eql(true); + expect(res.body.dns.dmarc.value).to.eql('"v=DMARC1; p=reject; pct=100"'); + + expect(res.body.dns.mx).to.be.an('object'); + expect(res.body.dns.mx.status).to.eql(true); + expect(res.body.dns.mx.expected).to.eql('10 ' + config.mailFqdn() + '.'); + expect(res.body.dns.mx.value).to.eql('10 ' + config.mailFqdn() + '.'); + + done(); + }); + }); + }); +}); diff --git a/src/routes/test/settings-test.js b/src/routes/test/settings-test.js index c87b90b74..06e887d26 100644 --- a/src/routes/test/settings-test.js +++ b/src/routes/test/settings-test.js @@ -527,253 +527,6 @@ describe('Settings API', function () { }); }); - describe('email DNS records', function () { - var resolve = null; - var dnsAnswerQueue = []; - var dkimDomain, spfDomain, mxDomain, dmarcDomain; - - this.timeout(10000); - - before(function (done) { - var dig = require('../../dig.js'); - - // replace dns resolveTxt() - resolve = dig.resolve; - dig.resolve = function (hostname, type, options, callback) { - expect(hostname).to.be.a('string'); - expect(callback).to.be.a('function'); - - if (!dnsAnswerQueue[hostname] || !(type in dnsAnswerQueue[hostname])) return callback(new Error('no mock answer')); - - callback(null, dnsAnswerQueue[hostname][type]); - }; - - dkimDomain = 'cloudron._domainkey.' + config.fqdn(); - spfDomain = config.fqdn(); - mxDomain = config.fqdn(); - dmarcDomain = '_dmarc.' + config.fqdn(); - - done(); - }); - - after(function (done) { - var dig = require('../../dig.js'); - - dig.resolve = resolve; - - done(); - }); - - it('does not fail when dns errors', function (done) { - superagent.get(SERVER_URL + '/api/v1/settings/email_status') - .query({ access_token: token }) - .end(function (err, res) { - expect(res.statusCode).to.equal(200); - done(); - }); - }); - - function clearDnsAnswerQueue() { - dnsAnswerQueue = { }; - dnsAnswerQueue[dkimDomain] = { }; - dnsAnswerQueue[spfDomain] = { }; - dnsAnswerQueue[mxDomain] = { }; - dnsAnswerQueue[dmarcDomain] = { }; - } - - it('succeeds with dns errors', function (done) { - clearDnsAnswerQueue(); - - superagent.get(SERVER_URL + '/api/v1/settings/email_status') - .query({ access_token: token }) - .end(function (err, res) { - expect(res.statusCode).to.equal(200); - - expect(res.body.dns.dkim).to.be.an('object'); - expect(res.body.dns.dkim.domain).to.eql(dkimDomain); - expect(res.body.dns.dkim.type).to.eql('TXT'); - expect(res.body.dns.dkim.value).to.eql(null); - expect(res.body.dns.dkim.expected).to.eql('"v=DKIM1; t=s; p=' + cloudron.readDkimPublicKeySync() + '"'); - expect(res.body.dns.dkim.status).to.eql(false); - - expect(res.body.dns.spf).to.be.an('object'); - expect(res.body.dns.spf.domain).to.eql(spfDomain); - expect(res.body.dns.spf.type).to.eql('TXT'); - expect(res.body.dns.spf.value).to.eql(null); - expect(res.body.dns.spf.expected).to.eql('"v=spf1 a:' + config.adminFqdn() + ' ~all"'); - expect(res.body.dns.spf.status).to.eql(false); - - expect(res.body.dns.dmarc).to.be.an('object'); - expect(res.body.dns.dmarc.type).to.eql('TXT'); - expect(res.body.dns.dmarc.value).to.eql(null); - expect(res.body.dns.dmarc.expected).to.eql('"v=DMARC1; p=reject; pct=100"'); - expect(res.body.dns.dmarc.status).to.eql(false); - - expect(res.body.dns.mx).to.be.an('object'); - expect(res.body.dns.mx.type).to.eql('MX'); - expect(res.body.dns.mx.value).to.eql(null); - expect(res.body.dns.mx.expected).to.eql('10 ' + config.mailFqdn() + '.'); - expect(res.body.dns.mx.status).to.eql(false); - - expect(res.body.dns.ptr).to.be.an('object'); - expect(res.body.dns.ptr.type).to.eql('PTR'); - // expect(res.body.ptr.value).to.eql(null); this will be anything random - expect(res.body.dns.ptr.expected).to.eql(config.mailFqdn() + '.'); - expect(res.body.dns.ptr.status).to.eql(false); - - done(); - }); - }); - - it('succeeds with "undefined" spf, dkim, dmarc, mx, ptr records', function (done) { - clearDnsAnswerQueue(); - - dnsAnswerQueue[dkimDomain].TXT = null; - dnsAnswerQueue[spfDomain].TXT = null; - dnsAnswerQueue[mxDomain].MX = null; - dnsAnswerQueue[dmarcDomain].TXT = null; - - superagent.get(SERVER_URL + '/api/v1/settings/email_status') - .query({ access_token: token }) - .end(function (err, res) { - expect(res.statusCode).to.equal(200); - - expect(res.body.dns.spf).to.be.an('object'); - expect(res.body.dns.spf.expected).to.eql('"v=spf1 a:' + config.adminFqdn() + ' ~all"'); - expect(res.body.dns.spf.status).to.eql(false); - expect(res.body.dns.spf.value).to.eql(null); - - expect(res.body.dns.dkim).to.be.an('object'); - expect(res.body.dns.dkim.expected).to.eql('"v=DKIM1; t=s; p=' + cloudron.readDkimPublicKeySync() + '"'); - expect(res.body.dns.dkim.status).to.eql(false); - expect(res.body.dns.dkim.value).to.eql(null); - - expect(res.body.dns.dmarc).to.be.an('object'); - expect(res.body.dns.dmarc.expected).to.eql('"v=DMARC1; p=reject; pct=100"'); - expect(res.body.dns.dmarc.status).to.eql(false); - expect(res.body.dns.dmarc.value).to.eql(null); - - expect(res.body.dns.mx).to.be.an('object'); - expect(res.body.dns.mx.status).to.eql(false); - expect(res.body.dns.mx.expected).to.eql('10 ' + config.mailFqdn() + '.'); - expect(res.body.dns.mx.value).to.eql(null); - - expect(res.body.dns.ptr).to.be.an('object'); - expect(res.body.dns.ptr.expected).to.eql(config.mailFqdn() + '.'); - expect(res.body.dns.ptr.status).to.eql(false); - // expect(res.body.ptr.value).to.eql(null); this will be anything random - - done(); - }); - }); - - it('succeeds with all different spf, dkim, dmarc, mx, ptr records', function (done) { - clearDnsAnswerQueue(); - - dnsAnswerQueue[mxDomain].MX = [ { priority: '20', exchange: config.mailFqdn() + '.' }, { priority: '30', exchange: config.mailFqdn() + '.'} ]; - dnsAnswerQueue[dmarcDomain].TXT = ['"v=DMARC2; p=reject; pct=100"']; - dnsAnswerQueue[dkimDomain].TXT = ['"v=DKIM2; t=s; p=' + cloudron.readDkimPublicKeySync() + '"']; - dnsAnswerQueue[spfDomain].TXT = ['"v=spf1 a:random.com ~all"']; - - superagent.get(SERVER_URL + '/api/v1/settings/email_status') - .query({ access_token: token }) - .end(function (err, res) { - expect(res.statusCode).to.equal(200); - - expect(res.body.dns.spf).to.be.an('object'); - expect(res.body.dns.spf.expected).to.eql('"v=spf1 a:' + config.adminFqdn() + ' a:random.com ~all"'); - expect(res.body.dns.spf.status).to.eql(false); - expect(res.body.dns.spf.value).to.eql('"v=spf1 a:random.com ~all"'); - - expect(res.body.dns.dkim).to.be.an('object'); - expect(res.body.dns.dkim.expected).to.eql('"v=DKIM1; t=s; p=' + cloudron.readDkimPublicKeySync() + '"'); - expect(res.body.dns.dkim.status).to.eql(false); - expect(res.body.dns.dkim.value).to.eql('"v=DKIM2; t=s; p=' + cloudron.readDkimPublicKeySync() + '"'); - - expect(res.body.dns.dmarc).to.be.an('object'); - expect(res.body.dns.dmarc.expected).to.eql('"v=DMARC1; p=reject; pct=100"'); - expect(res.body.dns.dmarc.status).to.eql(false); - expect(res.body.dns.dmarc.value).to.eql('"v=DMARC2; p=reject; pct=100"'); - - expect(res.body.dns.mx).to.be.an('object'); - expect(res.body.dns.mx.status).to.eql(false); - expect(res.body.dns.mx.expected).to.eql('10 ' + config.mailFqdn() + '.'); - expect(res.body.dns.mx.value).to.eql('20 ' + config.mailFqdn() + '. 30 ' + config.mailFqdn() + '.'); - - expect(res.body.dns.ptr).to.be.an('object'); - expect(res.body.dns.ptr.expected).to.eql(config.mailFqdn() + '.'); - expect(res.body.dns.ptr.status).to.eql(false); - // expect(res.body.ptr.value).to.eql(null); this will be anything random - - expect(res.body.relay).to.be.an('object'); - - done(); - }); - }); - - it('succeeds with existing embedded spf', function (done) { - clearDnsAnswerQueue(); - - dnsAnswerQueue[spfDomain].TXT = ['"v=spf1 a:example.com a:' + config.mailFqdn() + ' ~all"']; - - superagent.get(SERVER_URL + '/api/v1/settings/email_status') - .query({ access_token: token }) - .end(function (err, res) { - expect(res.statusCode).to.equal(200); - - expect(res.body.dns.spf).to.be.an('object'); - expect(res.body.dns.spf.domain).to.eql(spfDomain); - expect(res.body.dns.spf.type).to.eql('TXT'); - expect(res.body.dns.spf.value).to.eql('"v=spf1 a:example.com a:' + config.mailFqdn() + ' ~all"'); - expect(res.body.dns.spf.expected).to.eql('"v=spf1 a:example.com a:' + config.mailFqdn() + ' ~all"'); - expect(res.body.dns.spf.status).to.eql(true); - - done(); - }); - }); - - it('succeeds with all correct records', function (done) { - clearDnsAnswerQueue(); - - dnsAnswerQueue[mxDomain].MX = [ { priority: '10', exchange: config.mailFqdn() + '.' } ]; - dnsAnswerQueue[dmarcDomain].TXT = ['"v=DMARC1; p=reject; pct=100"']; - dnsAnswerQueue[dkimDomain].TXT = ['"v=DKIM1; t=s; p=' + cloudron.readDkimPublicKeySync() + '"']; - dnsAnswerQueue[spfDomain].TXT = ['"v=spf1 a:' + config.adminFqdn() + ' ~all"']; - - superagent.get(SERVER_URL + '/api/v1/settings/email_status') - .query({ access_token: token }) - .end(function (err, res) { - expect(res.statusCode).to.equal(200); - - expect(res.body.dns.dkim).to.be.an('object'); - expect(res.body.dns.dkim.domain).to.eql(dkimDomain); - expect(res.body.dns.dkim.type).to.eql('TXT'); - expect(res.body.dns.dkim.value).to.eql('"v=DKIM1; t=s; p=' + cloudron.readDkimPublicKeySync() + '"'); - expect(res.body.dns.dkim.expected).to.eql('"v=DKIM1; t=s; p=' + cloudron.readDkimPublicKeySync() + '"'); - expect(res.body.dns.dkim.status).to.eql(true); - - expect(res.body.dns.spf).to.be.an('object'); - expect(res.body.dns.spf.domain).to.eql(spfDomain); - expect(res.body.dns.spf.type).to.eql('TXT'); - expect(res.body.dns.spf.value).to.eql('"v=spf1 a:' + config.adminFqdn() + ' ~all"'); - expect(res.body.dns.spf.expected).to.eql('"v=spf1 a:' + config.adminFqdn() + ' ~all"'); - expect(res.body.dns.spf.status).to.eql(true); - - expect(res.body.dns.dmarc).to.be.an('object'); - expect(res.body.dns.dmarc.expected).to.eql('"v=DMARC1; p=reject; pct=100"'); - expect(res.body.dns.dmarc.status).to.eql(true); - expect(res.body.dns.dmarc.value).to.eql('"v=DMARC1; p=reject; pct=100"'); - - expect(res.body.dns.mx).to.be.an('object'); - expect(res.body.dns.mx.status).to.eql(true); - expect(res.body.dns.mx.expected).to.eql('10 ' + config.mailFqdn() + '.'); - expect(res.body.dns.mx.value).to.eql('10 ' + config.mailFqdn() + '.'); - - done(); - }); - }); - }); - describe('mail relay', function () { it('get mail relay succeeds', function (done) { superagent.get(SERVER_URL + '/api/v1/settings/mail_relay') diff --git a/src/server.js b/src/server.js index bba57becf..d0e4480b4 100644 --- a/src/server.js +++ b/src/server.js @@ -203,7 +203,6 @@ function initializeExpressSync() { router.post('/api/v1/settings/cloudron_name', settingsScope, routes.user.requireAdmin, routes.settings.setCloudronName); router.get ('/api/v1/settings/cloudron_avatar', settingsScope, routes.user.requireAdmin, routes.settings.getCloudronAvatar); router.post('/api/v1/settings/cloudron_avatar', settingsScope, routes.user.requireAdmin, multipart, routes.settings.setCloudronAvatar); - router.get ('/api/v1/settings/email_status', settingsScope, routes.user.requireAdmin, routes.settings.getEmailStatus); router.get ('/api/v1/settings/backup_config', settingsScope, routes.user.requireAdmin, routes.settings.getBackupConfig); router.post('/api/v1/settings/backup_config', settingsScope, routes.user.requireAdmin, routes.settings.setBackupConfig); @@ -214,6 +213,8 @@ function initializeExpressSync() { router.post('/api/v1/settings/appstore_config', settingsScope, routes.user.requireAdmin, routes.settings.setAppstoreConfig); // email routes + router.get ('/api/v1/mail/status', settingsScope, routes.user.requireAdmin, routes.mail.getStatus); + router.get ('/api/v1/settings/mail_config', settingsScope, routes.user.requireAdmin, routes.settings.getMailConfig); router.post('/api/v1/settings/mail_config', settingsScope, routes.user.requireAdmin, routes.settings.setMailConfig); router.get ('/api/v1/settings/mail_relay', settingsScope, routes.user.requireAdmin, routes.settings.getMailRelay); diff --git a/webadmin/src/js/client.js b/webadmin/src/js/client.js index f2b3e0200..931548800 100644 --- a/webadmin/src/js/client.js +++ b/webadmin/src/js/client.js @@ -497,7 +497,7 @@ angular.module('Application').service('Client', ['$http', '$interval', 'md5', 'N }; Client.prototype.getEmailStatus = function (callback) { - get('/api/v1/settings/email_status').success(function(data, status) { + get('/api/v1/mail/status').success(function(data, status) { if (status !== 200) return callback(new ClientError(status, data)); callback(null, data); }).error(defaultErrorHandler(callback));