const internal = require("stream"); const { __glob, __web } = require("./global-variables"); const { LogType } = require("./sub-log"); const log = require("./sub-log"); const auth = require("./sub-auth"); const cook = require("cookie") const wlog = new LogType("Web") const subplayer = require(__glob.SUBPLAYER); const { List } = require("./sub-list") const subplaylist = require("./sub-playlist") var fs = require("fs") var path = require("path") module.exports.WebServer = class { constructor() { wlog.step.init("start_server", "Démarrage du serveur Express (Web)") init() } } function init() { const createError = require('http-errors'); const express = require('express'); const path = require('path'); const cookieParser = require('cookie-parser'); const http = require("http"); const favicon = require('express-favicon'); const app = express(); const port = normalizePort(process.env.PORT || '4000'); const server = require('http').createServer(app); const io = require('socket.io')(server) const indexRouter = require(__web.ROUTER + "index.js"); const loginRouter = require(__web.ROUTER + "login.js"); const internalRouter = require(__web.ROUTER + "internal.js") IOConnection(io) app.set('views', __web.TEMPLATES); // general config app.set('view engine', 'ejs'); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(__web.PUBLIC)); app.set('port', port); app.use('/', indexRouter); app.use('/login', loginRouter); app.use("/internal", internalRouter) app.use(favicon(__web.ICON)); app.use(function (req, res, next) { next(createError(404)); }); app.use(function (err, req, res, next) { // Set locals, only providing error // in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); server.listen(port); server.on('error', (error) => { if (error.syscall !== 'listen') { throw error; } let bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; // Handle specific listen errors with // friendly messages switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); break; default: throw error; } }); server.on('listening', () => { let addr = server.address(); let bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; wlog.log("Serveur démarré sur le port : " + bind ) }); wlog.step.end("start_server") } // EXPRESS FUNCTIONS function normalizePort(val) { let port = parseInt(val, 10); if (isNaN(port)) { // Named pipe return val; } if (port >= 0) { // Port number return port; } return false; } function IOConnection(io) { const alog = log.getInstance("Authentification") process.on("MUSIC_UPDATE_STATE", () => { const data = subplayer.updateMusicState() io.sockets.emit("/ALWAYS/MUSIC_STATE", data) }) io.on("connection", (socket) => { wlog.log("[SOCKET] - Nouvelle session : " + socket.id) socket.on("disconnect", () => { wlog.log("[SOCKET] - Fin de session : " + socket.id) }) // SPECIAL socket.on("GET/DISCORD_LOGIN_LINK", () => { var discordlink = null if(process.env.DEV == "true") { alog.log("Mode Developpeur Actif : Redirige vers LOCALHOST") discordlink = "https://discord.com/api/oauth2/authorize?client_id=1094727789682380922&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Finternal%2Fredirect&response_type=code&scope=identify%20guilds%20guilds.members.read" //DEV } else { discordlink = "https://discord.com/api/oauth2/authorize?client_id=1094727789682380922&redirect_uri=https%3A%2F%2Fsubsonics.raphix.fr%2Finternal%2Fredirect&response_type=code&scope=identify%20guilds%20guilds.members.read" //OFFICIEL } alog.log("Redirection de '" + socket.id + "' vers le service d'Authentification de Discord [ETAPE 1]") io.emit("ANSWER/GET/DISCORD_LOGIN_LINK", discordlink ) }) GetRequest(io, socket, "USER_INFO", () => { var cookies = socket.handshake.headers.cookie cookies = cook.parse(cookies) var token = cookies.token const user = auth.getUser(token) alog.log("Envoi des informations Discord de '" + user.user.username + "' à '" + socket.id + "'" ) socket.emit("ANSWER/GET/USER_INFO",user) }) GetRequest(io, socket, "MUSIC_STATE", () => { var cookies = socket.handshake.headers.cookie cookies = cook.parse(cookies) var token = cookies.token const data = subplayer.updateMusicState() const user = auth.getUser(token) socket.emit("ANSWER/GET/MUSIC_STATE", "Bienvenue " + user.user.username + " ! ") io.sockets.emit("/ALWAYS/MUSIC_STATE", data) }) GetRequest(io, socket, "PLAYLIST", () => { var cookies = socket.handshake.headers.cookie cookies = cook.parse(cookies) var token = cookies.token const user = auth.getUser(token) const playlistResult = subplaylist.getUser(user.user.id) socket.emit("ANSWER/GET/PLAYLIST", playlistResult) }) GetRequest(io, socket, "LOGS", () => { var cookies = socket.handshake.headers.cookie cookies = cook.parse(cookies) var token = cookies.token const user = auth.getUser(token) const logs_data = new Array() if(user.admin == true) { const logs_folder = fs.readdirSync(__glob.LOGS) for(var log of logs_folder) { logs_data.push({"name":log, "value": fs.readFileSync(__glob.LOGS + path.sep + log).toString()}) } socket.emit("ANSWER/GET/LOGS", logs_data) } }) GetRequest(io, socket, "PAUSE", () => { subplayer.pause() io.emit("ANSWER/GET/PAUSE", "OK") }) GetRequest(io, socket, "BACKWARD", () => { subplayer.previous() io.emit("ANSWER/GET/BACKWARD", "OK") }) GetRequest(io, socket, "FORWARD", () => { subplayer.skip() io.emit("ANSWER/GET/FORWARD", "OK") }) GetRequest(io, socket, "LOOP", () => { subplayer.loop() io.emit("ANSWER/GET/LOOP", "OK") }) GetRequest(io, socket, "SHUFFLE", () => { subplayer.changeShuffle() io.emit("ANSWER/GET/SHUFFLE", "OK") }) GetRequest(io, socket, "DISCONNECT", () => { subplayer.leave() io.emit("ANSWER/GET/DISCONNECT", "OK") }) GetRequest(io, socket, "RESTART", () => { const pm2 = require('pm2'); pm2.restart('SubSonics - Bot Discord') }) GetRequest(io, socket, "SPECIAL/MJ", () => { var cookiesA = socket.handshake.headers.cookie cookiesA = cook.parse(cookiesA) var tokenA = cookiesA.token var userA = auth.getUser(tokenA) var userId = userA.user.id subplayer.SPECIAL_MJ(null, userId) io.emit("ANSWER/GET/SPECIAL/MJ", "OK") }) // SEND REQUEST socket.on("SEND/SEEK", (data) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { subplayer.seek(data) } else { io.emit("ANSWER/SEND/SEEK", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/SEEK", {"error":"TOKEN_NOT_FINDED"}) } }) socket.on("SEND/VOLUME", (data) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { subplayer.setVol(data) } else { io.emit("ANSWER/SEND/VOLUME", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/VOLUME", {"error":"TOKEN_NOT_FINDED"}) } }) socket.on("SEND/DELETE_QUEUE", (data) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { var sublist = new List() sublist.removeByIndex(data) } else { io.emit("ANSWER/SEND/DELETE_QUEUE", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/DELETE_QUEUE", {"error":"TOKEN_NOT_FINDED"}) } }) socket.on("SEND/MOVE_QUEUE", (data) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { var sublist = new List() sublist.moveUp(data) } else { io.emit("ANSWER/SEND/DELETE_QUEUE", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/DELETE_QUEUE", {"error":"TOKEN_NOT_FINDED"}) } }) socket.on("SEND/REPORT", (data) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { data.username = auth.getUser(token) subplayer.report(null, null, data) } else { io.emit("ANSWER/SEND/REPORT", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/REPORT", {"error":"TOKEN_NOT_FINDED"}) } }) socket.on("SEND/SEARCH", async (data) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { const results = await subplayer.search(data) io.emit("ANSWER/SEND/SEARCH", results) } else { io.emit("ANSWER/SEND/SEARCH", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/SEARCH", {"error":"TOKEN_NOT_FINDED"}) } }) socket.on("SEND/ADD_SONG", async (data) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { var user = auth.getUser(token) var userId = user.user.id subplayer.addSong(data, null, userId) io.emit("ANSWER/SEND/ADD_SONG/OK") } else { io.emit("ANSWER/SEND/ADD_SONG", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/ADD_SONG", {"error":"TOKEN_NOT_FINDED"}) } }) socket.on("SEND/ADD_SONG_NOW", async (data) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { var user = auth.getUser(token) var userId = user.user.id subplayer.addSong(data, null, userId, true) io.emit("ANSWER/SEND/ADD_SONG_NOW/OK") } else { io.emit("ANSWER/SEND/ADD_SONG_NOW", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/ADD_SONG_NOW", {"error":"TOKEN_NOT_FINDED"}) } }) socket.on("SEND/FP_ADD_SONG", async (data) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { var user = auth.getUser(token) var userId = user.user.id subplayer.addSong(data, null, userId, false, true) io.emit("ANSWER/SEND/FP_ADD_SONG/OK") } else { io.emit("ANSWER/SEND/FP_ADD_SONG", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/FP_ADD_SONG", {"error":"TOKEN_NOT_FINDED"}) } }) socket.on("SEND/FP_ADD_SONG_NOW", async (data) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { var user = auth.getUser(token) var userId = user.user.id subplayer.addSong(data, null, userId, true, true) io.emit("ANSWER/SEND/FP_ADD_SONG_NOW/OK") } else { io.emit("ANSWER/SEND/FP_ADD_SONG_NOW", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/FP_ADD_SONG_NOW", {"error":"TOKEN_NOT_FINDED"}) } }) socket.on("SEND/FP_PLAY_PLAYLIST", async (data) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { var user = auth.getUser(token) var userId = user.user.id subplayer.addSongsFromPlaylist(data, null, userId, true) io.emit("ANSWER/SEND/FP_PLAY_PLAYLIST/OK") } else { io.emit("ANSWER/SEND/FP_PLAY_PLAYLIST", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/FP_PLAY_PLAYLIST", {"error":"TOKEN_NOT_FINDED"}) } }) socket.on("SEND/CREATE_PLAYLIST", async (data) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { var user = auth.getUser(token) var userId = user.user.id subplaylist.addPlaylist(userId, data) io.emit("DO_UPDATE_PLAYLIST") io.emit("ANSWER/SEND/CREATE_PLAYLIST/OK") } else { io.emit("ANSWER/SEND/CREATE_PLAYLIST", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/CREATE_PLAYLIST", {"error":"TOKEN_NOT_FINDED"}) } }) socket.on("SEND/DELETE_PLAYLIST", async (data) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { var user = auth.getUser(token) var userId = user.user.id subplaylist.removePlaylist(userId, data) io.emit("DO_UPDATE_PLAYLIST") io.emit("ANSWER/SEND/DELETE_PLAYLIST/OK") } else { io.emit("ANSWER/SEND/DELETE_PLAYLIST", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/DELETE_PLAYLIST", {"error":"TOKEN_NOT_FINDED"}) } }) socket.on("SEND/PLAY_PLAYLIST", async (data) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { var user = auth.getUser(token) var userId = user.user.id subplaylist.playPlaylist(userId, data) io.emit("DO_UPDATE_PLAYLIST") io.emit("ANSWER/SEND/PLAY_PLAYLIST/OK") } else { io.emit("ANSWER/SEND/PLAY_PLAYLIST", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/PLAY_PLAYLIST", {"error":"TOKEN_NOT_FINDED"}) } }) socket.on("SEND/ADD_SONG_TO_PLAYLIST", async (data, song) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { var user = auth.getUser(token) var userId = user.user.id subplaylist.addSong(userId, data, song) io.emit("DO_UPDATE_PLAYLIST") io.emit("ANSWER/SEND/ADD_SONG_TO_PLAYLIST/OK") } else { io.emit("ANSWER/SEND/ADD_SONG_TO_PLAYLIST", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/ADD_SONG_TO_PLAYLIST", {"error":"TOKEN_NOT_FINDED"}) } }) socket.on("SEND/DELETE_SONG_TO_PLAYLIST", async (data, song) => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { var user = auth.getUser(token) var userId = user.user.id subplaylist.removeSong(userId, data, song) io.emit("DO_UPDATE_PLAYLIST") io.emit("ANSWER/SEND/DELETE_SONG_TO_PLAYLIST/OK") } else { io.emit("ANSWER/SEND/DELETE_SONG_TO_PLAYLIST", {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/SEND/DELETE_SONG_TO_PLAYLIST", {"error":"TOKEN_NOT_FINDED"}) } }) }) } function GetRequest (io, socket, name, func) { socket.on("GET/" + name, () => { var cookies = socket.handshake.headers.cookie if(cookies) { cookies = cook.parse(cookies) var token = cookies.token if(auth.checkUser(token)) { const user = auth.getUser(token) wlog.log("Requête de " + user.user.username + " avec l'information \"" + name + "\"") func() } else { io.emit("ANSWER/GET/" + name, {"error":"USER_DONT_EXIST"}) } } else { io.emit("ANSWER/GET/" + name, {"error":"TOKEN_NOT_FINDED"}) } }) }