diff --git a/changelog b/changelog index 372a2968..02ca3865 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,10 @@ +Sat Sep 7 23:38 2013 CDT + * lib/user.js: Add "loggingIn" field to act as a lock on async logins. + Delay further login attempts until the current login attempt finishes. + Should prevent cases where sending multiple logins quickly in + succession caused race conditions and thus odd "duplicate login" + kicks. + Sat Sep 7 15:43 2013 CDT * lib/channel.js, lib/user.js: Add an extra check for channel.users[i] to write an error message (instead of kicking) when the same user that diff --git a/lib/user.js b/lib/user.js index cb64c5ef..880b9828 100644 --- a/lib/user.js +++ b/lib/user.js @@ -20,6 +20,7 @@ var User = function(socket, Server) { this.server = Server; this.socket = socket; this.loggedIn = false; + this.loggingIn = false; this.saverank = false; this.rank = Rank.Anonymous; this.global_rank = Rank.Anonymous; @@ -159,8 +160,28 @@ User.prototype.initCallbacks = function() { var session = data.session || ""; if(pw.length > 100) pw = pw.substring(0, 100); - if(self.name == "") + + if (self.loggedIn) + return; + + if (self.loggingIn) { + var j = 0; + // Wait until current login finishes + var i = setInterval(function () { + j++; + if (!self.loggingIn) { + clearInterval(i); + if (!self.loggedIn) + self.login(name, pw, session); + return; + } + // Just in case to prevent the interval from going wild + if (j >= 4) + clearInterval(i); + }, 1000); + } else { self.login(name, pw, session); + } }); self.socket.on("assignLeader", function(data) { @@ -627,8 +648,10 @@ User.prototype.login = function(name, pw, session) { } }); } else { + self.loggingIn = true; self.server.db.userLogin(name, pw, session, function (err, row) { if(err) { + self.loggingIn = false; self.server.actionlog.record(self.ip, name, "login-failure"); self.socket.emit("login", { success: false, @@ -640,7 +663,7 @@ User.prototype.login = function(name, pw, session) { for(var i = 0; i < self.channel.users.length; i++) { if(self.channel.users[i].name.toLowerCase() == name.toLowerCase()) { if (self.channel.users[i] == self) { - Logger.errlog.log("Wat: user.login() but user"+ + Logger.errlog.log("Wat: user.login() but user "+ "already logged in on channel"); break; } @@ -651,6 +674,7 @@ User.prototype.login = function(name, pw, session) { if(self.global_rank >= 255) self.server.actionlog.record(self.ip, name, "login-success"); self.loggedIn = true; + self.loggingIn = false; self.socket.emit("login", { success: true, session: row.session_hash,