Files
zoff/server/handlers/chat.js

919 lines
32 KiB
JavaScript

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;