mail: require catch all to be absolute
This commit is contained in:
1
CHANGES
1
CHANGES
@@ -2514,4 +2514,5 @@
|
|||||||
* eventlog: distinguish ghost/impersonate logins from others
|
* eventlog: distinguish ghost/impersonate logins from others
|
||||||
* ldap: remove virtual user and admin groups to ldap user records
|
* ldap: remove virtual user and admin groups to ldap user records
|
||||||
* Randomize certificate generation cronjob to lighten load on Let's Encrypt servers
|
* Randomize certificate generation cronjob to lighten load on Let's Encrypt servers
|
||||||
|
* mail: catch all address can be any domain
|
||||||
|
|
||||||
|
|||||||
18
migrations/20220911090713-mail-catchAll-make-absolute.js
Normal file
18
migrations/20220911090713-mail-catchAll-make-absolute.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const safe = require('safetydance');
|
||||||
|
|
||||||
|
exports.up = async function (db) {
|
||||||
|
const mailDomains = await db.runSql('SELECT * FROM mail', []);
|
||||||
|
|
||||||
|
for (const mailDomain of mailDomains) {
|
||||||
|
let catchAll = safe.JSON.parse(mailDomain.catchAllJson) || [];
|
||||||
|
if (catchAll.length === 0) continue;
|
||||||
|
|
||||||
|
catchAll = catchAll.map(a => `${a}@${mailDomain.domain}`);
|
||||||
|
await db.runSql('UPDATE mail SET catchAllJson = ? WHERE domain = ?', [ JSON.stringify(catchAll), mailDomain.domain ]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.down = async function( /* db */) {
|
||||||
|
};
|
||||||
@@ -1042,6 +1042,10 @@ async function setCatchAllAddress(domain, addresses) {
|
|||||||
assert.strictEqual(typeof domain, 'string');
|
assert.strictEqual(typeof domain, 'string');
|
||||||
assert(Array.isArray(addresses));
|
assert(Array.isArray(addresses));
|
||||||
|
|
||||||
|
for (const address of addresses) {
|
||||||
|
if (!validator.isEmail(address)) throw new BoxError(BoxError.BAD_FIELD, `Invalid catch all address: ${address}`);
|
||||||
|
}
|
||||||
|
|
||||||
await updateDomain(domain, { catchAll: addresses });
|
await updateDomain(domain, { catchAll: addresses });
|
||||||
|
|
||||||
safe(restartMail(), { debug }); // have to restart mail container since haraka cannot watch symlinked config files (mail.ini)
|
safe(restartMail(), { debug }); // have to restart mail container since haraka cannot watch symlinked config files (mail.ini)
|
||||||
|
|||||||
@@ -352,10 +352,19 @@ describe('Mail API', function () {
|
|||||||
expect(response.statusCode).to.equal(400);
|
expect(response.statusCode).to.equal(400);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('cannot set with bad addresses field', async function () {
|
||||||
|
const response = await superagent.post(`${serverUrl}/api/v1/mail/${dashboardDomain}/catch_all`)
|
||||||
|
.query({ access_token: owner.token })
|
||||||
|
.send({ addresses: [ 'user1' ] })
|
||||||
|
.ok(() => true);
|
||||||
|
|
||||||
|
expect(response.statusCode).to.equal(400);
|
||||||
|
});
|
||||||
|
|
||||||
it('set succeeds', async function () {
|
it('set succeeds', async function () {
|
||||||
const response = await superagent.post(`${serverUrl}/api/v1/mail/${dashboardDomain}/catch_all`)
|
const response = await superagent.post(`${serverUrl}/api/v1/mail/${dashboardDomain}/catch_all`)
|
||||||
.query({ access_token: owner.token })
|
.query({ access_token: owner.token })
|
||||||
.send({ addresses: [ 'user1' ] });
|
.send({ addresses: [ `user1@${dashboardDomain}` ] });
|
||||||
|
|
||||||
expect(response.statusCode).to.equal(202);
|
expect(response.statusCode).to.equal(202);
|
||||||
});
|
});
|
||||||
@@ -365,7 +374,7 @@ describe('Mail API', function () {
|
|||||||
.query({ access_token: owner.token });
|
.query({ access_token: owner.token });
|
||||||
|
|
||||||
expect(response.statusCode).to.equal(200);
|
expect(response.statusCode).to.equal(200);
|
||||||
expect(response.body.catchAll).to.eql([ 'user1' ]);
|
expect(response.body.catchAll).to.eql([ `user1@${dashboardDomain}` ]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -40,11 +40,16 @@ describe('Mail', function () {
|
|||||||
expect(mailConfig.mailFromValidation).to.be(false);
|
expect(mailConfig.mailFromValidation).to.be(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can set catch all address', async function () {
|
it('cannot set invalid catch all address', async function () {
|
||||||
await mail.setCatchAllAddress(domain.domain, [ 'user1', 'user2' ]);
|
const [error] = await safe(mail.setCatchAllAddress(domain.domain, [ 'user1' ]));
|
||||||
|
expect(error.reason).to.be(BoxError.BAD_FIELD);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can set invalid catch all address', async function () {
|
||||||
|
await mail.setCatchAllAddress(domain.domain, [ `user1@${domain.domain}`, `user2@${domain.domain}` ]);
|
||||||
|
|
||||||
const mailConfig = await mail.getDomain(domain.domain);
|
const mailConfig = await mail.getDomain(domain.domain);
|
||||||
expect(mailConfig.catchAll).to.eql([ 'user1', 'user2' ]);
|
expect(mailConfig.catchAll).to.eql([ `user1@${domain.domain}`, `user2@${domain.domain}` ]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can set mail relay', async function () {
|
it('can set mail relay', async function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user