From b7c02334eda1b4b7ed344541fd242f802c0dcd5e Mon Sep 17 00:00:00 2001 From: calzoneman Date: Sat, 17 Aug 2013 12:30:52 -0500 Subject: [PATCH] Start on channel.js --- channel.js | 496 +++++++++++++++++++++++++++-------------------------- user.js | 24 +-- 2 files changed, 256 insertions(+), 264 deletions(-) diff --git a/channel.js b/channel.js index 3460e139..4195cd53 100644 --- a/channel.js +++ b/channel.js @@ -24,26 +24,27 @@ var Playlist = require("./playlist"); var sanitize = require("validator").sanitize; var Channel = function(name, Server) { + var self = this; Logger.syslog.log("Opening channel " + name); - this.initialized = false; - this.server = Server; + self.initialized = false; + self.server = Server; - this.name = name; - this.canonical_name = name.toLowerCase(); + self.name = name; + self.canonical_name = name.toLowerCase(); // Initialize defaults - this.registered = false; - this.users = []; - this.afkers = []; - this.playlist = new Playlist(this); - this.library = {}; - this.position = -1; - this.drinks = 0; - this.leader = null; - this.chatbuffer = []; - this.openqueue = false; - this.poll = false; - this.voteskip = false; - this.permissions = { + self.registered = false; + self.users = []; + self.afkers = []; + self.playlist = new Playlist(self); + self.library = {}; + self.position = -1; + self.drinks = 0; + self.leader = null; + self.chatbuffer = []; + self.openqueue = false; + self.poll = false; + self.voteskip = false; + self.permissions = { oplaylistadd: -1, oplaylistnext: 1.5, oplaylistmove: 1.5, @@ -74,11 +75,11 @@ var Channel = function(name, Server) { drink: 1.5, chat: 0 }; - this.opts = { + self.opts = { allow_voteskip: true, voteskip_ratio: 0.5, afk_timeout: 180, - pagetitle: this.name, + pagetitle: self.name, maxlength: 0, externalcss: "", externaljs: "", @@ -86,42 +87,43 @@ var Channel = function(name, Server) { show_public: false, enable_link_regex: true }; - this.filters = [ + self.filters = [ new Filter("monospace", "`([^`]+)`", "g", "$1"), new Filter("bold", "(^|\\s)\\*([^\\*]+)\\*", "g", "$1$2"), new Filter("italic", "(^| )_([^_]+)_", "g", "$1$2"), new Filter("strikethrough", "~~([^~]+)~~", "g", "$1"), new Filter("inline spoiler", "\\[spoiler\\](.*)\\[\\/spoiler\\]", "ig", "$1"), ]; - this.motd = { + self.motd = { motd: "", html: "" }; - this.ipbans = {}; - this.namebans = {}; - this.ip_alias = {}; - this.name_alias = {}; - this.login_hist = []; - this.logger = new Logger.Logger("chanlogs/" + this.canonical_name + ".log"); - this.i = 0; - this.time = new Date().getTime(); - this.plmeta = { + self.ipbans = {}; + self.namebans = {}; + self.ip_alias = {}; + self.name_alias = {}; + self.login_hist = []; + self.logger = new Logger.Logger("chanlogs/" + self.canonical_name + ".log"); + self.i = 0; + self.time = new Date().getTime(); + self.plmeta = { count: 0, time: "00:00" }; - this.css = ""; - this.js = ""; + self.css = ""; + self.js = ""; - this.ipkey = ""; + self.ipkey = ""; for(var i = 0; i < 15; i++) { - this.ipkey += "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[parseInt(Math.random() * 65)] + self.ipkey += "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[parseInt(Math.random() * 65)] } - Server.db.loadChannel(this); - if(this.registered) { - this.loadDump(); - } + Server.db.loadChannelData(self, function () { + if(self.registered) { + self.loadDump(); + } + }); } /* REGION Permissions */ @@ -338,18 +340,19 @@ Channel.prototype.tryReadLog = function (user) { }); } -Channel.prototype.tryRegister = function(user) { - if(this.registered) { - ActionLog.record(user.ip, user.name, "channel-register-failure", [ - this.name, "Channel already registered"]); +Channel.prototype.tryRegister = function (user) { + var self = this; + if(self.registered) { + ActionLog.record(user.ip, user.name, "channel-register-failure", + [self.name, "Channel already registered"]); user.socket.emit("registerChannel", { success: false, error: "This channel is already registered" }); } else if(!user.loggedIn) { - ActionLog.record(user.ip, user.name, "channel-register-failure", [ - this.name, "Not logged in"]); + ActionLog.record(user.ip, user.name, "channel-register-failure", + [self.name, "Not logged in"]); user.socket.emit("registerChannel", { success: false, error: "You must log in to register a channel" @@ -357,70 +360,135 @@ Channel.prototype.tryRegister = function(user) { } else if(!Rank.hasPermission(user, "registerChannel")) { - ActionLog.record(user.ip, user.name, "channel-register-failure", [ - this.name, "Insufficient permissions"]); + ActionLog.record(user.ip, user.name, "channel-register-failure", + [self.name, "Insufficient permissions"]); user.socket.emit("registerChannel", { success: false, - error: "You don't have permission to register this channel" + error: "You don't have permission to register self channel" }); } else { - if(this.server.db.registerChannel(this.name, user.name)) { - ActionLog.record(user.ip, user.name, "channel-register-success", this.name); - this.registered = true; - this.initialized = true; - this.saveDump(); - this.saveRank(user); + self.server.db.registerChannel(self.name, user.name, + function (err, res) { + if(err) { + user.socket.emit("registerChannel", { + success: false, + error: "Unable to register channel: " + err + }); + return; + } + + ActionLog.record(user.ip, user.name, + "channel-register-success", self.name); + self.registered = true; + self.initialized = true; + self.saveDump(); + self.saveRank(user); user.socket.emit("registerChannel", { - success: true, + success: true }); - this.logger.log("*** " + user.name + " registered the channel"); - Logger.syslog.log("Channel " + this.name + " was registered by " + user.name); - } - else { - user.socket.emit("registerChannel", { + self.logger.log("*** " + user.name + " registered the channel"); + }); + } +} + +Channel.prototype.unregister = function (user) { + var self = this; + + if(!self.registered) { + user.socket.emit("unregisterChannel", { + success: false, + error: "This channel is already unregistered" + }); + return; + } + + if(user.rank < 10) { + user.socket.emit("unregisterChannel", { + success: false, + error: "You must be the channel owner to unregister it" + }); + return; + } + self.server.db.dropChannel(self.name, function (err, res) { + if(err) { + user.socket.emit("unregisterChannel", { success: false, - error: "Unable to register channel, see an admin" + error: "Unregistration failed: " + err }); + return; } - } -} - -Channel.prototype.unregister = function() { - if(this.server.db.deleteChannel(this.name)) { - this.registered = false; - return true; - } - return false; -} - -Channel.prototype.getRank = function(name) { - var global = Auth.getGlobalRank(name); - if(!this.registered) { - return global; - } - var local = this.server.db.getChannelRank(this.name, name); - return local > global ? local : global; -} - -Channel.prototype.saveRank = function(user) { - return this.server.db.setChannelRank(this.name, user.name, user.rank); -} - -Channel.prototype.getIPRank = function(ip) { - var names = []; - if(!(ip in this.ip_alias)) - this.ip_alias[ip] = this.server.db.getAliases(ip); - this.ip_alias[ip].forEach(function(name) { - names.push(name); + + self.registered = false; + user.socket.emit("unregisterChannel", { success: true }); }); +} - var ranks = this.server.db.getChannelRank(this.name, names); - var rank = 0; - for(var i = 0; i < ranks.length; i++) { - rank = (ranks[i] > rank) ? ranks[i] : rank; +Channel.prototype.getRank = function (name, callback) { + var self = this; + self.server.db.getGlobalRank(name, function (err, global) { + if(err) { + callback(err, null); + return; + } + + if(!self.registered) { + callback(null, global); + return; + } + + self.server.db.getChannelRank(self.name, name, + function (err, rank) { + if(err) { + callback(err, null); + return; + } + + callback(null, rank > global ? rank : global); + }); + }); +} + +Channel.prototype.saveRank = function (user) { + this.server.db.setChannelRank(this.name, user.name, user.rank); +} + +Channel.prototype.getIPRank = function (ip, callback) { + var self = this; + var names = []; + var next = function (names) { + self.server.db.getChannelRank(self.name, names, + function (err, res) { + if(err) { + callback(err, null); + return; + } + + var rank = 0; + for(var i in res) { + rank = (res[i].rank > rank) ? res[i].rank : rank; + } + callback(null, rank); + }); + }; + + if(ip in self.ip_alias) { + names = self.ip_alias[ip]; + next(names); + } else if(ip.match(/^(\d+)\.(\d+)\.(\d+)$/)) { + // Range + for(var ip2 in self.ip_alias) { + if(ip2.indexOf(ip) == 0) { + for(var i in self.ip_aliases[ip2]) + names.push(self.ip_aliases[ip2][i]); + } + next(names); + } else{ + self.server.db.listAliases(ip, function (err, names) { + self.ip_alias[ip] = names; + next(names); + }); } - return rank; } Channel.prototype.cacheMedia = function(media) { @@ -437,35 +505,46 @@ Channel.prototype.cacheMedia = function(media) { } Channel.prototype.tryNameBan = function(actor, name) { - if(!this.hasPermission(actor, "ban")) { + var self = this; + if(!self.hasPermission(actor, "ban")) { return false; } name = name.toLowerCase(); - var rank = this.getRank(name); - if(rank >= actor.rank) { - actor.socket.emit("errorMsg", {msg: "You don't have permission to ban this person."}); - return false; - } - - this.namebans[name] = actor.name; - for(var i = 0; i < this.users.length; i++) { - if(this.users[i].name.toLowerCase() == name) { - this.kick(this.users[i], "You're banned!"); - break; + self.getRank(name, function (err, rank) { + if(err) { + actor.socket.emit("errorMsg", { + msg: "Internal error" + }); + return; } - } - this.logger.log("*** " + actor.name + " namebanned " + name); - var chan = this; - this.users.forEach(function(u) { - chan.sendBanlist(u); - }); - if(!this.registered) { - return false; - } - return this.server.db.channelBan(this.name, "*", name, actor.name); + if(rank >= actor.rank) { + actor.socket.emit("errorMsg", { + msg: "You don't have permission to ban this person." + }); + return; + } + + self.namebans[name] = actor.name; + for(var i = 0; i < self.users.length; i++) { + if(self.users[i].name.toLowerCase() == name) { + self.kick(self.users[i], "You're banned!"); + break; + } + } + self.logger.log("*** " + actor.name + " namebanned " + name); + self.users.forEach(function(u) { + self.sendBanlist(u); + }); + + if(!self.registered) { + return; + } + + self.server.db.addChannelBan(self.name, "*", name, actor.name); + }); } Channel.prototype.unbanName = function(actor, name) { @@ -485,50 +564,54 @@ Channel.prototype.unbanName = function(actor, name) { } Channel.prototype.tryIPBan = function(actor, name, range) { - if(!this.hasPermission(actor, "ban")) { - return false; + var self = this; + if(!self.hasPermission(actor, "ban")) { + return; } if(typeof name != "string") { - return false; + return; } - var ips = this.server.db.ipForName(name); - var chan = this; - ips.forEach(function(ip) { - if(chan.getIPRank(ip) >= actor.rank) { - actor.socket.emit("errorMsg", {msg: "You don't have permission to ban IP: x.x." + ip.replace(/\d+\.\d+\.(\d+\.\d+)/, "$1")}); - return false; - } - - if(range) { + var ips = self.server.db.ipForName(name); + ips.forEach(function (ip) { + if(range) ip = ip.replace(/(\d+)\.(\d+)\.(\d+)\.(\d+)/, "$1.$2.$3"); - for(var ip2 in chan.ip_alias) { - if(ip2.indexOf(ip) == 0 && chan.getIPRank(ip2) >= actor.rank) { - actor.socket.emit("errorMsg", {msg: "You don't have permission to ban IP: x.x." + ip2.replace(/\d+\.\d+\.(\d+\.\d+)/, "$1")}); - return false; + self.getIPRank(ip, function (err, rank) { + if(err) { + actor.socket.emit("errorMsg", { + msg: "Internal error" + }); + return; + } + + if(rank >= actor.rank) { + actor.socket.emit("errorMsg", { + msg: "You don't have permission to ban IP: x.x." + + ip.replace(/\d+\.\d+\.(\d+\.\d+)/, "$1") + }); + return; + } + + self.ipbans[ip] = [name, actor.name]; + self.logger.log("*** " + actor.name + " banned " + ip + + " (" + name + ")"); + + for(var i = 0; i < self.users.length; i++) { + if(self.users[i].ip.indexOf(ip) == 0) { + self.kick(self.users[i], "Your IP is banned!"); + i--; } } - } - chan.ipbans[ip] = [name, actor.name]; - //chan.broadcastBanlist(); - chan.logger.log("*** " + actor.name + " banned " + ip + " (" + name + ")"); - for(var i = 0; i < chan.users.length; i++) { - if(chan.users[i].ip.indexOf(ip) == 0) { - chan.kick(chan.users[i], "Your IP is banned!"); - i--; - } - } + if(!self.registered) + return; - if(!chan.registered) - return false; - - // Update database ban table - return chan.server.db.channelBan(chan.name, ip, name, actor.name); - }); - - var chan = this; - this.users.forEach(function(u) { - chan.sendBanlist(u); + self.server.db.addChannelBan(chan.name, ip, name, actor.name + function (err, res) { + self.users.forEach(function(u) { + self.sendBanlist(u); + }); + }); + }); }); } @@ -1858,6 +1941,7 @@ Channel.prototype.sendMessage = function(username, msg, msgclass, data) { /* REGION Rank stuff */ Channel.prototype.trySetRank = function(user, data) { + var self = this; if(!Rank.hasPermission(user, "promote")) return; @@ -1871,9 +1955,9 @@ Channel.prototype.trySetRank = function(user, data) { return; var receiver; - for(var i = 0; i < this.users.length; i++) { - if(this.users[i].name == data.user) { - receiver = this.users[i]; + for(var i = 0; i < self.users.length; i++) { + if(self.users[i].name == data.user) { + receiver = self.users[i]; break; } } @@ -1883,94 +1967,24 @@ Channel.prototype.trySetRank = function(user, data) { return; receiver.rank = data.rank; if(receiver.loggedIn) { - this.saveRank(receiver); + self.saveRank(receiver); } - this.broadcastUserUpdate(receiver); + self.broadcastUserUpdate(receiver); } else { - var rrank = this.getRank(data.user); - if(rrank >= user.rank) - return; - this.server.db.setChannelRank(this.name, data.user, data.rank); - } - - this.logger.log("*** " + user.name + " set " + data.user + "'s rank to " + - data.rank); - this.sendAllWithPermission("acl", "setChannelRank", data); -} - -Channel.prototype.tryPromoteUser = function(actor, data) { - if(!Rank.hasPermission(actor, "promote")) { - return; - } - - if(data.name == undefined) { - return; - } - - var name = data.name; - - var receiver; - for(var i = 0; i < this.users.length; i++) { - if(this.users[i].name == name) { - receiver = this.users[i]; - break; - } - } - - var rank = receiver ? receiver.rank : this.getRank(data.name); - - if(actor.rank > rank + 1) { - rank++; - if(receiver) { - receiver.rank++; - if(receiver.loggedIn) { - this.saveRank(receiver); - } - this.broadcastUserUpdate(receiver); - } - else { - this.server.db.setChannelRank(this.name, data.name, rank); - } - this.logger.log("*** " + actor.name + " promoted " + data.name + " from " + (rank - 1) + " to " + rank); - //this.broadcastRankTable(); - } -} - -Channel.prototype.tryDemoteUser = function(actor, data) { - if(!Rank.hasPermission(actor, "promote")) { - return; - } - - if(data.name == undefined) { - return; - } - - var name = data.name; - var receiver; - for(var i = 0; i < this.users.length; i++) { - if(this.users[i].name == name) { - receiver = this.users[i]; - break; - } - } - - var rank = receiver ? receiver.rank : this.getRank(data.name); - - if(actor.rank > rank) { - rank--; - if(receiver) { - receiver.rank--; - if(receiver.loggedIn) { - this.saveRank(receiver); - } - this.broadcastUserUpdate(receiver); - } - else { - this.server.db.setChannelRank(this.name, data.name, rank); - } - this.logger.log("*** " + actor.name + " demoted " + data.name + " from " + (rank + 1) + " to " + rank); - //this.broadcastRankTable(); + self.getRank(data.user, function (err, rrank) { + if(err) + return; + if(rrank >= user.rank) + return; + self.server.db.setChannelRank(this.name, data.user, + data.rank, function (err, res) { + + self.logger.log("*** " + user.name + " set " + + data.user + "'s rank to " + data.rank); + self.sendAllWithPermission("acl", "setChannelRank", data); + }); + }); } } diff --git a/user.js b/user.js index 6395c6c8..dfee73a0 100644 --- a/user.js +++ b/user.js @@ -343,29 +343,7 @@ User.prototype.initCallbacks = function() { if(this.channel == null) { return; } - if(!this.channel.registered) { - this.socket.emit("unregisterChannel", { - success: false, - error: "This channel is already unregistered" - }); - } - else if(this.rank < 10) { - this.socket.emit("unregisterChannel", { - success: false, - error: "You don't have permission to unregister" - }); - } - else if(this.channel.unregister()) { - this.socket.emit("unregisterChannel", { - success: true - }); - } - else { - this.socket.emit("unregisterChannel", { - success: false, - error: "Unregistration failed. Please see a site admin if this continues." - }); - } + this.channel.unregister(this); }.bind(this)); this.socket.on("setOptions", function(data) {