2020-04-29 18:44:27 +03:00
|
|
|
const should = require('should');
|
|
|
|
const sinon = require('sinon');
|
|
|
|
const Promise = require('bluebird');
|
2021-10-06 13:12:21 +03:00
|
|
|
const mail = require('../../../../../core/server/services/mail');
|
|
|
|
const settingsCache = require('../../../../../core/shared/settings-cache');
|
|
|
|
const configUtils = require('../../../../utils/configUtils');
|
|
|
|
const urlUtils = require('../../../../../core/shared/url-utils');
|
2020-04-29 18:44:27 +03:00
|
|
|
let mailer;
|
|
|
|
|
|
|
|
// Mock SMTP config
|
|
|
|
const SMTP = {
|
|
|
|
transport: 'SMTP',
|
|
|
|
options: {
|
|
|
|
service: 'Gmail',
|
|
|
|
auth: {
|
|
|
|
user: 'nil',
|
|
|
|
pass: '123'
|
2013-08-21 00:19:47 +04:00
|
|
|
}
|
2020-04-29 18:44:27 +03:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// test data
|
|
|
|
const mailDataNoDomain = {
|
|
|
|
to: 'joe@doesntexistexample091283zalgo.com',
|
|
|
|
subject: 'testemail',
|
|
|
|
html: '<p>This</p>'
|
|
|
|
};
|
|
|
|
|
|
|
|
const mailDataNoServer = {
|
|
|
|
to: 'joe@example.com',
|
|
|
|
subject: 'testemail',
|
|
|
|
html: '<p>This</p>'
|
|
|
|
};
|
|
|
|
|
|
|
|
const mailDataIncomplete = {
|
|
|
|
subject: 'testemail',
|
|
|
|
html: '<p>This</p>'
|
|
|
|
};
|
2016-01-13 16:17:18 +03:00
|
|
|
|
2019-10-06 16:31:44 +03:00
|
|
|
const sandbox = sinon.createSandbox();
|
|
|
|
|
2016-06-28 21:13:01 +03:00
|
|
|
describe('Mail: Ghostmailer', function () {
|
2013-08-21 00:19:47 +04:00
|
|
|
afterEach(function () {
|
2016-02-08 02:35:47 +03:00
|
|
|
mailer = null;
|
2015-12-14 23:05:11 +03:00
|
|
|
configUtils.restore();
|
2019-10-06 16:31:44 +03:00
|
|
|
sandbox.restore();
|
2013-08-21 00:19:47 +04:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should attach mail provider to ghost instance', function () {
|
2016-06-28 21:13:01 +03:00
|
|
|
mailer = new mail.GhostMailer();
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2013-11-28 06:45:01 +04:00
|
|
|
should.exist(mailer);
|
2016-02-08 00:27:01 +03:00
|
|
|
mailer.should.have.property('send').and.be.a.Function();
|
2013-08-21 00:19:47 +04:00
|
|
|
});
|
|
|
|
|
2016-02-08 02:35:47 +03:00
|
|
|
it('should setup SMTP transport on initialization', function () {
|
2015-12-14 23:05:11 +03:00
|
|
|
configUtils.set({mail: SMTP});
|
2016-06-28 21:13:01 +03:00
|
|
|
mailer = new mail.GhostMailer();
|
2016-02-08 02:35:47 +03:00
|
|
|
|
|
|
|
mailer.should.have.property('transport');
|
2021-09-14 14:39:40 +03:00
|
|
|
mailer.transport.transporter.name.should.eql('SMTP');
|
2016-02-08 02:35:47 +03:00
|
|
|
mailer.transport.sendMail.should.be.a.Function();
|
2013-08-21 00:19:47 +04:00
|
|
|
});
|
|
|
|
|
2016-02-08 02:35:47 +03:00
|
|
|
it('should fallback to direct if config is empty', function () {
|
2015-12-14 23:05:11 +03:00
|
|
|
configUtils.set({mail: {}});
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2016-06-28 21:13:01 +03:00
|
|
|
mailer = new mail.GhostMailer();
|
2016-02-08 02:35:47 +03:00
|
|
|
|
|
|
|
mailer.should.have.property('transport');
|
2021-09-14 14:39:40 +03:00
|
|
|
mailer.transport.transporter.name.should.eql('SMTP (direct)');
|
2013-08-21 00:19:47 +04:00
|
|
|
});
|
|
|
|
|
2016-01-13 16:17:18 +03:00
|
|
|
it('sends valid message successfully ', function (done) {
|
|
|
|
configUtils.set({mail: {transport: 'stub'}});
|
|
|
|
|
2016-06-28 21:13:01 +03:00
|
|
|
mailer = new mail.GhostMailer();
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2021-09-14 14:39:40 +03:00
|
|
|
mailer.transport.transporter.name.should.eql('Stub');
|
2016-02-08 02:35:47 +03:00
|
|
|
|
|
|
|
mailer.send(mailDataNoServer).then(function (response) {
|
2021-09-14 14:39:40 +03:00
|
|
|
should.exist(response.response);
|
2016-01-13 16:17:18 +03:00
|
|
|
should.exist(response.envelope);
|
|
|
|
response.envelope.to.should.containEql('joe@example.com');
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2016-01-13 16:17:18 +03:00
|
|
|
done();
|
|
|
|
}).catch(done);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('handles failure', function (done) {
|
|
|
|
configUtils.set({mail: {transport: 'stub', options: {error: 'Stub made a boo boo :('}}});
|
|
|
|
|
2016-06-28 21:13:01 +03:00
|
|
|
mailer = new mail.GhostMailer();
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2021-09-14 14:39:40 +03:00
|
|
|
mailer.transport.transporter.name.should.eql('Stub');
|
2016-02-08 02:35:47 +03:00
|
|
|
|
|
|
|
mailer.send(mailDataNoServer).then(function () {
|
2016-01-13 16:17:18 +03:00
|
|
|
done(new Error('Stub did not error'));
|
|
|
|
}).catch(function (error) {
|
2017-09-19 16:24:20 +03:00
|
|
|
error.message.should.containEql('Stub made a boo boo :(');
|
2016-01-13 16:17:18 +03:00
|
|
|
done();
|
|
|
|
}).catch(done);
|
|
|
|
});
|
|
|
|
|
2021-05-27 12:14:30 +03:00
|
|
|
it('should fail to send messages when given insufficient data', async function () {
|
2016-06-28 21:13:01 +03:00
|
|
|
mailer = new mail.GhostMailer();
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2021-05-27 12:14:30 +03:00
|
|
|
await mailer.send().should.be.rejectedWith('Incomplete message data.');
|
|
|
|
await mailer.send({subject: '123'}).should.be.rejectedWith('Incomplete message data.');
|
|
|
|
await mailer.send({subject: '', html: '123'}).should.be.rejectedWith('Incomplete message data.');
|
2013-08-21 00:19:47 +04:00
|
|
|
});
|
2014-02-24 20:28:07 +04:00
|
|
|
|
2016-01-13 16:17:18 +03:00
|
|
|
describe('Direct', function () {
|
2016-02-08 02:35:47 +03:00
|
|
|
beforeEach(function () {
|
2016-01-13 16:17:18 +03:00
|
|
|
configUtils.set({mail: {}});
|
|
|
|
|
2016-06-28 21:13:01 +03:00
|
|
|
mailer = new mail.GhostMailer();
|
2016-02-08 02:35:47 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(function () {
|
|
|
|
mailer = null;
|
2014-09-21 01:11:30 +04:00
|
|
|
});
|
2014-02-24 20:28:07 +04:00
|
|
|
|
2016-01-13 16:17:18 +03:00
|
|
|
it('return correct failure message for domain doesn\'t exist', function (done) {
|
2021-09-14 14:39:40 +03:00
|
|
|
mailer.transport.transporter.name.should.eql('SMTP (direct)');
|
2016-01-13 16:17:18 +03:00
|
|
|
|
|
|
|
mailer.send(mailDataNoDomain).then(function () {
|
|
|
|
done(new Error('Error message not shown.'));
|
|
|
|
}, function (error) {
|
2017-09-19 16:24:20 +03:00
|
|
|
error.message.should.startWith('Failed to send email.');
|
2016-01-13 16:17:18 +03:00
|
|
|
done();
|
|
|
|
}).catch(done);
|
|
|
|
});
|
2014-02-24 20:28:07 +04:00
|
|
|
|
2016-01-13 16:17:18 +03:00
|
|
|
it('return correct failure message for no mail server at this address', function (done) {
|
2021-09-14 14:39:40 +03:00
|
|
|
mailer.transport.transporter.name.should.eql('SMTP (direct)');
|
2014-02-24 20:28:07 +04:00
|
|
|
|
2016-01-13 16:17:18 +03:00
|
|
|
mailer.send(mailDataNoServer).then(function () {
|
|
|
|
done(new Error('Error message not shown.'));
|
|
|
|
}, function (error) {
|
2019-03-22 16:36:44 +03:00
|
|
|
error.message.should.startWith('Failed to send email.');
|
2016-01-13 16:17:18 +03:00
|
|
|
done();
|
|
|
|
}).catch(done);
|
|
|
|
});
|
2014-09-21 01:11:30 +04:00
|
|
|
|
2016-01-13 16:17:18 +03:00
|
|
|
it('return correct failure message for incomplete data', function (done) {
|
2021-09-14 14:39:40 +03:00
|
|
|
mailer.transport.transporter.name.should.eql('SMTP (direct)');
|
2016-01-13 16:17:18 +03:00
|
|
|
|
|
|
|
mailer.send(mailDataIncomplete).then(function () {
|
|
|
|
done(new Error('Error message not shown.'));
|
|
|
|
}, function (error) {
|
2017-09-19 16:24:20 +03:00
|
|
|
error.message.should.eql('Incomplete message data.');
|
2016-01-13 16:17:18 +03:00
|
|
|
done();
|
|
|
|
}).catch(done);
|
|
|
|
});
|
2014-09-21 01:11:30 +04:00
|
|
|
});
|
|
|
|
|
2016-01-13 16:17:18 +03:00
|
|
|
describe('From address', function () {
|
2019-10-06 14:28:36 +03:00
|
|
|
it('should use the config', async function () {
|
2016-01-13 16:17:18 +03:00
|
|
|
configUtils.set({
|
|
|
|
mail: {
|
|
|
|
from: '"Blog Title" <static@example.com>'
|
|
|
|
}
|
|
|
|
});
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2016-06-28 21:13:01 +03:00
|
|
|
mailer = new mail.GhostMailer();
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2019-10-06 14:28:36 +03:00
|
|
|
sandbox.stub(mailer, 'sendMail').resolves();
|
2021-09-14 14:39:40 +03:00
|
|
|
mailer.transport.transporter.name = 'NOT DIRECT';
|
2019-10-06 14:28:36 +03:00
|
|
|
|
|
|
|
await mailer.send({
|
|
|
|
to: 'user@example.com',
|
|
|
|
subject: 'subject',
|
|
|
|
html: 'content'
|
|
|
|
});
|
|
|
|
|
|
|
|
mailer.sendMail.firstCall.args[0].from.should.equal('"Blog Title" <static@example.com>');
|
2016-01-13 16:17:18 +03:00
|
|
|
});
|
2014-09-21 01:11:30 +04:00
|
|
|
|
2019-10-06 15:02:10 +03:00
|
|
|
describe('should fall back to [blog.title] <noreply@[blog.url]>', function () {
|
2019-10-06 14:28:36 +03:00
|
|
|
beforeEach(async function () {
|
2019-06-18 16:13:55 +03:00
|
|
|
mailer = new mail.GhostMailer();
|
2019-10-06 14:28:36 +03:00
|
|
|
sandbox.stub(mailer, 'sendMail').resolves();
|
2021-09-14 14:39:40 +03:00
|
|
|
mailer.transport.transporter.name = 'NOT DIRECT';
|
2019-10-06 16:31:44 +03:00
|
|
|
sandbox.stub(settingsCache, 'get').returns('Test');
|
2019-06-18 16:13:55 +03:00
|
|
|
});
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2019-10-06 14:28:36 +03:00
|
|
|
it('standard domain', async function () {
|
2019-10-06 16:31:44 +03:00
|
|
|
sandbox.stub(urlUtils, 'urlFor').returns('http://default.com');
|
2019-06-18 16:13:55 +03:00
|
|
|
configUtils.set({mail: {from: null}});
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2019-10-06 14:28:36 +03:00
|
|
|
await mailer.send({
|
|
|
|
to: 'user@example.com',
|
|
|
|
subject: 'subject',
|
|
|
|
html: 'content'
|
|
|
|
});
|
|
|
|
|
|
|
|
mailer.sendMail.firstCall.args[0].from.should.equal('"Test" <noreply@default.com>');
|
2019-06-18 16:13:55 +03:00
|
|
|
});
|
2014-09-21 01:11:30 +04:00
|
|
|
|
2019-10-06 14:28:36 +03:00
|
|
|
it('trailing slash', async function () {
|
2019-10-06 16:31:44 +03:00
|
|
|
sandbox.stub(urlUtils, 'urlFor').returns('http://default.com/');
|
2019-06-18 16:13:55 +03:00
|
|
|
configUtils.set({mail: {from: null}});
|
2017-02-03 16:15:11 +03:00
|
|
|
|
2019-10-06 14:28:36 +03:00
|
|
|
await mailer.send({
|
|
|
|
to: 'user@example.com',
|
|
|
|
subject: 'subject',
|
|
|
|
html: 'content'
|
|
|
|
});
|
|
|
|
|
|
|
|
mailer.sendMail.firstCall.args[0].from.should.equal('"Test" <noreply@default.com>');
|
2019-06-18 16:13:55 +03:00
|
|
|
});
|
2014-09-21 01:11:30 +04:00
|
|
|
|
2019-10-06 14:28:36 +03:00
|
|
|
it('strip port', async function () {
|
2019-10-06 16:31:44 +03:00
|
|
|
sandbox.stub(urlUtils, 'urlFor').returns('http://default.com:2368/');
|
2019-06-18 16:13:55 +03:00
|
|
|
configUtils.set({mail: {from: null}});
|
2019-10-06 14:28:36 +03:00
|
|
|
|
|
|
|
await mailer.send({
|
|
|
|
to: 'user@example.com',
|
|
|
|
subject: 'subject',
|
|
|
|
html: 'content'
|
|
|
|
});
|
|
|
|
|
|
|
|
mailer.sendMail.firstCall.args[0].from.should.equal('"Test" <noreply@default.com>');
|
2019-06-18 16:13:55 +03:00
|
|
|
});
|
2017-05-12 15:34:22 +03:00
|
|
|
|
2019-10-06 14:28:36 +03:00
|
|
|
it('Escape title', async function () {
|
2019-06-18 16:13:55 +03:00
|
|
|
settingsCache.get.restore();
|
2019-10-06 16:31:44 +03:00
|
|
|
sandbox.stub(settingsCache, 'get').returns('Test"');
|
2017-05-12 15:34:22 +03:00
|
|
|
|
2019-10-06 16:31:44 +03:00
|
|
|
sandbox.stub(urlUtils, 'urlFor').returns('http://default.com:2368/');
|
2019-06-18 16:13:55 +03:00
|
|
|
configUtils.set({mail: {from: null}});
|
2019-10-06 14:28:36 +03:00
|
|
|
|
|
|
|
await mailer.send({
|
|
|
|
to: 'user@example.com',
|
|
|
|
subject: 'subject',
|
|
|
|
html: 'content'
|
|
|
|
});
|
|
|
|
|
|
|
|
mailer.sendMail.firstCall.args[0].from.should.equal('"Test\\"" <noreply@default.com>');
|
2019-06-18 16:13:55 +03:00
|
|
|
});
|
2016-01-13 16:17:18 +03:00
|
|
|
});
|
|
|
|
|
2019-10-06 14:28:36 +03:00
|
|
|
it('should use mail.from', async function () {
|
2016-01-13 16:17:18 +03:00
|
|
|
// Standard domain
|
2017-07-27 11:27:38 +03:00
|
|
|
configUtils.set({mail: {from: '"bar" <from@default.com>'}});
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2016-06-28 21:13:01 +03:00
|
|
|
mailer = new mail.GhostMailer();
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2019-10-06 14:28:36 +03:00
|
|
|
sandbox.stub(mailer, 'sendMail').resolves();
|
2021-09-14 14:39:40 +03:00
|
|
|
mailer.transport.transporter.name = 'NOT DIRECT';
|
2019-10-06 14:28:36 +03:00
|
|
|
|
|
|
|
await mailer.send({
|
|
|
|
to: 'user@example.com',
|
|
|
|
subject: 'subject',
|
|
|
|
html: 'content'
|
|
|
|
});
|
|
|
|
|
|
|
|
mailer.sendMail.firstCall.args[0].from.should.equal('"bar" <from@default.com>');
|
2016-01-13 16:17:18 +03:00
|
|
|
});
|
2014-09-21 01:11:30 +04:00
|
|
|
|
2019-10-06 14:28:36 +03:00
|
|
|
it('should attach blog title', async function () {
|
2019-10-06 16:31:44 +03:00
|
|
|
sandbox.stub(settingsCache, 'get').returns('Test');
|
2017-02-03 16:15:11 +03:00
|
|
|
|
2017-07-27 11:27:38 +03:00
|
|
|
configUtils.set({mail: {from: 'from@default.com'}});
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2016-06-28 21:13:01 +03:00
|
|
|
mailer = new mail.GhostMailer();
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2019-10-06 14:28:36 +03:00
|
|
|
sandbox.stub(mailer, 'sendMail').resolves();
|
2021-09-14 14:39:40 +03:00
|
|
|
mailer.transport.transporter.name = 'NOT DIRECT';
|
2019-10-06 14:28:36 +03:00
|
|
|
|
|
|
|
await mailer.send({
|
|
|
|
to: 'user@example.com',
|
|
|
|
subject: 'subject',
|
|
|
|
html: 'content'
|
|
|
|
});
|
|
|
|
|
|
|
|
mailer.sendMail.firstCall.args[0].from.should.equal('"Test" <from@default.com>');
|
2016-01-13 16:17:18 +03:00
|
|
|
|
|
|
|
// only from set
|
2017-07-27 11:27:38 +03:00
|
|
|
configUtils.set({mail: {from: 'from@default.com'}});
|
2019-10-06 14:28:36 +03:00
|
|
|
|
|
|
|
await mailer.send({
|
|
|
|
to: 'user@example.com',
|
|
|
|
subject: 'subject',
|
|
|
|
html: 'content'
|
|
|
|
});
|
|
|
|
|
|
|
|
mailer.sendMail.firstCall.args[0].from.should.equal('"Test" <from@default.com>');
|
2016-01-13 16:17:18 +03:00
|
|
|
});
|
2014-09-21 01:11:30 +04:00
|
|
|
|
2019-10-06 14:28:36 +03:00
|
|
|
it('should ignore theme title if from address is Title <email@address.com> format', async function () {
|
2017-07-27 11:27:38 +03:00
|
|
|
configUtils.set({mail: {from: '"R2D2" <from@default.com>'}});
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2016-06-28 21:13:01 +03:00
|
|
|
mailer = new mail.GhostMailer();
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2019-10-06 14:28:36 +03:00
|
|
|
sandbox.stub(mailer, 'sendMail').resolves();
|
2021-09-14 14:39:40 +03:00
|
|
|
mailer.transport.transporter.name = 'NOT DIRECT';
|
2019-10-06 14:28:36 +03:00
|
|
|
|
|
|
|
await mailer.send({
|
|
|
|
to: 'user@example.com',
|
|
|
|
subject: 'subject',
|
|
|
|
html: 'content'
|
|
|
|
});
|
|
|
|
|
|
|
|
mailer.sendMail.firstCall.args[0].from.should.equal('"R2D2" <from@default.com>');
|
2016-01-13 16:17:18 +03:00
|
|
|
|
|
|
|
// only from set
|
2017-07-27 11:27:38 +03:00
|
|
|
configUtils.set({mail: {from: '"R2D2" <from@default.com>'}});
|
2019-10-06 14:28:36 +03:00
|
|
|
await mailer.send({
|
|
|
|
to: 'user@example.com',
|
|
|
|
subject: 'subject',
|
|
|
|
html: 'content'
|
|
|
|
});
|
|
|
|
|
|
|
|
mailer.sendMail.firstCall.args[0].from.should.equal('"R2D2" <from@default.com>');
|
2016-01-13 16:17:18 +03:00
|
|
|
});
|
|
|
|
|
2019-10-06 14:28:36 +03:00
|
|
|
it('should use default title if not theme title is provided', async function () {
|
2019-06-18 16:13:55 +03:00
|
|
|
configUtils.set({mail: {from: null}});
|
2019-10-06 16:31:44 +03:00
|
|
|
sandbox.stub(urlUtils, 'urlFor').returns('http://default.com:2368/');
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2016-06-28 21:13:01 +03:00
|
|
|
mailer = new mail.GhostMailer();
|
2016-02-08 02:35:47 +03:00
|
|
|
|
2019-10-06 14:28:36 +03:00
|
|
|
sandbox.stub(mailer, 'sendMail').resolves();
|
2021-09-14 14:39:40 +03:00
|
|
|
mailer.transport.transporter.name = 'NOT DIRECT';
|
2019-10-06 14:28:36 +03:00
|
|
|
|
|
|
|
await mailer.send({
|
|
|
|
to: 'user@example.com',
|
|
|
|
subject: 'subject',
|
|
|
|
html: 'content'
|
|
|
|
});
|
|
|
|
|
|
|
|
mailer.sendMail.firstCall.args[0].from.should.equal('"Ghost at default.com" <noreply@default.com>');
|
2016-01-13 16:17:18 +03:00
|
|
|
});
|
2014-02-24 20:28:07 +04:00
|
|
|
});
|
2013-08-21 00:19:47 +04:00
|
|
|
});
|