smtp-server
Advanced tools
Comparing version 1.3.0 to 1.3.1
# Changelog | ||
## v1.3.1 2015-04-21 | ||
* Added integration tests for CRAM-MD5 authentication | ||
* Exposed SNI support with `sniOptions` optional server option | ||
* Define used protocol for NPN as 'smtp' | ||
## v1.3.0 2015-04-21 | ||
* Added CRAM-MD5 authentication support | ||
## v1.2.0 2015-03-11 | ||
@@ -4,0 +14,0 @@ |
@@ -88,3 +88,2 @@ 'use strict'; | ||
this._server.logger.info('[%s] Trying to authenticate "%s" with %s', this._id, username, 'PLAIN'); | ||
this._server.onAuth({ | ||
@@ -97,3 +96,3 @@ method: 'PLAIN', | ||
if (err) { | ||
this._server.logger.info('[%s] Authentication error for "%s"\n%s', this._id, username, err.message); | ||
this._server.logger.info('[%s] Authentication error for %s using %s\n%s', this._id, username, 'PLAIN', err.message); | ||
this.send(err.responseCode || 535, err.message); | ||
@@ -104,2 +103,3 @@ return callback(); | ||
if (!response.user) { | ||
this._server.logger.info('[%s] Authentication failed for %s using %s', this._id, username, 'PLAIN'); | ||
this.send(response.responseCode || 535, response.message || 'Error: Authentication credentials invalid'); | ||
@@ -109,3 +109,3 @@ return callback(); | ||
this._server.logger.info('[%s] User "%s" authenticated'); | ||
this._server.logger.info('[%s] %s authenticated using %s', this._id, username, 'PLAIN'); | ||
this.session.user = response.user; | ||
@@ -149,3 +149,2 @@ | ||
this._server.logger.info('[%s] Trying to authenticate "%s" with %s', this._id, username, 'LOGIN'); | ||
this._server.onAuth({ | ||
@@ -158,3 +157,3 @@ method: 'LOGIN', | ||
if (err) { | ||
this._server.logger.info('[%s] Authentication error for "%s"\n%s', this._id, username, err.message); | ||
this._server.logger.info('[%s] Authentication error for %s using %s\n%s', this._id, username, 'LOGIN', err.message); | ||
this.send(err.responseCode || 535, err.message); | ||
@@ -165,2 +164,3 @@ return callback(); | ||
if (!response.user) { | ||
this._server.logger.info('[%s] Authentication failed for %s using %s', this._id, username, 'LOGIN'); | ||
this.send(response.responseCode || 535, response.message || 'Error: Authentication credentials invalid'); | ||
@@ -170,3 +170,3 @@ return callback(); | ||
this._server.logger.info('[%s] User "%s" authenticated'); | ||
this._server.logger.info('[%s] %s authenticated using %s', this._id, username, 'LOGIN'); | ||
this.session.user = response.user; | ||
@@ -212,3 +212,2 @@ | ||
this._server.logger.info('[%s] Trying to authenticate "%s" with %s', this._id, username, 'XOAUTH2'); | ||
this._server.onAuth({ | ||
@@ -221,3 +220,3 @@ method: 'XOAUTH2', | ||
if (err) { | ||
this._server.logger.info('[%s] Authentication error for "%s"\n%s', this._id, username, err.message); | ||
this._server.logger.info('[%s] Authentication error for %s using %s\n%s', this._id, username, 'XOAUTH2', err.message); | ||
this.send(err.responseCode || 535, err.message); | ||
@@ -228,2 +227,3 @@ return callback(); | ||
if (!response.user) { | ||
this._server.logger.info('[%s] Authentication failed for %s using %s', this._id, username, 'XOAUTH2'); | ||
this._nextHandler = SASL.XOAUTH2_error.bind(this); | ||
@@ -234,3 +234,3 @@ this.send(response.responseCode || 334, new Buffer(JSON.stringify(response.data || {})).toString('base64')); | ||
this._server.logger.info('[%s] User "%s" authenticated'); | ||
this._server.logger.info('[%s] %s authenticated using %s', this._id, username, 'XOAUTH2'); | ||
this.session.user = response.user; | ||
@@ -261,3 +261,2 @@ | ||
this._server.logger.info('[%s] Trying to authenticate "%s" with %s', this._id, username, 'CRAM-MD5'); | ||
this._server.onAuth({ | ||
@@ -273,3 +272,3 @@ method: 'CRAM-MD5', | ||
if (err) { | ||
this._server.logger.info('[%s] Authentication error for "%s"\n%s', this._id, username, err.message); | ||
this._server.logger.info('[%s] Authentication error for %s using %s\n%s', this._id, username, 'CRAM-MD5', err.message); | ||
this.send(err.responseCode || 535, err.message); | ||
@@ -280,2 +279,3 @@ return callback(); | ||
if (!response.user) { | ||
this._server.logger.info('[%s] Authentication failed for %s using %s', this._id, username, 'CRAM-MD5'); | ||
this.send(response.responseCode || 535, response.message || 'Error: Authentication credentials invalid'); | ||
@@ -285,3 +285,3 @@ return callback(); | ||
this._server.logger.info('[%s] User "%s" authenticated'); | ||
this._server.logger.info('[%s] %s authenticated using %s', this._id, username, 'CRAM-MD5'); | ||
this.session.user = response.user; | ||
@@ -288,0 +288,0 @@ |
@@ -501,6 +501,12 @@ 'use strict'; | ||
// throws if SNICallback is missing, so we set a default callback | ||
SNICallback: function(servername, cb) { | ||
cb(null, secureContext); | ||
} | ||
var ctxMap = this._server.options.sniOptions || {}; | ||
var ctx; | ||
if (typeof ctxMap.get === 'function') { | ||
ctx = ctxMap.get(servername); | ||
}else{ | ||
ctx = ctxMap[servername]; | ||
} | ||
cb(null, ctx && tls.createSecureContext(tlsOptions(ctx)) || secureContext); | ||
}.bind(this) | ||
}; | ||
@@ -532,3 +538,3 @@ | ||
this._server.logger.info('[%s] Upgraded to TLS', this._id); | ||
this._server.logger.info('[%s] Connection upgraded to TLS', this._id); | ||
this._socket.pipe(this._parser); | ||
@@ -535,0 +541,0 @@ }.bind(this)); |
@@ -29,2 +29,12 @@ 'use strict'; | ||
this.options = tlsOptions(this.options); | ||
this.options.SNICallback = function(servername, cb) { | ||
var ctxMap = this.options.sniOptions || {}; | ||
var ctx; | ||
if (typeof ctxMap.get === 'function') { | ||
ctx = ctxMap.get(servername); | ||
} else { | ||
ctx = ctxMap[servername]; | ||
} | ||
cb(null, tls.createSecureContext(ctx && tlsOptions(ctx) || this.options)); | ||
}.bind(this); | ||
} | ||
@@ -31,0 +41,0 @@ |
@@ -70,3 +70,4 @@ 'use strict'; | ||
].join(':'), | ||
honorCipherOrder: true | ||
honorCipherOrder: true, | ||
NPNProtocols: ['smtp'] | ||
}; | ||
@@ -73,0 +74,0 @@ |
{ | ||
"name": "smtp-server", | ||
"version": "1.3.0", | ||
"version": "1.3.1", | ||
"description": "Create custom SMTP servers on the fly", | ||
@@ -18,3 +18,2 @@ "main": "lib/smtp-server.js", | ||
"mocha": "^2.2.4", | ||
"sinon": "^1.14.1", | ||
"smtp-connection": "^1.2.0" | ||
@@ -21,0 +20,0 @@ }, |
@@ -41,2 +41,3 @@ # smtp-server | ||
* **hideSTARTTLS** optional boolean, if set to true then allow using STARTTLS but do not advertise or require it. It only makes sense when creating integration test servers for testing the scenario where you want to try STARTTLS even when it is not advertised | ||
* **options.sniOptions** optional [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) or an object of TLS options for SNI where servername is the key | ||
* **options.logger** optional [bunyan](https://github.com/trentm/node-bunyan) compatible logger instance. By default logs to console. If set to `false` then nothing is logged | ||
@@ -43,0 +44,0 @@ * **options.maxClients** sets the maximum number of concurrently connected clients, defaults to `Infinity` |
@@ -569,3 +569,3 @@ 'use strict'; | ||
logger: false, | ||
authMethods: ['PLAIN', 'LOGIN', 'XOAUTH2'], | ||
authMethods: ['PLAIN', 'LOGIN', 'XOAUTH2', 'CRAM-MD5'], | ||
onAuth: function(auth, session, callback) { | ||
@@ -586,3 +586,9 @@ if (auth.method === 'XOAUTH2') { | ||
} | ||
} else if (auth.username === 'testuser' && auth.password === 'testpass') { | ||
} else if (auth.username === 'testuser' && | ||
( | ||
auth.method === 'CRAM-MD5' ? | ||
auth.validatePassword('testpass') : | ||
auth.password === 'testpass' | ||
) | ||
) { | ||
callback(null, { | ||
@@ -754,4 +760,50 @@ user: 'userdata' | ||
// TODO: Add tests for CRAM-MD5 | ||
// smtp-connection does not support it currently | ||
describe('CRAM-MD5', function() { | ||
it('should authenticate', function(done) { | ||
var connection = new Client({ | ||
port: PORT, | ||
host: '127.0.0.1', | ||
tls: { | ||
rejectUnauthorized: false | ||
}, | ||
authMethod: 'CRAM-MD5' | ||
}); | ||
connection.on('end', done); | ||
connection.connect(function() { | ||
connection.login({ | ||
user: 'testuser', | ||
pass: 'testpass' | ||
}, function(err) { | ||
expect(err).to.not.exist; | ||
connection.quit(); | ||
}); | ||
}); | ||
}); | ||
it('should fail', function(done) { | ||
var connection = new Client({ | ||
port: PORT, | ||
host: '127.0.0.1', | ||
tls: { | ||
rejectUnauthorized: false | ||
}, | ||
authMethod: 'CRAM-MD5' | ||
}); | ||
connection.on('end', done); | ||
connection.connect(function() { | ||
connection.login({ | ||
user: 'zzzz', | ||
pass: 'yyyy' | ||
}, function(err) { | ||
expect(err).to.exist; | ||
connection.quit(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
@@ -758,0 +810,0 @@ |
106951
6
2321
349