'use strict'; const { SMTPServer } = require('smtp-server'); const assert = require('assert'); const fs = require('fs'); const path = require('path'); const db = require('./mocks/databasemock'); const Plugins = require('../src/plugins'); const Emailer = require('../src/emailer'); const user = require('../src/user'); const meta = require('../src/meta'); const Meta = require('../src/meta'); describe('emailer', () => { let onMail = function (address, session, callback) { callback(); }; let onTo = function (address, session, callback) { callback(); }; const template = 'test'; const email = 'test@example.org'; const language = 'en-GB'; const params = { subject: 'Welcome to NodeBB', }; before((done) => { const server = new SMTPServer({ allowInsecureAuth: true, onAuth: function (auth, session, callback) { callback(null, { user: auth.username, }); }, onMailFrom: function (address, session, callback) { onMail(address, session, callback); }, onRcptTo: function (address, session, callback) { onTo(address, session, callback); }, }); server.on('error', (err) => { throw err; }); server.listen(4000, done); }); // TODO: test sendmail here at some point it('plugin hook should work', (done) => { const error = new Error(); const method = function (data, next) { assert(data); assert.equal(data.to, email); assert.equal(data.subject, `[NodeBB] ${params.subject}`); next(error); }; Plugins.hooks.register('emailer-test', { hook: 'filter:email.send', method, }); Emailer.sendToEmail(template, email, language, params, (err) => { assert.equal(err, error); Plugins.hooks.unregister('emailer-test', 'filter:email.send', method); done(); }); }); it('should build custom template on config change', (done) => { const text = 'a random string of text'; // make sure it's not already set Emailer.renderAndTranslate('test', {}, 'en-GB', (err, output) => { assert.ifError(err); assert.notEqual(output, text); Meta.configs.set('email:custom:test', text, (err) => { assert.ifError(err); // wait for pubsub stuff setTimeout(() => { Emailer.renderAndTranslate('test', {}, 'en-GB', (err, output) => { assert.ifError(err); assert.equal(output, text); done(); }); }, 2000); }); }); }); it('should send via SMTP', (done) => { const from = 'admin@example.org'; const username = 'another@example.com'; onMail = function (address, session, callback) { assert.equal(address.address, from); assert.equal(session.user, username); callback(); }; onTo = function (address, session, callback) { assert.equal(address.address, email); callback(); done(); }; Meta.configs.setMultiple({ 'email:smtpTransport:enabled': '1', 'email:smtpTransport:user': username, 'email:smtpTransport:pass': 'anything', 'email:smtpTransport:service': 'nodebb-custom-smtp', 'email:smtpTransport:port': 4000, 'email:smtpTransport:host': 'localhost', 'email:smtpTransport:security': 'NONE', 'email:from': from, }, (err) => { assert.ifError(err); // delay so emailer has a chance to update after config changes setTimeout(() => { assert.equal(Emailer.fallbackTransport, Emailer.transports.smtp); Emailer.sendToEmail(template, email, language, params, (err) => { assert.ifError(err); }); }, 200); }); }); after((done) => { fs.unlinkSync(path.join(__dirname, '../build/public/templates/emails/test.js')); Meta.configs.setMultiple({ 'email:smtpTransport:enabled': '0', 'email:custom:test': '', }, done); }); describe('emailer.send()', () => { let recipientUid; before(async () => { recipientUid = await user.create({ username: 'recipient', email: 'test@example.org' }); await user.email.confirmByUid(recipientUid); }); it('should not send email to a banned user', async () => { const method = async () => { assert(false); // if thrown, email was sent }; Plugins.hooks.register('emailer-test', { hook: 'filter:email.send', method, }); await user.bans.ban(recipientUid); await Emailer.send('test', recipientUid, {}); Plugins.hooks.unregister('emailer-test', 'filter:email.send', method); }); it('should return true if the template is "banned"', async () => { const method = async () => { assert(true); // if thrown, email was sent }; Plugins.hooks.register('emailer-test', { hook: 'filter:email.send', method, }); await Emailer.send('banned', recipientUid, {}); Plugins.hooks.unregister('emailer-test', 'filter:email.send', method); }); it('should return true if system settings allow sending to banned users', async () => { const method = async () => { assert(true); // if thrown, email was sent }; Plugins.hooks.register('emailer-test', { hook: 'filter:email.send', method, }); meta.config.sendEmailToBanned = 1; await Emailer.send('test', recipientUid, {}); meta.config.sendEmailToBanned = 0; await user.bans.unban(recipientUid); Plugins.hooks.unregister('emailer-test', 'filter:email.send', method); }); }); });