var Functions = require(pathThumbnails + "/handlers/functions.js"); var crypto = require("crypto"); var Filter = require("bad-words"); var filter = new Filter({ placeHolder: "x" }); /*var filter = { clean: function(str) { return str; } }*/ var db = require(pathThumbnails + "/handlers/db.js"); function get_history(channel, all, socket) { var query = {}; if (all) { query = { all: true }; } else { query = { all: false, channel: channel }; } //channel = channel.replace(/ /g,''); var pass = ""; if (!query.all) { Functions.getSessionAdminUser( Functions.getSession(socket), channel, function(userpass) { if (userpass != "" || pass == undefined) { pass = userpass; } else { pass = crypto .createHash("sha256") .update(Functions.decrypt_string(pass)) .digest("base64"); } db.collection(channel + "_settings").find({ id: "config" }, function( err, conf ) { if (conf.length > 0) { if (conf[0].userpass == "" || conf[0].userpass == pass) { getAndSendLogs(channel, all, socket, pass, query); } } }); } ); } else { getAndSendLogs(channel, all, socket, pass, query); } } function getAndSendLogs(channel, all, socket, pass, query) { //channel = channel.replace(/ /g,''); db.collection("chat_logs") .find(query, { from: 1, createdAt: 1, all: 1, channel: 1, msg: 1, icon: 1, _id: 0 }) .sort({ createdAt: 1 }) .limit(20, function(err, docs) { socket.emit("chat_history", { all: all, data: docs }); }); } function chat(msg, guid, offline, socket) { if ( typeof msg !== "object" || !msg.hasOwnProperty("data") || !msg.hasOwnProperty("channel") || typeof msg.data != "string" || typeof msg.channel != "string" ) { var result = { data: { expected: "string", got: msg.hasOwnProperty("data") ? typeof msg.data : undefined }, channel: { expected: "string", got: msg.hasOwnProperty("channel") ? typeof msg.channel : undefined }, pass: { expected: "string", got: msg.hasOwnProperty("pass") ? typeof msg.pass : undefined } }; socket.emit("update_required", result); return; } var coll = msg.channel.toLowerCase(); //.replace(/ /g,''); coll = Functions.removeEmojis(coll).toLowerCase(); //coll = filter.clean(coll); checkIfUserIsBanned(coll, socket, guid, function() { Functions.getSessionAdminUser(Functions.getSession(socket), coll, function( userpass, adminpass ) { if (userpass != "" || msg.pass == undefined) { msg.pass = userpass; } else { msg.pass = crypto .createHash("sha256") .update(Functions.decrypt_string(msg.pass)) .digest("base64"); } db.collection(coll + "_settings").find(function(err, conf) { if ( conf.length > 0 && (conf[0].hasOwnProperty("toggleChat") && !conf[0].toggleChat) ) { socket.emit("chat", { from: "System", msg: ": Chat for this channel has been disabled.", icon: "https://zoff.me/assets/images/favicon-32x32.png" }); return; } else if ( conf.length > 0 && (conf[0].userpass == undefined || conf[0].userpass == "" || (msg.hasOwnProperty("pass") && conf[0].userpass == msg.pass)) ) { 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(adminpass); 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"); } }); }); }); } function all_chat(msg, guid, offline, socket) { if ( typeof msg !== "object" || !msg.hasOwnProperty("channel") || !msg.hasOwnProperty("data") || typeof msg.data != "string" || typeof msg.channel != "string" ) { var result = { data: { expected: "string", got: msg.hasOwnProperty("data") ? typeof msg.data : undefined }, channel: { expected: "string", got: msg.hasOwnProperty("channel") ? typeof msg.channel : undefined } }; socket.emit("update_required", result); return; } var coll = msg.channel.toLowerCase(); //.replace(/ /g,''); var data = msg.data; coll = Functions.removeEmojis(coll).toLowerCase(); //coll = filter.clean(coll); Functions.check_inlist( coll, guid, socket, offline, function() { 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: true, channel: coll, from: docs[0].name, msg: ": " + data, icon: icon }, function(err, docs) {} ); 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, socket: socket }); } }); } }, "place 2" ); } function checkIfChatEnabled(channel, socket, callback) { if (channel == "" || channel == undefined) callback(); else { db.collection(channel + "_settings").find(function(err, docs) { if ( docs.length > 0 && (docs[0].hasOwnProperty("toggleChat") && !docs[0].toggleChat) ) { socket.emit("chat", { from: "System", msg: ": Chat for this channel has been disabled.", icon: "https://zoff.me/assets/images/favicon-32x32.png" }); callback(false); } else { callback(true); } }); } } function checkIfUserIsBanned(channel, socket, guid, callback, callback_error) { 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( { $or: [{ connection_id: connection_id }, { connection_id: guid }] }, function(err, docs) { if (docs.length == 0) callback(); else { db.collection("user_names").findAndModify( { query: { guid, guid }, update: { $addToSet: { channels: channel } } }, function(e, d) { 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" }); if (typeof callback_error == "function") callback_error(); else return; } ); } } ); } function namechange(data, guid, socket, tried, callback) { checkIfChatEnabled(data.channel, socket, function(enabled) { if (!enabled) { callback(false); return; } checkIfUserIsBanned( data.channel, socket, guid, function() { var pw = ""; var new_password; var first = false; Functions.getSessionChatPass(Functions.getSession(socket), function( name, pass ) { var fetched = false; 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(true); return; } fetched = true; password = pw; } else { var name = data.name; if (data.hasOwnProperty("first")) { first = data.first; } 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); } password = Functions.decrypt_string(pw); password = Functions.hash_pass(password); doubled = true; } if (name == "") { if (typeof callback == "function") callback(true); return; } 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(true); return; } accepted_password = true; Functions.setSessionChatPass( Functions.getSession(socket), name.toLowerCase(), data.password, function() { db.collection("registered_users").update( { _id: name.toLowerCase() }, { $set: { password: password } }, { upsert: true }, function() {} ); } ); } else if (docs[0].password == 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: password }, { $set: { password: Functions.hash_pass(new_password) } }, function() {} ); } ); } else { Functions.setSessionChatPass( Functions.getSession(socket), name.toLowerCase(), fetched ? data.password : Functions.hash_pass( Functions.decrypt_string(data.password) ), function() {} ); } } if (accepted_password) { db.collection("user_names").find({ guid: guid }, function( err, names ) { if ( names.length > 0 || (docs.length != 0 && docs[0].password == 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(true); } ); } ); } 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 }); } ); } } ); }); }, callback ); }); } function removename(guid, coll, socket) { //coll = coll.replace(/ /g,''); checkIfChatEnabled(coll, socket, function(enabled) { if (!enabled) return; db.collection("user_names").find({ guid: guid }, function(err, docs) { if (docs.length == 1) { var old_name = docs[0].name; 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, socket: socket }); }); } ); } ); } }); }); } function generate_name(guid, announce_payload, second, round, channel) { if (round == undefined) round = 0; var tmp_name = Functions.rndName( second ? second : guid, Math.floor(8 + round) ); db.collection("registered_users").find({ _id: tmp_name }, function( err, docs ) { 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 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) { io.to(announce_payload.channel).emit("chat", { from: announce_payload.old_name, msg: " changed name to " + name }); io.sockets.emit("chat.all", { from: announce_payload.old_name, msg: " changed name to " + name, channel: announce_payload.channel }); } else if (announce_payload.message && !announce_payload.all) { io.to(announce_payload.channel).emit("chat", { from: name, msg: ": " + announce_payload.message }); } else if (announce_payload.message && announce_payload.all) { io.sockets.emit("chat.all", { from: name, msg: ": " + announce_payload.message, channel: announce_payload.channel }); } } ); } else { generate_name( guid, announce_payload, tmp_name, round + 0.25, channel ); } } ); } else { generate_name(guid, announce_payload, tmp_name, round + 0.25, channel); } }); } function get_name(guid, announce_payload, first) { if (!announce_payload.announce && announce_payload.hasOwnProperty("socket")) { Functions.getSessionChatPass( Functions.getSession(announce_payload.socket), function(name, pass) { if (name == "" || pass == "") { get_name_generate( guid, announce_payload, first, announce_payload.channel ); return; } db.collection("registered_users").find( { _id: name.toLowerCase() }, function(err, docs) { if ( docs[0].password == Functions.hash_pass(Functions.decrypt_string(pass)) ) { var icon = false; if (docs[0].icon) { icon = docs[0].icon; } Functions.setSessionChatPass( Functions.getSession(announce_payload.socket), name.toLowerCase(), pass, function() {} ); 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; } ); } ); } } ); } ); } else { get_name_generate(guid, announce_payload, first, announce_payload.channel); } } 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, undefined); } else { name = docs[0].name; } }); } module.exports.get_history = get_history; module.exports.chat = chat; module.exports.all_chat = all_chat; module.exports.namechange = namechange; module.exports.removename = removename; module.exports.generate_name = generate_name; module.exports.get_name = get_name;