simplesmtp
Advanced tools
Comparing version 0.3.25 to 0.3.26
# CHANGELOG | ||
## v0.3.24 2014-04-16 | ||
## v0.3.26 2014-04-23 | ||
* Bumped version to 0.3.26 | ||
* Server: Added support for XOAUTH2 authentication [87b6ed66] | ||
* Client: Use interval NOOPing to keep the connection up [184d8623] | ||
* Client: do not throw if recipients are note set [785a2b09] | ||
## v0.3.25 2014-04-16 | ||
* Bumped version to 0.3.25 | ||
@@ -6,0 +13,0 @@ * disabled server test for max incoming connections [476f8cf5] |
@@ -159,2 +159,8 @@ "use strict"; | ||
/** | ||
* Timeout variable for NOOP when idling | ||
* @private | ||
*/ | ||
this._noopTimeout = false; | ||
if(this.options.ignoreTLS || this.options.secureConnection){ | ||
@@ -321,2 +327,4 @@ this._secureMode = true; | ||
clearTimeout(this._noopTimeout); | ||
if(this._ignoreData || !chunk || !chunk.length){ | ||
@@ -543,2 +551,3 @@ return; | ||
this._currentAction = this._actionIdle; | ||
clearTimeout(this._noopTimeout); | ||
@@ -573,3 +582,3 @@ if (this.stage === "init") { | ||
this._envelope.to = this._envelope.to.map(function(to){ | ||
this._envelope.to = [].concat(this._envelope.to || []).map(function(to){ | ||
return to && to.address || to; | ||
@@ -595,4 +604,3 @@ }); | ||
// no need to authenticate, at least no data given | ||
this._currentAction = this._actionIdle; | ||
this.emit("idle"); // ready to take orders | ||
this._enterIdle(); | ||
return; | ||
@@ -865,4 +873,3 @@ } | ||
} | ||
this._currentAction = this._actionIdle; | ||
this.emit("idle"); // ready to take orders | ||
this._enterIdle(); | ||
}; | ||
@@ -922,4 +929,3 @@ | ||
this._currentAction = this._actionIdle; | ||
this.emit("idle"); // ready to take orders | ||
this._enterIdle(); | ||
}; | ||
@@ -990,2 +996,16 @@ | ||
/** | ||
* Emits "idle" and starts a NOOP timer | ||
*/ | ||
SMTPClient.prototype._enterIdle = function(){ | ||
clearTimeout(this._noopTimeout); | ||
this._noopTimeout = setTimeout(function(){ | ||
// Return to idle mode once NOOP has been accepted | ||
this._currentAction = this._enterIdle; | ||
this.sendCommand("NOOP"); | ||
}.bind(this), 60 * 1000); | ||
this._currentAction = this._actionIdle; | ||
this.emit("idle"); // ready to take orders | ||
}; | ||
/** | ||
* <p>SetsUp DSN</p> | ||
@@ -1089,5 +1109,5 @@ */ | ||
if(typeof setImmediate == "function"){ | ||
setImmediate(this.emit.bind(this, "idle")); | ||
setImmediate(this._enterIdle.bind(this)); | ||
}else{ | ||
process.nextTick(this.emit.bind(this, "idle")); | ||
process.nextTick(this._enterIdle.bind(this)); | ||
} | ||
@@ -1094,0 +1114,0 @@ }; |
@@ -243,3 +243,2 @@ "use strict"; | ||
SMTPServerConnection.prototype._onCommand = function(command, payload){ | ||
if(this.authentication.state == "AUTHPLAINUSERDATA"){ | ||
@@ -255,2 +254,7 @@ this._handleAuthPlain(command.toString("utf-8").trim().split(" ")); | ||
if(this.authentication.state == "AUTHXOAUTH2"){ | ||
this._handleAuthXOAuth2(command); | ||
return; | ||
} | ||
switch((command || "").toString().trim().toUpperCase()){ | ||
@@ -317,2 +321,7 @@ | ||
// No operation | ||
case "": | ||
// ignore blank lines | ||
break; | ||
// Display an error on anything else | ||
@@ -548,2 +557,5 @@ default: | ||
break; | ||
case "XOAUTH2": | ||
this._handleAuthXOAuth2(payload); | ||
break; | ||
case "LOGIN": | ||
@@ -555,3 +567,3 @@ var username = payload.shift(); | ||
} | ||
this._handleAuthLogin( username); | ||
this._handleAuthLogin(username); | ||
break; | ||
@@ -678,3 +690,2 @@ } | ||
} | ||
}; | ||
@@ -722,2 +733,42 @@ | ||
/** | ||
* <p>Detect login information from the payload and initiate authentication | ||
* by emitting <code>'authorizeUser'</code> and waiting for its callback</p> | ||
* | ||
* @param {Buffer} payload AUTH XOAUTH2 login information | ||
*/ | ||
SMTPServerConnection.prototype._handleAuthXOAuth2 = function(payload){ | ||
if(this.authentication.state == "AUTHXOAUTH2"){ | ||
// empty response from the client | ||
this.authentication.authenticated = false; | ||
this.authentication.username = false; | ||
this.authentication.state = "NORMAL"; | ||
return this.client.send("535 5.7.1 Username and Password not accepted"); | ||
} | ||
var userdata = new Buffer(payload.join(" "), "base64"), token; | ||
userdata = userdata.toString("utf-8").split("\x01"); | ||
if (userdata.length != 4) { | ||
return this.client.send("500 5.5.2 Error: invalid userdata to decode"); | ||
} | ||
this.authentication.username = userdata[0].substr(5) || ""; | ||
token = userdata[1].split(" ")[1] || ""; | ||
this.server.emit("authorizeUser", | ||
this.envelope, | ||
this.authentication.username, | ||
token, | ||
(function(err, success){ | ||
if(err || !success){ | ||
this.authentication.state = "AUTHXOAUTH2"; | ||
return this.client.send("334 eyJzdGF0dXMiOiI0MDEiLCJzY2hlbWVzIjoiYmVhcmVyIG1hYyIsInNjb3BlIjoiaHR0cHM6Ly9tYWlsLmdvb2dsZS5jb20vIn0K"); | ||
} | ||
this.client.send("235 2.7.0 Authentication successful"); | ||
this.authentication.authenticated = true; | ||
this.authentication.state = "AUTHENTICATED"; | ||
}).bind(this)); | ||
}; | ||
/** | ||
* <p>Emits the data received from the client with <code>'data'</code> | ||
@@ -724,0 +775,0 @@ * |
{ | ||
"name": "simplesmtp", | ||
"description": "Simple SMTP server module to create custom SMTP servers", | ||
"version": "0.3.25", | ||
"version": "0.3.26", | ||
"author" : "Andris Reinman", | ||
@@ -27,3 +27,3 @@ "maintainers":[ | ||
"dependencies": { | ||
"rai": "~0.1", | ||
"rai": "^0.1.10", | ||
"xoauth2": "~0.1" | ||
@@ -30,0 +30,0 @@ }, |
@@ -245,3 +245,3 @@ "use strict"; | ||
this.smtp = new simplesmtp.createServer({requireAuthentication: true}); | ||
this.smtp = new simplesmtp.createServer({requireAuthentication: true, authMethods: ["PLAIN", "LOGIN", "XOAUTH2"]}); | ||
this.smtp.listen(PORT_NUMBER, function(err){ | ||
@@ -400,2 +400,27 @@ if(err){ | ||
}); | ||
}, | ||
"AUTH XOAUTH2 Login success": function(test){ | ||
var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH XOAUTH2 " + | ||
new Buffer([ | ||
'user=andris', | ||
'auth=Bearer test', | ||
'', | ||
'\n' ].join('\x01')).toString("base64")]; | ||
runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ | ||
test.equal("2",resp.toString("utf-8").trim().substr(0,1)); | ||
test.done(); | ||
}); | ||
}, | ||
"AUTH XOAUTH2 Login fail": function(test){ | ||
var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH XOAUTH2 " + | ||
new Buffer([ | ||
'user=andris', | ||
'auth=Bearer test2', | ||
'', | ||
'\n' ].join('\x01')).toString("base64"), | ||
""]; | ||
runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ | ||
test.equal("5",resp.toString("utf-8").trim().substr(0,1)); | ||
test.done(); | ||
}); | ||
} | ||
@@ -402,0 +427,0 @@ }; |
150981
3610
Updatedrai@^0.1.10