Skip to content

Commit

Permalink
Provide a way of limiting the mail storage size
Browse files Browse the repository at this point in the history
MailDev may sometimes be used as a part of a development/staging
environment where the process may be running for a very long time
without interruption. In those cases, it is undesirable to let that
process grow freely. This limit makes sure that the memory usage is
bounded.
  • Loading branch information
kjagiello committed Nov 15, 2018
1 parent 0ff1f28 commit 3d13ec9
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 2 deletions.
10 changes: 9 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ module.exports = function (config) {
'Comma separated list of SMTP extensions to NOT advertise (STARTTLS, SMTPUTF8, PIPELINING, 8BITMIME)',
function (val) { return val.split(',') }
)
.option('--store-limit <limit>', 'Limit the number of stored messages')
.option('-o, --open', 'Open the Web GUI after startup')
.option('-v, --verbose')
.option('--silent')
Expand All @@ -54,7 +55,14 @@ module.exports = function (config) {
}

// Start the Mailserver & Web GUI
mailserver.create(config.smtp, config.ip, config.incomingUser, config.incomingPass, config.hideExtensions)
mailserver.create(
config.smtp,
config.ip,
config.incomingUser,
config.incomingPass,
config.hideExtensions,
config.storeLimit
)

if (config.outgoingHost ||
config.outgoingPort ||
Expand Down
8 changes: 7 additions & 1 deletion lib/mailserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ function saveEmail (id, envelope, mailObject) {

store.push(object)

if (mailServer.storeLimit && store.length > mailServer.storeLimit) {
const removedMail = store.shift()
eventEmitter.emit('delete', {id: removedMail.id, index: 0})
}

logger.log('Saving email: ', mailObject.subject)

if (outgoing.isAutoRelayEnabled()) {
Expand Down Expand Up @@ -161,7 +166,7 @@ function createTempFolder () {
* Create and configure the mailserver
*/

mailServer.create = function (port, host, user, password, hideExtensions) {
mailServer.create = function (port, host, user, password, hideExtensions, storeLimit) {
const hideExtensionOptions = getHideExtensionOptions(hideExtensions)
const smtpServerConfig = Object.assign({
onAuth: smtpHelpers.createOnAuthCallback(user, password),
Expand All @@ -179,6 +184,7 @@ mailServer.create = function (port, host, user, password, hideExtensions) {

mailServer.port = port || defaultPort
mailServer.host = host || defaultHost
mailServer.storeLimit = storeLimit

// testability requires this to be exposed.
// otherwise we cannot test whether error handling works
Expand Down
43 changes: 43 additions & 0 deletions test/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

const assert = require('assert')
const expect = require('expect')
const nodemailer = require('nodemailer')

const MailDev = require('../index.js')
Expand Down Expand Up @@ -133,5 +134,47 @@ describe('API', function () {
transporter.sendMail(emailOpts)
})
})

it('should respect store size limit', function (done) {
const maildev = new MailDev({
silent: true,
disableWeb: true,
storeLimit: 2
})

const transporter = nodemailer.createTransport({
port: 1025,
ignoreTLS: true
})

const emailOpts = {
from: 'Angelo Pappas <angelo.pappas@fbi.gov>',
to: 'Johnny Utah <johnny.utah@fbi.gov>',
subject: 'You were right.',
text: 'They are surfers.\n'
}

let emailCount = 3

maildev.on('new', function (email) {
expect(maildev.store.length).toBeLessThan(3)

if (!--emailCount) {
maildev.close(function () {
maildev.removeAllListeners()
transporter.close()
done()
})
}
})

maildev.listen(function (err) {
if (err) return done(err)

transporter.sendMail(emailOpts)
transporter.sendMail(emailOpts)
transporter.sendMail(emailOpts)
})
})
})
})

0 comments on commit 3d13ec9

Please sign in to comment.