Fix some login race conditions/issues

This commit is contained in:
calzoneman 2014-01-25 21:29:56 -06:00
parent c3035ca368
commit 574ef4435c
5 changed files with 93 additions and 59 deletions

View file

@ -440,30 +440,86 @@ Channel.prototype.getIPRank = function (ip, callback) {
});
};
/**
* Called when a user attempts to join a channel.
* Handles password check
*/
Channel.prototype.preJoin = function (user, password) {
var self = this;
self.whenReady(function () {
user.whenLoggedIn(function () {
self.getRank(user.name, function (err, rank) {
if (err) {
user.rank = user.global_rank;
} else {
user.rank = Math.max(rank, user.global_rank);
}
user.socket.emit("rank", user.rank);
user.emit("channelRank", user.rank);
});
});
if (self.opts.password !== false && user.rank < 2) {
if (password !== self.opts.password) {
var checkPassword = function (pw) {
if (self.dead) {
return;
}
if (pw !== self.opts.password) {
user.socket.emit("needPassword", true);
return;
}
user.socket.listeners("channelPassword").splice(
user.socket.listeners("channelPassword").indexOf(checkPassword)
);
user.socket.emit("cancelNeedPassword");
self.join(user);
};
user.socket.on("channelPassword", checkPassword);
user.socket.emit("needPassword", typeof password !== "undefined");
user.once("channelRank", function (r) {
if (!user.inChannel() && !self.dead && r >= 2) {
user.socket.emit("cancelNeedPassword");
self.join(user);
}
});
return;
}
}
self.join(user);
});
};
/**
* Called when a user joins a channel
*/
Channel.prototype.join = function (user, password) {
Channel.prototype.join = function (user) {
var self = this;
user.whenLoggedIn(function () {
self.getRank(user.name, function (err, rank) {
if (err) {
user.rank = user.global_rank;
} else {
user.rank = Math.max(rank, user.global_rank);
}
user.socket.emit("rank", user.rank);
user.emit("channelRank", user.rank);
});
});
var afterIPBanCheck = function () {
var afterLogin = function () {
if (self.dead) {
return;
}
var lname = user.name.toLowerCase();
for (var i = 0; i < self.users.length; i++) {
if (self.users[i].name.toLowerCase() === lname && self.users[i] !== user) {
self.users[i].kick("Duplicate login");
}
}
self.sendUserJoin(self.users, user);
self.sendUserlist([user]);
};
var afterIPBan = function () {
user.autoAFK();
user.socket.join(self.uniqueName);
user.channel = self;
@ -498,44 +554,13 @@ Channel.prototype.join = function (user, password) {
Logger.syslog.log(user.ip + " joined channel " + self.name);
};
var afterLogin = function () {
if (self.dead) {
db.channels.isIPBanned(self.name, user.ip, function (err, banned) {
if (!err && banned) {
user.kick("You're banned!");
return;
} else {
afterIPBan();
}
var lname = user.name.toLowerCase();
for (var i = 0; i < self.users.length; i++) {
if (self.users[i].name.toLowerCase() === lname && self.users[i] !== user) {
self.users[i].kick("Duplicate login");
}
}
self.sendUserJoin(self.users, user);
self.sendUserlist([user]);
};
self.whenReady(function () {
if (self.opts.password !== false && user.rank < 2) {
if (password !== self.opts.password) {
user.socket.emit("needPassword", typeof password !== "undefined");
user.once("channelRank", function (r) {
if (r >= 2) {
self.join(user);
}
});
return;
}
}
user.socket.emit("cancelNeedPassword");
db.channels.isIPBanned(self.name, user.ip, function (err, banned) {
if (!err && banned) {
user.kick("You're banned!");
return;
} else {
afterIPBanCheck();
}
});
});
};

View file

@ -175,7 +175,7 @@ User.prototype.initChannelCallbacks = function () {
}
});
self.socket.on("joinChannel", typecheck("object", {}, function (data) {
self.socket.once("joinChannel", typecheck("object", {}, function (data) {
if (self.inChannel()) {
return;
}
@ -195,7 +195,7 @@ User.prototype.initChannelCallbacks = function () {
data.name = data.name.toLowerCase();
var chan = Server.getServer().getChannel(data.name);
chan.join(self, data.pw);
chan.preJoin(self, data.pw);
}));
wrapTypecheck("assignLeader", function (data) {