630 lines
18 KiB
JavaScript
630 lines
18 KiB
JavaScript
const { __glob, __web } = require("./global-variables");
|
|
const { LogType } = require("loguix");
|
|
const log = require("loguix");
|
|
const auth = require("./sub-auth");
|
|
const cook = require("cookie")
|
|
const wlog = new LogType("Web")
|
|
const subplayer = require('./sub-player');
|
|
|
|
const { List } = require("./sub-list")
|
|
const subplaylist = require("./sub-playlist")
|
|
const nodesfinder = require("./nodes-finder")
|
|
const { Server } = require("socket.io")
|
|
var fs = require("fs")
|
|
var path = require("path")
|
|
const { Metric } = require("webmetrik");
|
|
const markdownit = require("markdown-it")({
|
|
html: true,
|
|
linkify: true,
|
|
typographer: true
|
|
})
|
|
|
|
const Lyrics = require('song-lyrics-api');
|
|
const lyrics = new Lyrics();
|
|
|
|
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 cookieParser = require('cookie-parser');
|
|
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("/userspictures", express.static(__glob.PICTURE_DIR))
|
|
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;
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
* @param {Server} io
|
|
*/
|
|
function IOConnection(io) {
|
|
/**
|
|
* @type {LogType}
|
|
*/
|
|
const alog = log.getInstance("Authentification")
|
|
|
|
const usersOnline = new Array()
|
|
|
|
process.on("UPDATE_SELF", () => {
|
|
|
|
if(io) {
|
|
|
|
AlwaysRequest("UPDATE_SELF")
|
|
AlwaysRequest("ALL_CONNECTED_USER", usersOnline)
|
|
}
|
|
|
|
})
|
|
|
|
process.on("UPDATE_NODES", () => {
|
|
|
|
if(io) {
|
|
|
|
const data = nodesfinder.getNodesData()
|
|
AdminRequest("NODES", data)
|
|
}
|
|
|
|
})
|
|
|
|
process.on("PLAYLIST_REFRESH", () => {
|
|
if(io) {
|
|
AlwaysRequest("PLAYLIST_REFRESH", "OK")
|
|
}
|
|
})
|
|
|
|
|
|
process.on("MUSIC_UPDATE_STATE", () => {
|
|
if(io) {
|
|
const data = subplayer.updateMusicState()
|
|
AlwaysRequest("MUSIC_STATE", data)
|
|
|
|
}
|
|
})
|
|
|
|
io.on("connection", (socket) => {
|
|
|
|
var token = cook.parse(socket.handshake.headers.cookie).token
|
|
var user = auth.getUser(token)
|
|
if(user) {
|
|
|
|
if(user.admin == true) {
|
|
socket.join("admin")
|
|
|
|
}
|
|
|
|
const online_users_data = auth.getSimpleUser(token)
|
|
|
|
if(online_users_data) {
|
|
// Check if user is already connected and if not push it
|
|
if(!usersOnline.find(item => item.username == online_users_data.username)) {
|
|
usersOnline.push(online_users_data)
|
|
|
|
}
|
|
|
|
alog.log(online_users_data.username + " - Connexion du serveur avec le socket : " + socket.id + " - " + socket.handshake.address + " - " + socket.handshake.headers["user-agent"])
|
|
}
|
|
|
|
AlwaysRequest("ALL_CONNECTED_USER", usersOnline)
|
|
|
|
socket.on("disconnect", () => {
|
|
alog.log(user.user.username + " - Déconnexion du serveur - Socket : " + socket.id)
|
|
socket.leave("admin")
|
|
var index = usersOnline.indexOf(online_users_data)
|
|
if(index > -1) {
|
|
usersOnline.splice(index, 1)
|
|
}
|
|
AlwaysRequest("ALL_CONNECTED_USER", usersOnline)
|
|
})
|
|
|
|
GetRequest("USER_INFO", () => {
|
|
|
|
GetAnswer("USER_INFO", user)
|
|
alog.log("Envoi des informations Discord de '" + user.user.username + "' à '" + socket.id + "'" )
|
|
})
|
|
|
|
GetRequest("USER_LIST", () => {
|
|
|
|
GetAnswer("USER_LIST", auth.getSimpleUsers())
|
|
|
|
})
|
|
|
|
GetRequest('MUSIC_STATE', () => {
|
|
|
|
const data = subplayer.updateMusicState()
|
|
|
|
GetAnswer("MUSIC_STATE", "Bienvenue " + user.user.username + " ! " )
|
|
AlwaysRequest("MUSIC_STATE", data)
|
|
})
|
|
|
|
GetRequest("PLAYLIST", () => {
|
|
|
|
const playlistResult = subplaylist.getUser(user.user.id)
|
|
GetAnswer("PLAYLIST", playlistResult)
|
|
})
|
|
|
|
GetRequest("PAUSE", () => {
|
|
subplayer.pause()
|
|
GetAnswer("PAUSE", "OK")
|
|
})
|
|
|
|
GetRequest("BACKWARD", () => {
|
|
subplayer.previous()
|
|
GetAnswer("BACKWARD", "OK")
|
|
})
|
|
|
|
GetRequest("FORWARD", () => {
|
|
subplayer.skip()
|
|
GetAnswer("FORWARD", "OK")
|
|
})
|
|
|
|
GetRequest("LOOP", () => {
|
|
subplayer.loop()
|
|
GetAnswer("LOOP", "OK")
|
|
})
|
|
|
|
GetRequest("SHUFFLE", () => {
|
|
subplayer.changeShuffle()
|
|
GetAnswer("SHUFFLE", "OK")
|
|
})
|
|
|
|
GetRequest("DISCONNECT", () => {
|
|
subplayer.leave()
|
|
GetAnswer("DISCONNECT", "OK")
|
|
|
|
})
|
|
|
|
GetRequest("NODES", () => {
|
|
process.emit("UPDATE_NODES")
|
|
GetAnswer("NODES", "OK")
|
|
})
|
|
|
|
GetRequest("ALL_CONNECTED_USER", () => {
|
|
GetAnswer("ALL_CONNECTED_USER", "OK")
|
|
AlwaysRequest("ALL_CONNECTED_USER", usersOnline)
|
|
})
|
|
|
|
GetRequest("README", () => {
|
|
var content = markdownit.render(fs.readFileSync(__glob.README).toString())
|
|
GetAnswer("README", content)
|
|
|
|
})
|
|
|
|
GetRequest("OOBE_CHECK", () => {
|
|
GetAnswer("OOBE_CHECK", auth.getOOBE(user.user.id))
|
|
})
|
|
|
|
GetRequest("OOBE_VALID", () => {
|
|
auth.setOOBE(user.user.id)
|
|
GetAnswer("OOBE_VALID", "OK")
|
|
})
|
|
|
|
|
|
GetRequest("MOVEOUT", () => {
|
|
subplayer.moveOut(user.user.id)
|
|
GetAnswer("MOVEOUT", "OK")
|
|
})
|
|
|
|
PostRequest("SEEK", (data) => {
|
|
subplayer.seek(data)
|
|
PostAnswer("SEEK", "OK")
|
|
})
|
|
|
|
PostRequest("VOLUME", (data) => {
|
|
subplayer.setVol(data)
|
|
PostAnswer("VOLUME", "OK")
|
|
})
|
|
|
|
PostRequest("PLAY_QUEUE", (data) => {
|
|
var sublist = new List()
|
|
subplayer.addSong(sublist.playQueue(data), user.user.id, true)
|
|
PostAnswer("PLAY_QUEUE", "OK")
|
|
|
|
})
|
|
|
|
PostRequest("CHANGE_QUEUE", (data) => {
|
|
var sublist = new List()
|
|
sublist.changeQueue(data)
|
|
PostAnswer("CHANGE_QUEUE", "OK")
|
|
|
|
})
|
|
|
|
PostRequest("DELETE_QUEUE", (data) => {
|
|
var sublist = new List()
|
|
sublist.removeByIndex(data)
|
|
|
|
PostAnswer("DELETE_QUEUE", "OK")
|
|
|
|
})
|
|
|
|
PostRequest("DELETE_ALL_QUEUE", () => {
|
|
var sublist = new List()
|
|
sublist.removeAll()
|
|
|
|
PostAnswer("DELETE_QUEUE", "OK")
|
|
|
|
})
|
|
|
|
PostRequest("MOVE_QUEUE", (data) => {
|
|
var sublist = new List()
|
|
sublist.moveUp(data)
|
|
|
|
PostAnswer("MOVE_QUEUE", "OK")
|
|
|
|
})
|
|
|
|
PostRequest("MOVE_QUEUE_BY_ENTIRE", (data) => {
|
|
var sublist = new List()
|
|
sublist.replaceList(data)
|
|
|
|
PostAnswer("MOVE_QUEUE_BY_ENTIRE", "OK")
|
|
|
|
})
|
|
|
|
PostRequest("REPORT", (data) => {
|
|
|
|
data.username = user
|
|
subplayer.report(null, null, data)
|
|
PostAnswer("REPORT", "OK")
|
|
|
|
})
|
|
|
|
PostRequest("SEARCH", async (data) => {
|
|
const results = await subplayer.search(data)
|
|
PostAnswer("SEARCH", results)
|
|
})
|
|
|
|
PostRequest("ADD_SONG", async (data) => {
|
|
subplayer.addSong(data, user.user.id)
|
|
PostAnswer("ADD_SONG", "OK")
|
|
|
|
playStats(user.user.username)
|
|
})
|
|
|
|
PostRequest("ADD_SONG_NOW", async (data) => {
|
|
subplayer.addSong(data, user.user.id, true)
|
|
PostAnswer("ADD_SONG_NOW", "OK")
|
|
|
|
playStats(user.user.username)
|
|
})
|
|
|
|
PostRequest("FP_ADD_SONG", async (data) => {
|
|
subplayer.addSong(data, user.user.id, false, true)
|
|
PostAnswer("FP_ADD_SONG", "OK")
|
|
|
|
playStats(user.user.username)
|
|
})
|
|
|
|
PostRequest("FP_ADD_SONG_NOW", async (data) => {
|
|
subplayer.addSong(data, user.user.id, true, true)
|
|
PostAnswer("FP_ADD_SONG_NOW", "OK")
|
|
|
|
playStats(user.user.username)
|
|
})
|
|
|
|
PostRequest("PLAY_PLAYLIST", async (data) => {
|
|
subplaylist.playPlaylist(user.user.id, data)
|
|
PostAnswer("PLAY_PLAYLIST", "OK")
|
|
|
|
playStats(user.user.username)
|
|
})
|
|
|
|
PostRequest("PLAY_PLAYLIST_NOW", async (data) => {
|
|
subplaylist.playPlaylist(user.user.id, data, true)
|
|
PostAnswer("PLAY_PLAYLIST_NOW", "OK")
|
|
|
|
playStats(user.user.username)
|
|
})
|
|
|
|
|
|
PostRequest("CREATE_PLAYLIST", async (data) => {
|
|
subplaylist.addPlaylist(user.user.id, data)
|
|
socket.emit("DO_UPDATE_PLAYLIST")
|
|
PostAnswer("CREATE_PLAYLIST", "OK")
|
|
|
|
})
|
|
|
|
PostRequest("DELETE_PLAYLIST", async (data) => {
|
|
subplaylist.removePlaylist(user.user.id, data)
|
|
socket.emit("DO_UPDATE_PLAYLIST")
|
|
PostAnswer("DELETE_PLAYLIST", "OK")
|
|
})
|
|
|
|
PostRequest("SEND_PLAYLIST", async (data) => {
|
|
subplaylist.copyPlaylist(user.user.id, data.key, data.dest)
|
|
socket.emit("DO_UPDATE_PLAYLIST")
|
|
PostAnswer("SEND_PLAYLIST", "OK")
|
|
})
|
|
|
|
PostRequest("RENAME_PLAYLIST", async (data) => {
|
|
subplaylist.renamePlaylist(user.user.id, data.id, data.name)
|
|
socket.emit("DO_UPDATE_PLAYLIST")
|
|
PostAnswer("RENAME_PLAYLIST", "OK")
|
|
})
|
|
|
|
PostRequest("ADD_SONG_TO_PLAYLIST", async (data) => {
|
|
subplaylist.addSong(user.user.id, data.id, data.url)
|
|
socket.emit("DO_UPDATE_PLAYLIST")
|
|
PostAnswer("ADD_SONG_TO_PLAYLIST", "OK")
|
|
})
|
|
|
|
PostRequest("DELETE_SONG_TO_PLAYLIST", async (data) => {
|
|
subplaylist.removeSong(user.user.id, data.id, data.identifier)
|
|
socket.emit("DO_UPDATE_PLAYLIST")
|
|
PostAnswer("DELETE_SONG_TO_PLAYLIST", "OK")
|
|
})
|
|
|
|
|
|
PostRequest("FP_PLAY_PLAYLIST", async (data) => {
|
|
subplayer.addSongsFromPlaylist(data, user.user.id)
|
|
PostAnswer("FP_PLAY_PLAYLIST", "OK")
|
|
|
|
})
|
|
|
|
PostRequest("FP_PLAY_PLAYLIST_NOW", async (data) => {
|
|
subplayer.addSongsFromPlaylist(data, user.user.id, true)
|
|
PostAnswer("FP_PLAY_PLAYLIST", "OK")
|
|
|
|
})
|
|
|
|
PostRequest("LYRICS", async (data) => {
|
|
lyrics.getLyrics(data)
|
|
.then((response) => {
|
|
PostAnswer("LYRICS", response[0].lyrics)
|
|
})
|
|
.catch((error) => {
|
|
PostAnswer("LYRICS", null)
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if(user.admin == true) {
|
|
GetRequest("LOGS", () => {
|
|
const logs_data = new Array()
|
|
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()})
|
|
}
|
|
|
|
GetAnswer("LOGS", logs_data)
|
|
})
|
|
|
|
GetRequest("USERS", () => {
|
|
const users_data = auth.getUsers()
|
|
AdminRequest("USERS", users_data)
|
|
})
|
|
|
|
PostRequest("NODES/ADD", (data) => {
|
|
nodesfinder.addNodes(data)
|
|
PostAnswer("NODES/ADD", "OK")
|
|
process.emit("UPDATE_NODES")
|
|
})
|
|
|
|
PostRequest("NODES/DELETE", (data) => {
|
|
nodesfinder.deleteNode(data)
|
|
PostAnswer("NODES/DELETE", "OK")
|
|
process.emit("UPDATE_NODES")
|
|
})
|
|
|
|
PostRequest("NODES/RELOAD", (data) => {
|
|
nodesfinder.reloadNode(data)
|
|
PostAnswer("NODES/RELOAD", "OK")
|
|
process.emit("UPDATE_NODES")
|
|
})
|
|
|
|
|
|
PostRequest("USERS/ADMIN", (data) => {
|
|
auth.setAdmin(data)
|
|
PostAnswer("USERS/ADMIN", "OK")
|
|
const users_data = auth.getUsers()
|
|
AdminRequest("USERS", users_data)
|
|
})
|
|
|
|
PostRequest("USERS/BAN", (data) => {
|
|
auth.setBan(data)
|
|
PostAnswer("USERS/BAN", "OK")
|
|
const users_data = auth.getUsers()
|
|
AdminRequest("USERS", users_data)
|
|
})
|
|
|
|
PostRequest("USERS/DELETE", (data) => {
|
|
auth.removeUser(data)
|
|
PostAnswer("USERS/DELETE", "OK")
|
|
const users_data = auth.getUsers()
|
|
AdminRequest("USERS", users_data)
|
|
})
|
|
|
|
GetRequest("RESTART", () => {
|
|
const pm2 = require('pm2');
|
|
pm2.restart('Subsonics')
|
|
|
|
GetAnswer("RESTART", "OK")
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function GetRequest(GQname, GQcallback) {
|
|
socket.on("GET/" + GQname, () => {
|
|
|
|
wlog.log(user.user.username + " - Socket : " + socket.id + " - GET/" + GQname + " - [RECIEVED]")
|
|
GQcallback()
|
|
})
|
|
|
|
}
|
|
|
|
function GetAnswer(GRname, GRvalue) {
|
|
|
|
wlog.log(user.user.username + " - Socket : " + socket.id + " - GET/" + GRname + " - [ANSWERED]")
|
|
socket.emit("ANSWER/GET/" + GRname, GRvalue)
|
|
|
|
}
|
|
|
|
function PostRequest(GQname, GQcallback) {
|
|
socket.on("POST/" + GQname, (value) => {
|
|
wlog.log(user.user.username + " - Socket : " + socket.id + " - POST/" + GQname + " - [RECIEVED]")
|
|
GQcallback(value)
|
|
})
|
|
|
|
}
|
|
|
|
function PostAnswer(GRname, GRvalue) {
|
|
|
|
wlog.log(user.user.username + " - Socket : " + socket.id + " - POST/" + GRname + " - [ANSWERED]")
|
|
socket.emit("ANSWER/POST/" + GRname, GRvalue)
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
function AlwaysRequest(GRname, GRvalue) {
|
|
|
|
io.sockets.emit("ALWAYS/" + GRname, GRvalue)
|
|
|
|
}
|
|
|
|
|
|
function AdminRequest(GRname, GRvalue) {
|
|
|
|
io.to("admin").emit("ALWAYS/" + GRname, GRvalue)
|
|
|
|
}
|
|
|
|
|
|
|
|
function playStats(username) {
|
|
var userMusicPlayed = new Metric("userMusicPlayed_" + username, "Nombre de musiques jouées par l'utilisateur : " + username)
|
|
userMusicPlayed.setValue(userMusicPlayed.getValue() + 1)
|
|
|
|
}
|
|
|
|
}
|