diff --git a/server/apps/mailtest.js b/server/apps/mailtest.js new file mode 100644 index 00000000..0fc45e2c --- /dev/null +++ b/server/apps/mailtest.js @@ -0,0 +1,39 @@ +var cluster = require("cluster"), + net = require("net"), + path = require("path"), + //publicPath = path.join(__dirname, 'public'), + http = require("http"), + port = 8080, + //farmhash = require('farmhash'), + uniqid = require("uniqid"), + num_processes = require("os").cpus().length; + +publicPath = path.join(__dirname, "public"); +pathThumbnails = __dirname; +var nodemailer = require("nodemailer"); +var mailconfig = require(path.join(__dirname, "../config/mailconfig.js")); + +let transporter = nodemailer.createTransport(mailconfig); + +transporter.verify(function(error, success) { + if (error) { + return; + } else { + var message = "Testmail"; + var msg = { + from: mailconfig.from, + to: mailconfig.notify_mail, + subject: "ZOFF: Requested new ", + text: message, + html: message + }; + transporter.sendMail(msg, (error, info) => { + console.log(error); + if (error) { + transporter.close(); + return; + } + transporter.close(); + }); + } +}); diff --git a/server/handlers/dbFunctions/advancedFunctions/changeSong.js b/server/handlers/dbFunctions/advancedFunctions/changeSong.js new file mode 100644 index 00000000..00089cc5 --- /dev/null +++ b/server/handlers/dbFunctions/advancedFunctions/changeSong.js @@ -0,0 +1,195 @@ +var path = require("path"); +var db = require(pathThumbnails + "/handlers/db.js"); +var aggregate = require(pathThumbnails + "/handlers/dbFunctions/aggregate.js"); +var remove = require(pathThumbnails + "/handlers/dbFunctions/remove.js"); +var frontpage = require(pathThumbnails + + "/handlers/dbFunctions/frontpageUpdates.js"); +var findAggregate = [ + { + $match: { + views: { + $exists: false + }, + type: { + $ne: "suggested" + } + } + }, + { + $sort: { + now_playing: -1, + votes: -1, + added: 1, + title: 1 + } + }, + { + $limit: 2 + } +]; + +var verifyAggregate = [ + { + $match: { + now_playing: false, + type: { + $ne: "suggested" + } + } + }, + { + $sort: { + votes: -1, + added: 1, + title: 1 + } + }, + { + $limit: 2 + } +]; + +async function changeSong(coll, error, id, conf, socket) { + return pre(coll, error, id, conf, socket); +} + +async function pre(coll, error, id, conf, socket) { + return new Promise((resolve, reject) => { + var startTime = conf[0].startTime; + if (conf === null || conf.length == 0) { + return; + } + + var now_playing_doc = await aggregate(coll, findAggregate); + if ( + now_playing_doc.length > 0 && + ((id && id == now_playing_doc[0].id) || !id) + ) { + if (error) { + var docs = await remove(coll, { now_playing: true, id: id }); + var next_song; + if (now_playing_doc.length == 2) { + next_song = now_playing_doc[1].id; + } + await post(coll, next_song, conf, socket, error); + /*if (!callback) { + io.to(coll).emit("channel", { + type: "deleted", + value: now_playing_doc[0].id, + removed: true + }); + }*/ + if (docs.deletedCount == 1) { + frontpage.incrementList("frontpage_lists", -1); + } + resolve(); + return; + } else if (conf[0].removeplay === true) { + var docs = await remove(coll, { now_playing: true, id: id }); + var next_song; + if (now_playing_doc.length == 2) next_song = now_playing_doc[1].id; + await post(coll, next_song, conf, socket, error); + if (docs.deletedCount == 1) { + frontpage.incrementList("frontpage_lists", -1); + } + resolve(); + return; + } else { + if ( + (conf[0].skipped_time != undefined && + conf[0].skipped_time != Functions.get_time()) || + conf[0].skipped_time == undefined + ) { + var docs = await update( + coll, + { now_playing: true, id: id }, + { + $set: { + now_playing: false, + votes: 0, + guids: [] + } + }, + { multi: true } + ); + var next_song; + if (now_playing_doc.length == 2) next_song = now_playing_doc[1].id; + await post(coll, next_song, conf, socket, error); + + resolve(); + return; + } + } + } + if ( + now_playing_doc.length > 0 && + now_playing_doc[0].now_playing == true && + now_playing_doc.length > 1 && + now_playing_doc[1].id == id + ) { + var docs = await update( + coll, + { id: now_playing_doc[0].id }, + { $set: { now_playing: false } }, + {} + ); + return await pre(coll, error, id, conf, socket, error); + } + resolve(); + }); +} + +async function post(coll, next_song, conf, socket, removed) { + return new Promise((resolve, reject) => { + var docs = await aggregate(coll, verifyAggregate); + if (docs === null || docs.length == 0) { + reject(); + return; + } + var id = docs[0].id; + if (next_song && next_song != id) { + if (docs.length == 2 && next_song == docs[1].id) { + id = docs[1].id; + } else { + reject(); + return; + } + } + var returnDocs = await update( + coll, + { id: id, now_playing: false }, + { + $set: { + now_playing: true, + votes: 0, + guids: [], + added: Functions.get_time() + } + }, + {} + ); + if ( + (returnDocs.hasOwnProperty("nModified") && returnDocs.nModified == 0) || + (returnDocs.hasOwnProperty("n") && returnDocs.n == 0) + ) { + resolve(); + return; + } + returnDocs = await update( + coll + "_settings", + { id: "config" }, + { + $set: { + startTime: Functions.get_time(), + skips: [] + } + }, + {} + ); + resolve(); + }); +} + +module.exports.changeSong = changeSong; +module.exports.pre = pre; +module.exports.post = post; diff --git a/server/handlers/dbFunctions/advancedFunctions/frontpageUpdates.js b/server/handlers/dbFunctions/advancedFunctions/frontpageUpdates.js new file mode 100644 index 00000000..49a1efde --- /dev/null +++ b/server/handlers/dbFunctions/advancedFunctions/frontpageUpdates.js @@ -0,0 +1,18 @@ +var path = require("path"); +var mongojs = require("mongojs"); +var db = require(pathThumbnails + "/handlers/db.js"); +var update = require(pathThumbnails + "/handlers/dbFunctions/update.js"); + +function incrementList(collection, way) { + return update( + collection, + { _id: coll, count: { $gt: 0 } }, + { + $inc: { count: way }, + $set: { accessed: Functions.get_time() } + }, + { upsert: true } + ); +} + +module.exports.incrementList = incrementList; diff --git a/server/handlers/dbFunctions/advancedFunctions/functions.js b/server/handlers/dbFunctions/advancedFunctions/functions.js new file mode 100644 index 00000000..39ae060b --- /dev/null +++ b/server/handlers/dbFunctions/advancedFunctions/functions.js @@ -0,0 +1,173 @@ +var path = require("path"); +var mongojs = require("mongojs"); +var db = require(pathThumbnails + "/handlers/db.js"); +var find = require(pathThumbnails + "/handlers/dbFunctions/find.js"); +var remove = require(pathThumbnails + "/handlers/dbFunctions/remove.js"); +var update = require(pathThumbnails + "/handlers/dbFunctions/update.js"); + +async function setSessionAdminPass(id, adminpass, list, callback) { + return new Promise((resolve, reject) => { + try { + if (id == "empty" || id == undefined) { + callback(); + return; + } + + var docs = update( + id, + { _id: list }, + { $set: { adminpass: hash_pass(decrypt_string(adminpass), true) } }, + { upsert: true } + ); + callback(); + } catch (e) { + reject(); + } + }); +} + +async function setSessionChatPass(id, name, pass, callback) { + return new Promise((resolve, reject) => { + try { + if (id == "empty" || id == undefined) { + resolve(); + return; + } + var docs = await update( + id, + { _id: "_chat_" }, + { $set: { password: pass, name: name } }, + { upsert: true } + ); + resolve(); + } catch (e) { + reject(); + return; + } + }); +} + +async function getSessionChatPass(id, callback) { + return new Promise((resolve, reject) => { + try { + if (id == "empty" || id == undefined) { + resolve({ name: "", pass: "", gotten: false }); + return; + } + + var d = await find(id, { _id: "_chat_" }); + if (d.length > 0) { + var name = ""; + var pass = ""; + if (d[0].name != undefined) name = d[0].name; + if (d[0].password != undefined) pass = d[0].password; + resolve({ name: name, pass: pass, gotten: false }); + return; + } else { + resolve({ name: "", pass: "", gotten: false }); + return; + } + } catch (e) { + reject(); + return; + } + }); +} + +async function setChromecastHost(id, other_id, list, callback) { + return new Promise((resolve, reject) => { + try { + if ( + id == "empty" || + id == undefined || + other_id == "empty" || + other_id == undefined + ) { + resolve(false); + return; + } + await update( + id, + { _id: list }, + { chromecast: true, id: other_id }, + { upsert: true } + ); + resolve(true); + return; + } catch (e) { + resolve(false); + } + }); +} + +async function setSessionUserPass(id, userpass, list, callback) { + return new Promise((resolve, reject) => { + try { + if (id == "empty" || id == undefined || userpass == undefined) { + reject(); + return; + } + + update( + id, + { _id: list }, + { $set: { userpass: userpass } }, + { upsert: true } + ); + resolve(); + return; + } catch (e) { + reject(); + } + }); +} + +async function getSessionAdminUser(id, list, callback) { + return new Promise((resolve, reject) => { + try { + if (id == "empty" || id == undefined) { + resolve({ userpass: "", adminpass: "", gotten: false }); + return; + } + var d = await find(id, { _id: list }); + var userpass = ""; + var adminpass = ""; + if (d.length > 0) { + if (d[0].hasOwnProperty("chromecast") && d[0].chromecast) { + return await getSessionAdminUser(d[0].id, list, callback); + } else { + if (d[0].userpass != undefined) userpass = d[0].userpass; + if (d[0].adminpass != undefined) adminpass = d[0].adminpass; + resolve({ userpass: userpass, adminpass: adminpass, gotten: true }); + } + } else { + resolve({ userpass: userpass, adminpass: adminpass, gotten: true }); + } + } catch (e) { + resolve({ userpass: "", adminpass: "", gotten: false }); + } + }); +} + +async function removeSessionChatPass(id, callback) { + return new Promise((resolve, reject) => { + if (id == "empty" || id == undefined) { + resolve(); + return; + } + await remove(id, { _id: "_chat_" }); + resolve(); + return; + }); +} + +async function removeSessionAdminPass(id, channel, callback) { + return new Promise((resolve, reject) => { + if (id == "empty" || id == undefined) { + resolve(); + return; + } + await update(id, { _id: channel }, { $set: { adminpass: "" } }); + resolve(); + }); +} diff --git a/server/handlers/dbFunctions/advancedFunctions/joinList.js b/server/handlers/dbFunctions/advancedFunctions/joinList.js new file mode 100644 index 00000000..bc42e2c8 --- /dev/null +++ b/server/handlers/dbFunctions/advancedFunctions/joinList.js @@ -0,0 +1,209 @@ +var path = require("path"); +var mongojs = require("mongojs"); +var db = require(pathThumbnails + "/handlers/db.js"); +var find = require(pathThumbnails + "/handlers/dbFunctions/find.js"); + +async function joinSilent(msg, socket) { + if (typeof msg === "object" && msg !== undefined && msg !== null) { + var channelName = msg.channel; + var tryingPassword = false; + var password = ""; + if (msg.password != "") { + tryingPassword = true; + password = Functions.decrypt_string(msg.password); + password = crypto + .createHash("sha256") + .update(password) + .digest("base64"); + } + + channelName = channelName.toLowerCase(); //.replace(/ /g,''); + channelName = Functions.removeEmojis(channelName).toLowerCase(); + var docs = await find(channelName + "_settings"); + if (docs.length == 0) { + socket.emit("join_silent_declined", ""); + return; + } + if ( + docs[0].userpass == "" || + docs[0].userpass == undefined || + docs[0].userpass == password + ) { + socket.join(channelName); + socket.emit("join_silent_accepted", ""); + + send_play(channelName, socket); + } else { + socket.emit("join_silent_declined", ""); + } + } else { + return; + } +} + +async function list(msg, guid, coll, offline, socket) { + var socketid = socket.zoff_id; + if (typeof msg === "object" && msg !== undefined && msg !== null) { + var sessionAdminUser = await Functions.getSessionAdminUser( + Functions.getSession(socket), + coll + ); + var userpass = sessionAdminUser.userpass; + var adminpass = sessionAdminUser.adminpass; + var gotten = sessionAdminUser.gotten; + if (gotten && userpass != "" && !msg.hasOwnProperty("pass")) { + msg.pass = userpass; + } else { + msg.pass = crypto + .createHash("sha256") + .update(Functions.decrypt_string(msg.pass)) + .digest("base64"); + } + adminpass = Functions.hash_pass(adminpass); + if ( + !msg.hasOwnProperty("version") || + !msg.hasOwnProperty("channel") || + msg.version != VERSION || + msg.version == undefined || + typeof msg.channel != "string" + ) { + var result = { + channel: { + expected: "string", + got: msg.hasOwnProperty("channel") ? typeof msg.channel : undefined + }, + version: { + expected: VERSION, + got: msg.version + }, + pass: { + expected: "string", + got: msg.hasOwnProperty("pass") ? typeof msg.pass : undefined + } + }; + socket.emit("update_required", result); + return; + } + coll = msg.channel.toLowerCase(); //.replace(/ /g,''); + coll = Functions.removeEmojis(coll).toLowerCase(); + //coll = filter.clean(coll); + var pass = msg.pass; + var frontpage_lists = await find("frontpage_lists", { _id: coll }); + if (frontpage_lists.length == 1) { + var docs = await find(coll + "_settings"); + if ( + docs.length == 0 || + (docs.length > 0 && + (docs[0].userpass == undefined || + docs[0].userpass == "" || + docs[0].userpass == pass)) + ) { + if ( + docs.length > 0 && + docs[0].hasOwnProperty("userpass") && + docs[0].userpass != "" && + docs[0].userpass == pass + ) { + Functions.setSessionUserPass( + Functions.getSession(socket), + msg.pass, + coll + ); + socket.emit("auth_accepted", { value: true }); + } + if (docs.length > 0 && docs[0].userpass != pass) { + Functions.setSessionUserPass(Functions.getSession(socket), "", coll); + } + if ( + docs.length > 0 && + docs[0].hasOwnProperty("adminpass") && + docs[0].adminpass != "" && + docs[0].adminpass == adminpass + ) { + socket.emit("pw", true); + } + in_list = true; + socket.join(coll); + Functions.check_inlist( + coll, + guid, + socket, + offline, + undefined, + "place 10" + ); + + if (frontpage_lists[0].viewers != undefined) { + io.to(coll).emit("viewers", frontpage_lists[0].viewers); + } else { + io.to(coll).emit("viewers", 1); + } + + send_list(coll, socket, true, false, true); + } else { + socket.emit("auth_required"); + } + } else { + db.createCollection(coll, function(err, docs) { + db.collection(coll).createIndex({ id: 1 }, { unique: true }, function( + e, + d + ) { + var configs = { + addsongs: false, + adminpass: "", + allvideos: true, + frontpage: true, + longsongs: false, + removeplay: false, + shuffle: true, + skip: false, + skips: [], + startTime: Functions.get_time(), + views: [], + vote: false, + description: "", + thumbnail: "", + rules: "", + userpass: "", + id: "config", + toggleChat: true + }; + db.collection(coll + "_settings").insert(configs, function( + err, + docs + ) { + socket.join(coll); + send_list(coll, socket, true, false, true); + db.collection("frontpage_lists").insert( + { + _id: coll, + count: 0, + frontpage: true, + accessed: Functions.get_time(), + viewers: 1 + }, + function(e, d) {} + ); + Functions.check_inlist( + coll, + guid, + socket, + offline, + undefined, + "place 11" + ); + }); + }); + }); + } + } else { + var result = { + msg: { + expected: "object", + got: typeof msg + } + }; + socket.emit("update_required", result); + } +} diff --git a/server/handlers/dbFunctions/advancedFunctions/play.js b/server/handlers/dbFunctions/advancedFunctions/play.js new file mode 100644 index 00000000..e95f008f --- /dev/null +++ b/server/handlers/dbFunctions/advancedFunctions/play.js @@ -0,0 +1,23 @@ +var path = require("path"); +var mongojs = require("mongojs"); +var db = require(pathThumbnails + "/handlers/db.js"); +var find = require(pathThumbnails + "/handlers/dbFunctions/find.js"); + +async function getNowPlaying(list, socket) { + return new Promise((resolve, reject) => { + if (typeof list !== "string" || typeof fn !== "function") { + socket.emit("update_required"); + return; + } + var docs = await find(list, { now_playing: true }); + if (docs.length === 0) { + resolve("No song currently playing"); + return; + } + var title = docs[0].title; + if (title === undefined) resolve("No song currently playing"); + else resolve(title); + }); +} + +module.exports.getNowPlaying = getNowPlaying; diff --git a/server/handlers/dbFunctions/aggregate.js b/server/handlers/dbFunctions/aggregate.js new file mode 100644 index 00000000..509144b6 --- /dev/null +++ b/server/handlers/dbFunctions/aggregate.js @@ -0,0 +1,17 @@ +var path = require("path"); +var mongojs = require("mongojs"); +var db = require(pathThumbnails + "/handlers/db.js"); + +function aggregate(collection, aggregateObject) { + return new Promise((resolve, reject) => { + db.collection(coll).aggregate(aggregateObject, function(error, results) { + if (error) { + reject(error); + return; + } + resolve(results); + }); + }); +} + +module.exports.aggregate = aggregate; diff --git a/server/handlers/dbFunctions/find.js b/server/handlers/dbFunctions/find.js new file mode 100644 index 00000000..ebc4650e --- /dev/null +++ b/server/handlers/dbFunctions/find.js @@ -0,0 +1,17 @@ +var path = require("path"); +var mongojs = require("mongojs"); +var db = require(pathThumbnails + "/handlers/db.js"); + +function find(collection, searchObject) { + return new Promise((resolve, reject) => { + db.collection(collection).find(searchObject, (error, result) => { + if (error) { + reject(error); + return; + } + resolve(result); + }); + }); +} + +module.exports.find = find; diff --git a/server/handlers/dbFunctions/remove.js b/server/handlers/dbFunctions/remove.js new file mode 100644 index 00000000..2ab01334 --- /dev/null +++ b/server/handlers/dbFunctions/remove.js @@ -0,0 +1,17 @@ +var path = require("path"); +var mongojs = require("mongojs"); +var db = require(pathThumbnails + "/handlers/db.js"); + +function remove(collection, removeObject) { + return new Promise((resolve, reject) => { + db.collection(collection).remove(removeObject, (error, result) => { + if (error) { + reject(error); + return; + } + resolve(result); + }); + }); +} + +module.exports.remove = remove; diff --git a/server/handlers/dbFunctions/update.js b/server/handlers/dbFunctions/update.js new file mode 100644 index 00000000..373f08a5 --- /dev/null +++ b/server/handlers/dbFunctions/update.js @@ -0,0 +1,22 @@ +var path = require("path"); +var mongojs = require("mongojs"); +var db = require(pathThumbnails + "/handlers/db.js"); + +function update(collection, searchObject, updateObject, extraObject) { + return new Promise((resolve, reject) => { + db.collection(collection).update( + searchObject, + updateObject, + extraObject, + (error, result) => { + if (error) { + reject(error); + return; + } + resolve(result); + } + ); + }); +} + +module.exports.update = update;