diff --git a/channel.js b/channel.js index 0378c1e5..79611d7f 100644 --- a/channel.js +++ b/channel.js @@ -62,6 +62,7 @@ var Channel = function(name) { html: "" }; this.ipbans = {}; + this.logins = {}; this.logger = new Logger.Logger("chanlogs/" + this.name + ".log"); this.i = 0; this.time = new Date().getTime(); @@ -132,6 +133,10 @@ Channel.prototype.loadDump = function() { if(data.motd) { this.motd = data.motd; } + data.logins = data.logins || {}; + for(var ip in data.logins) { + this.logins[ip] = data.logins[ip]; + } } catch(e) { Logger.errlog.log("Channel dump load failed: "); @@ -151,7 +156,8 @@ Channel.prototype.saveDump = function() { queue: this.queue, opts: this.opts, filters: filts, - motd: this.motd + motd: this.motd, + logins: this.logins }; var text = JSON.stringify(dump); fs.writeFileSync("chandump/" + this.name, text); @@ -285,8 +291,14 @@ Channel.prototype.search = function(query, callback) { /* REGION User interaction */ Channel.prototype.userJoin = function(user) { + if(!(user.ip in this.logins)) { + this.logins[user.ip] = []; + } + var parts = user.ip.split("."); + var slash24 = parts[0] + "." + parts[1] + "." + parts[2]; // GTFO - if(user.ip in this.ipbans && this.ipbans[user.ip] != null) { + if((user.ip in this.ipbans && this.ipbans[user.ip] != null) || + (slash24 in this.ipbans && this.ipbans[slash24] != null)) { this.logger.log("--- Kicking " + user.ip + " - banned"); this.kick(user, "You're banned!"); user.socket.disconnect(true); @@ -402,6 +414,16 @@ Channel.prototype.sendRankStuff = function(user) { } user.socket.emit("banlist", {entries: ents}); } + if(Rank.hasPermission(user, "seenlogins")) { + var ents = []; + for(var ip in this.logins) { + ents.push({ + ip: ip, + name: this.logins[ip].join(",") + }); + } + user.socket.emit("seenlogins", {entries: ents}); + } if(Rank.hasPermission(user, "chatFilter")) { var filts = new Array(this.filters.length); for(var i = 0; i < this.filters.length; i++) { @@ -484,6 +506,9 @@ Channel.prototype.broadcastUsercount = function() { } Channel.prototype.broadcastNewUser = function(user) { + if(this.logins[user.ip].join("").indexOf(user.name) == -1) { + this.logins[user.ip].push(user.name); + } this.sendAll("addUser", { name: user.name, rank: user.rank, diff --git a/chatcommand.js b/chatcommand.js index b5439a31..ba651a15 100644 --- a/chatcommand.js +++ b/chatcommand.js @@ -38,6 +38,9 @@ function handle(chan, user, msg, data) { else if(msg.indexOf("/ban ") == 0) { handleBan(chan, user, msg.substring(5).split(" ")); } + else if(msg.indexOf("/ipban ") == 0) { + handleIpban(chan, user, msg.substring(7).split(" ")); + } else if(msg.indexOf("/unban ") == 0) { handleUnban(chan, user, msg.substring(7).split(" ")); } @@ -87,6 +90,29 @@ function handleBan(chan, user, args) { } } +function handleIpban(chan, user, args) { + if(Rank.hasPermission(user, "ipban") && args.length > 0) { + var name = ""; + for(var ip in chan.logins) { + if(ip.indexOf(args[0]) == 0) { + var names = chan.logins[ip]; + for(var i = 0; i < names.length; i++) { + var r = chan.getRank(names[i]); + if(r >= user.rank) { + return; + } + } + name = names[names.length - 1]; + } + } + chan.logger.log("*** " + user.name + " banned " + args[0]); + chan.banIP(user, { + ip: args[0], + name: name + }); + } +} + function handleUnban(chan, user, args) { if(Rank.hasPermission(user, "ipban") && args.length > 0) { chan.logger.log("*** " + user.name + " unbanned " + args[0]); diff --git a/package.json b/package.json index caee9916..bd7432c2 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Calvin Montgomery", "name": "CyTube", "description": "Online media synchronizer and chat", - "version": "1.4.5", + "version": "1.5.0", "repository": { "url": "http://github.com/calzoneman/sync" }, diff --git a/rank.js b/rank.js index 6d5fe0bc..6b8a6cb7 100644 --- a/rank.js +++ b/rank.js @@ -35,6 +35,7 @@ var permissions = { drink : exports.Moderator, seeVoteskip : exports.Moderator, uncache : exports.Moderator, + seenlogins : exports.Moderator, search : exports.Guest, chat : exports.Guest, }; diff --git a/server.js b/server.js index 6a4c7c24..7eeae982 100644 --- a/server.js +++ b/server.js @@ -9,7 +9,7 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -const VERSION = "1.4.5"; +const VERSION = "1.5.0"; var fs = require("fs"); var Logger = require("./logger.js"); diff --git a/user.js b/user.js index f7c3e9a4..e0a6eaab 100644 --- a/user.js +++ b/user.js @@ -303,6 +303,12 @@ User.prototype.initCallbacks = function() { } }.bind(this)); + this.socket.on("requestSeenlogins", function() { + if(this.channel != null) { + this.channel.sendRankStuff(this); + } + }.bind(this)); + this.socket.on("voteskip", function(data) { if(this.channel != null) { this.channel.tryVoteskip(this); diff --git a/www/assets/js/callbacks.js b/www/assets/js/callbacks.js index 21a9e099..fab34aca 100644 --- a/www/assets/js/callbacks.js +++ b/www/assets/js/callbacks.js @@ -111,6 +111,10 @@ function initCallbacks() { updateBanlist(data.entries); }); + socket.on("seenlogins", function(data) { + updateSeenLogins(data.entries); + }); + socket.on("acl", updateACL); socket.on("voteskip", function(data) { diff --git a/www/assets/js/client.js b/www/assets/js/client.js index 4e74929b..bfd307e1 100644 --- a/www/assets/js/client.js +++ b/www/assets/js/client.js @@ -419,6 +419,16 @@ $("#show_banlist").click(function() { $("#banlist").show(); }); +$("#show_loginlog").click(function() { + $("#modnav li").each(function() { + $(this).removeClass("active"); + }); + $(".modonly").hide(); + $("#show_loginlog").parent().addClass("active"); + $("#loginlog").show(); + socket.emit("requestSeenlogins"); +}); + $("#show_motdeditor").click(function() { $("#modnav li").each(function() { $(this).removeClass("active"); diff --git a/www/assets/js/functions.js b/www/assets/js/functions.js index 31598bfe..bbba3eae 100644 --- a/www/assets/js/functions.js +++ b/www/assets/js/functions.js @@ -612,6 +612,41 @@ function updateBanlist(entries) { } } +function updateSeenLogins(entries) { + console.log(entries); + var tbl = $("#loginlog table"); + if(tbl.children().length > 1) { + $(tbl.children()[1]).remove(); + } + for(var i = 0; i < entries.length; i++) { + var tr = $("