Files
zoff/server/handlers/chat.js
Kasper Rynning-Tønnesen 03ca6a9f77 Fix/total listeners disabled chat (#458)
* Testing some leavers

* Logging before and after namechange

* Testing callback even on chat disabled

* Fixed issue with channels with disabled chat not adding to total listeners

* Fixed potential issue with joining a channel with disabled chat broadcasts it
2019-01-15 19:04:08 +01:00

487 lines
27 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;