diff --git a/server/handlers/chat.js b/server/handlers/chat.js index 1283e010..a5d88c4b 100644 --- a/server/handlers/chat.js +++ b/server/handlers/chat.js @@ -56,6 +56,16 @@ function getAndSendLogs(channel, all, socket, pass, query) { }); } +function checkIfUserIsBanned(channel, socket, callback) { + var connection_id = Functions.hash_pass(socket.handshake.headers["user-agent"] + socket.handshake.address + socket.handshake.headers["accept-language"]); + db.collection(channel + "_banned_chat").find({connection_id: connection_id}, function(err, docs) { + if(docs.length == 0) callback(); + else { + socket.emit('chat', {from: "System", msg: ": You can't chat in this channel, you are banned. The reason is: " + docs[0].reason, icon: "https://zoff.me/assets/images/favicon-32x32.png"}); + return; + } + }) +} function chat(msg, guid, offline, socket) { if(typeof(msg) !== 'object' || !msg.hasOwnProperty('data') || @@ -80,42 +90,102 @@ function chat(msg, guid, offline, socket) { var coll = msg.channel.toLowerCase();//.replace(/ /g,''); coll = Functions.removeEmojis(coll).toLowerCase(); //coll = filter.clean(coll); - Functions.getSessionAdminUser(Functions.getSession(socket), coll, function(userpass) { - if(userpass != "" || msg.pass == undefined) { - msg.pass = userpass; - } - db.collection(coll + "_settings").find(function(err, docs){ - if(docs.length > 0 && (docs[0].userpass == undefined || docs[0].userpass == "" || (msg.hasOwnProperty('pass') && docs[0].userpass == crypto.createHash('sha256').update(Functions.decrypt_string(msg.pass)).digest("base64")))) { - var data = msg.data; - - Functions.check_inlist(coll, guid, socket, offline, function() { - if(data == "/who") { - db.collection("user_names").distinct("name", {channels: coll}, function(err, docs) { - var userAdd = "s"; - if(docs.length == 1) userAdd = ""; - socket.emit('chat', {from: "System", msg: ": User" + userAdd + " in channel are: " + docs.join(", "), icon: "https://zoff.me/assets/images/favicon-32x32.png"}); - }); - } else if(data !== "" && data !== undefined && data !== null && - data.length < 151 && data.replace(/\s/g, '').length){ - db.collection("user_names").find({"guid": guid}, function(err, docs) { - if(docs.length == 1) { - db.collection("registered_users").find({"_id": docs[0].name}, function(err, n) { - var icon = false; - if(n.length > 0 && n[0].icon) { - icon = n[0].icon; - } - db.collection("chat_logs").insert({ "createdAt": new Date(), all: false, channel: coll, from: docs[0].name, msg: ": " + data, icon: icon }); - io.to(coll).emit('chat', {from: docs[0].name, msg: ": " + data, icon: icon}); - }); - } else if(docs.length == 0){ - get_name(guid, {announce: false, channel: coll, message: data, all: false}); - } - }); - } - }, "place 1"); - } else { - socket.emit('auth_required'); + checkIfUserIsBanned(coll, socket, function() { + Functions.getSessionAdminUser(Functions.getSession(socket), coll, function(userpass, adminpass) { + if(userpass != "" || msg.pass == undefined) { + msg.pass = userpass; } + db.collection(coll + "_settings").find(function(err, conf){ + if(conf.length > 0 && (conf[0].userpass == undefined || conf[0].userpass == "" || (msg.hasOwnProperty('pass') && conf[0].userpass == crypto.createHash('sha256').update(Functions.decrypt_string(msg.pass)).digest("base64")))) { + var data = msg.data; + + Functions.check_inlist(coll, guid, socket, offline, function() { + if(data == "/who") { + db.collection("user_names").distinct("name", {channels: coll}, function(err, docs) { + var userAdd = "s"; + if(docs.length == 1) userAdd = ""; + socket.emit('chat', {from: "System", msg: ": User" + userAdd + " in channel are: " + docs.join(", "), icon: "https://zoff.me/assets/images/favicon-32x32.png"}); + }); + } else if(data !== "" && data !== undefined && data !== null && + data.length < 151 && data.replace(/\s/g, '').length){ + db.collection("user_names").find({"guid": guid}, function(err, docs) { + if(docs.length == 1) { + var splitData = data.split(" "); + if((data.startsWith("/ban") && splitData.length >= 3) || (data.startsWith("/unban") && splitData.length >= 2)) { + if(splitData[1].length > 0) { + var passToCompare = Functions.hash_pass(Functions.hash_pass(Functions.decrypt_string(adminpass), true)) + if(passToCompare == conf[0].adminpass) { + db.collection("user_names").find({name: splitData[1]}, function(err, name) { + if(name.length == 1) { + if(data.startsWith("/ban") && splitData.length >= 3) { + var reason = splitData.slice(2, splitData.length).join(" "); + var connection_id = name[0].connection_id; + var yourSelf = Functions.hash_pass(socket.handshake.headers["user-agent"] + socket.handshake.address + socket.handshake.headers["accept-language"]); + if(connection_id != yourSelf) { + db.collection(coll + "_banned_chat").update({ + connection_id: connection_id + }, { + connection_id: connection_id, + by: docs[0].name, + reason: reason + }, { + upsert: true + }, function(err, results) { + io.to(coll).emit('chat', {from: "System", msg: ": " + docs[0].name + " has banned " + splitData[1] + " for: " + reason, icon: "https://zoff.me/assets/images/favicon-32x32.png"}); + return; + }); + } else { + socket.emit('chat', {from: "System", msg: ": I'm sorry but you can't ban yourself..", icon: "https://zoff.me/assets/images/favicon-32x32.png"}); + return; + } + } else if(data.startsWith("/unban")) { + db.collection(coll + "_banned_chat").remove({connection_id: name[0].connection_id}, function(err, results) { + if(results.hasOwnProperty("n") && results.n == 1 && results.hasOwnProperty("deletedCount") && results.deletedCount == 1) { + io.to(coll).emit('chat', {from: "System", msg: ": " + docs[0].name + " has unbanned " + splitData[1], icon: "https://zoff.me/assets/images/favicon-32x32.png"}); + return; + } else { + socket.emit('chat', {from: "System", msg: ": Cannot find anyone with that username in this chat.", icon: "https://zoff.me/assets/images/favicon-32x32.png"}); + return; + } + + }) + } else if(data.startsWith("/ban") && splitData.length < 3) { + socket.emit('chat', {from: "System", msg: ": You are doing that command wrong. its /ban USERNAME", icon: "https://zoff.me/assets/images/favicon-32x32.png"}); + return; + } + } else { + socket.emit('chat', {from: "System", msg: ": No user by that name.", icon: "https://zoff.me/assets/images/favicon-32x32.png"}); + return; + } + }); + } else { + socket.emit('chat', {from: "System", msg: ": You are not logged in as an admin to the channel, don't try any funnybusiness.", icon: "https://zoff.me/assets/images/favicon-32x32.png"}); + return; + } + } else { + socket.emit('chat', {from: "System", msg: ": You are doing that command wrong. its /ban USERNAME REASON or /unban USERNAME", icon: "https://zoff.me/assets/images/favicon-32x32.png"}); + return; + } + } else { + db.collection("registered_users").find({"_id": docs[0].name}, function(err, n) { + var icon = false; + if(n.length > 0 && n[0].icon) { + icon = n[0].icon; + } + db.collection("chat_logs").insert({ "createdAt": new Date(), all: false, channel: coll, from: docs[0].name, msg: ": " + data, icon: icon }); + io.to(coll).emit('chat', {from: docs[0].name, msg: ": " + data, icon: icon}); + }); + } + } else if(docs.length == 0){ + get_name(guid, {announce: false, channel: coll, message: data, all: false, socket: socket}); + } + }); + } + }, "place 1"); + } else { + socket.emit('auth_required'); + } + }); }); }); } @@ -155,7 +225,7 @@ function all_chat(msg, guid, offline, socket) { io.sockets.emit('chat.all', {from: docs[0].name, msg: ": " + data, channel: coll, icon: icon}); }); } else if(docs.length == 0) { - get_name(guid, {announce: false, channel: coll, message: data, all: true}); + get_name(guid, {announce: false, channel: coll, message: data, all: true, socket: socket}); } }); } @@ -165,107 +235,110 @@ function all_chat(msg, guid, offline, socket) { function namechange(data, guid, socket, tried, callback) { /*if(!data.hasOwnProperty("channel") || typeof(data.channel) != "string") return;*/ - var pw = ""; - var new_password; - var first = false; - Functions.getSessionChatPass(Functions.getSession(socket), function(name, pass) { - if(data.hasOwnProperty("first") && data.first) { - pw = pass; - name = name; - data.name = name; - data.password = pass; - new_password = false; - if(name == "" || pass == "") { - if(typeof(callback) == "function") callback(); - return; - } - } else { - var name = data.name; - if(data.hasOwnProperty("first")) { - first = data.first; - } - if(data.hasOwnProperty("password")) { - pw = data.password; + checkIfUserIsBanned(data.channel, socket, function() { + var pw = ""; + var new_password; + var first = false; + Functions.getSessionChatPass(Functions.getSession(socket), function(name, pass) { + if(data.hasOwnProperty("first") && data.first) { + pw = pass; + name = name; + data.name = name; + data.password = pass; new_password = false; - } else if(data.hasOwnProperty("new_password") && data.hasOwnProperty("old_password")) { - pw = data.old_password; - new_password = Functions.decrypt_string(data.new_password); - } - } - - if(name == "") { - if(typeof(callback) == "function") callback(); - return; - } - var password = Functions.decrypt_string(pw); - db.collection("registered_users").find({"_id": name.toLowerCase()}, function(err, docs) { - var accepted_password = false; - var icon = false; - if(docs.length == 0) { - if(new_password) { + if(name == "" || pass == "") { if(typeof(callback) == "function") callback(); return; } - accepted_password = true; - Functions.setSessionChatPass(Functions.getSession(socket), name.toLowerCase(), data.password, function() { - db.collection("registered_users").update({"_id": name.toLowerCase()}, {$set: {password: Functions.hash_pass(password)}}, {upsert: true}, function() { - }); - }); - } else if(docs[0].password == Functions.hash_pass(password)) { - if(docs[0].icon) { - icon = docs[0].icon; + } else { + var name = data.name; + if(data.hasOwnProperty("first")) { + first = data.first; } - accepted_password = true; - if(new_password) { - Functions.setSessionChatPass(Functions.getSession(socket), name.toLowerCase(), data.new_password, function() { - db.collection("registered_users").update({"_id": name.toLowerCase(), password: Functions.hash_pass(password)}, {$set: {password: Functions.hash_pass(new_password)}}, function() { - - }); - }); - } else { - Functions.setSessionChatPass(Functions.getSession(socket), name.toLowerCase(), data.password, function() { - }); + if(data.hasOwnProperty("password")) { + pw = data.password; + new_password = false; + } else if(data.hasOwnProperty("new_password") && data.hasOwnProperty("old_password")) { + pw = data.old_password; + new_password = Functions.decrypt_string(data.new_password); } } - if(accepted_password) { - db.collection("user_names").find({"guid": guid}, function(err, names) { - if(names.length > 0 || (docs.length != 0 && docs[0].password == Functions.hash_pass(password))) { - var no_name = false; - if(names.length == 0) no_name = true; - if(!no_name) { - var old_name = names[0].name; - db.collection("user_names").update({"_id": "all_names"}, {$pull: {names: old_name}}, function() {}); - } - var updateElement = {$set: {name: name, icon: icon}}; - if(data.hasOwnProperty("channel") && data.channel != "") { - updateElement["$addToSet"] = {channels: data.channel}; - } - db.collection("user_names").update({"guid": guid}, updateElement, {upsert: true}, function(err, docs) { - db.collection("user_names").update({"_id": "all_names"}, {$addToSet: {names: name}}, function(err, docs) { - //socket.emit('name', {type: "name", accepted: true}); - if(old_name != name && !first && !no_name) { - if(data.hasOwnProperty("channel") && typeof(data.channel) == "string") { - io.to(data.channel).emit('chat', {from: old_name, msg: " changed name to " + name}); - io.sockets.emit('chat.all', {from: old_name , msg: " changed name to " + name, channel: data.channel}); - } - } - if(callback != undefined && typeof(callback) == "function") callback(); + + if(name == "") { + if(typeof(callback) == "function") callback(); + return; + } + var password = Functions.decrypt_string(pw); + db.collection("registered_users").find({"_id": name.toLowerCase()}, function(err, docs) { + var accepted_password = false; + var icon = false; + if(docs.length == 0) { + if(new_password) { + if(typeof(callback) == "function") callback(); + return; + } + accepted_password = true; + Functions.setSessionChatPass(Functions.getSession(socket), name.toLowerCase(), data.password, function() { + db.collection("registered_users").update({"_id": name.toLowerCase()}, {$set: {password: Functions.hash_pass(password)}}, {upsert: true}, function() { + }); + }); + } else if(docs[0].password == Functions.hash_pass(password)) { + if(docs[0].icon) { + icon = docs[0].icon; + } + accepted_password = true; + if(new_password) { + Functions.setSessionChatPass(Functions.getSession(socket), name.toLowerCase(), data.new_password, function() { + db.collection("registered_users").update({"_id": name.toLowerCase(), password: Functions.hash_pass(password)}, {$set: {password: Functions.hash_pass(new_password)}}, function() { + }); }); } else { - if(tried < 3 || tried == undefined) { - if(tried == undefined) { - tried = 1; - } - namechange(data, guid, socket, tried + 1); - } + Functions.setSessionChatPass(Functions.getSession(socket), name.toLowerCase(), data.password, function() { + }); } - }); - } else { - Functions.removeSessionChatPass(Functions.getSession(socket), function() { - socket.emit('name', {type: "name", accepted: false}); - }); - } + } + if(accepted_password) { + db.collection("user_names").find({"guid": guid}, function(err, names) { + if(names.length > 0 || (docs.length != 0 && docs[0].password == Functions.hash_pass(password))) { + var no_name = false; + if(names.length == 0) no_name = true; + if(!no_name) { + var old_name = names[0].name; + db.collection("user_names").update({"_id": "all_names"}, {$pull: {names: old_name}}, function() {}); + } + var connection_id = Functions.hash_pass(socket.handshake.headers["user-agent"] + socket.handshake.address + socket.handshake.headers["accept-language"]); + var updateElement = {$set: {name: name, icon: icon, connection_id: connection_id}}; + if(data.hasOwnProperty("channel") && data.channel != "") { + updateElement["$addToSet"] = {channels: data.channel}; + } + db.collection("user_names").update({"guid": guid}, updateElement, {upsert: true}, function(err, docs) { + db.collection("user_names").update({"_id": "all_names"}, {$addToSet: {names: name}}, function(err, docs) { + //socket.emit('name', {type: "name", accepted: true}); + if(old_name != name && !first && !no_name) { + if(data.hasOwnProperty("channel") && typeof(data.channel) == "string") { + io.to(data.channel).emit('chat', {from: old_name, msg: " changed name to " + name}); + io.sockets.emit('chat.all', {from: old_name , msg: " changed name to " + name, channel: data.channel}); + } + } + if(callback != undefined && typeof(callback) == "function") callback(); + }); + }); + } else { + if(tried < 3 || tried == undefined) { + if(tried == undefined) { + tried = 1; + } + namechange(data, guid, socket, tried + 1); + } + } + }); + } else { + Functions.removeSessionChatPass(Functions.getSession(socket), function() { + socket.emit('name', {type: "name", accepted: false}); + }); + } + }); }); }); } @@ -278,7 +351,7 @@ function removename(guid, coll, socket) { Functions.removeSessionChatPass(Functions.getSession(socket), function() { db.collection("user_names").update({"_id": "all_names"}, {$pull: {names: old_name}}, function(err, updated) { db.collection("user_names").remove({"guid": guid}, function(err, removed) { - get_name(guid, {announce: true, old_name: old_name, channel: coll}); + get_name(guid, {announce: true, old_name: old_name, channel: coll, socket: socket}); }); }); }); @@ -293,10 +366,14 @@ function generate_name(guid, announce_payload, second, round, channel) { if(docs.length == 0) { db.collection("user_names").update({"_id": "all_names"}, {$addToSet: {names: tmp_name}}, {upsert: true}, function(err, updated) { if(updated.nModified == 1 || (updated.hasOwnProperty("upserted") && updated.hasOwnProperty("n") && updated.n == 1)) { - var updateElement = {$set: {name: tmp_name, icon: false}}; + var connection_id = Functions.hash_pass(announce_payload.socket.handshake.headers["user-agent"] + announce_payload.socket.handshake.address + announce_payload.socket.handshake.headers["accept-language"]); + var updateElement = {$set: {name: tmp_name, icon: false, connection_id: connection_id}}; if(channel != undefined && channel != "") { updateElement["$addToSet"] = {channels: channel}; } + if(announce_payload.hasOwnProperty("channel") && announce_payload.channel != "") { + updateElement["$addToSet"] = {channels: announce_payload.channel}; + } db.collection("user_names").update({"guid": guid}, updateElement, {upsert: true}, function(err, update){ name = tmp_name; if(announce_payload.announce) { @@ -333,7 +410,10 @@ function get_name(guid, announce_payload, first) { } Functions.setSessionChatPass(Functions.getSession(announce_payload.socket), name.toLowerCase(), pass, function() { }); - db.collection("user_names").update({"guid": guid}, {$set: {name: name, icon: icon}}, {upsert: true}, function(err, docs) { + var connection_id = Functions.hash_pass(announce_payload.socket.handshake.headers["user-agent"] + announce_payload.socket.handshake.address + announce_payload.socket.handshake.headers["accept-language"]); + var updateElement = {$set: {name: name, icon: icon, connection_id: connection_id}}; + if(announce_payload.hasOwnProperty("channel") && announce_payload.channel != "") updateElement["$addToSet"] = {channel: announce_payload.channel}; + db.collection("user_names").update({"guid": guid}, updateElement, {upsert: true}, function(err, docs) { db.collection("user_names").update({"_id": "all_names"}, {$addToSet: {names: name}}, function(err, docs) { name = name; }); @@ -349,7 +429,7 @@ function get_name(guid, announce_payload, first) { function get_name_generate(guid, announce_payload, first, channel) { db.collection("user_names").find({"guid": guid}, function(err, docs) { if(docs.length == 0) { - generate_name(guid, announce_payload, channel); + generate_name(guid, announce_payload, undefined); } else { name = docs[0].name; } diff --git a/server/public/assets/js/chat.js b/server/public/assets/js/chat.js index 2b572ac5..d33911c4 100755 --- a/server/public/assets/js/chat.js +++ b/server/public/assets/js/chat.js @@ -2,6 +2,10 @@ var Chat = { channel_received: 0, all_received: 0, + chat_admin_help: [ + "/ban USERNAME REASON to ban user", + "/unban USERNAME to unban a user" + ], chat_help: [ "/login to register and save a password for a nickname, or to log in with a password on a name.", "/login to change the password on a nickname", @@ -62,7 +66,9 @@ var Chat = { } add = "chatchannel"; } - for(var x = 0; x < Chat.chat_help.length; x++) { + var help = Chat.chat_help; + if(Admin.logged_in) help = help.concat(Chat.chat_admin_help); + for(var x = 0; x < help.length; x++) { var color = Helper.intToARGB(Helper.hashCode("System")); if(color.length < 6) { for(x = color.length; x < 6; x++) { @@ -75,7 +81,7 @@ var Chat = { var color_temp = Helper.rgbToHsl([color.r, color.g, color.b], false); document.querySelector("#" + add).insertAdjacentHTML("beforeend", "
  • " + time + " SystemSystem:
  • "); - var in_text = document.createTextNode(Chat.chat_help[x]); + var in_text = document.createTextNode(help[x]); document.querySelector("#" + add).children[document.querySelector("#" + add).children.length - 1].appendChild(in_text); document.getElementById("" + add).scrollTop = document.getElementById("" + add).scrollHeight; }