2019-09-28 21:43:25 -05:00
|
|
|
import * as express from "express";
|
|
|
|
import * as njk from "nunjucks";
|
|
|
|
import * as bodyparser from "body-parser";
|
2019-10-05 14:34:57 -05:00
|
|
|
import * as fs from "fs";
|
2019-10-17 16:01:35 -05:00
|
|
|
import * as socketio from "socket.io";
|
|
|
|
import * as http from "http";
|
2019-10-20 16:09:28 -05:00
|
|
|
import * as dirty from "dirty";
|
2019-09-28 21:43:25 -05:00
|
|
|
import * as api from "./api";
|
|
|
|
import * as db from "./database";
|
2019-11-05 17:22:52 -06:00
|
|
|
import * as irc from "./irc";
|
2019-09-28 21:43:25 -05:00
|
|
|
|
2019-10-17 16:01:35 -05:00
|
|
|
const app = express();
|
|
|
|
const server = http.createServer(app);
|
|
|
|
const io = socketio(server);
|
2019-10-20 16:09:28 -05:00
|
|
|
const store = dirty();
|
2019-09-28 21:43:25 -05:00
|
|
|
var njkconf;
|
|
|
|
|
2019-11-05 17:22:52 -06:00
|
|
|
async function init(satyr: any, port: number, ircconf: any){
|
2019-09-28 21:43:25 -05:00
|
|
|
njk.configure('templates', {
|
|
|
|
autoescape: true,
|
|
|
|
express : app,
|
2019-11-05 16:30:15 -06:00
|
|
|
watch: false
|
2019-09-28 21:43:25 -05:00
|
|
|
});
|
|
|
|
njkconf ={
|
|
|
|
sitename: satyr.name,
|
|
|
|
domain: satyr.domain,
|
|
|
|
email: satyr.email,
|
2019-10-05 14:34:57 -05:00
|
|
|
rootredirect: satyr.rootredirect,
|
|
|
|
version: satyr.version
|
2019-09-28 21:43:25 -05:00
|
|
|
};
|
|
|
|
app.use(bodyparser.json());
|
|
|
|
app.use(bodyparser.urlencoded({ extended: true }));
|
2019-10-05 14:34:57 -05:00
|
|
|
//site handlers
|
2019-09-28 21:43:25 -05:00
|
|
|
app.get('/', (req, res) => {
|
2019-10-05 14:34:57 -05:00
|
|
|
res.redirect(njkconf.rootredirect);
|
2019-09-28 21:43:25 -05:00
|
|
|
});
|
|
|
|
app.get('/about', (req, res) => {
|
|
|
|
res.render('about.njk', njkconf);
|
|
|
|
});
|
2019-10-05 14:34:57 -05:00
|
|
|
app.get('/users', (req, res) => {
|
|
|
|
db.query('select username from users').then((result) => {
|
|
|
|
njkconf.list = result;
|
|
|
|
res.render('list.njk', njkconf);
|
|
|
|
njkconf.list = '';
|
|
|
|
});
|
|
|
|
});
|
|
|
|
app.get('/users/live', (req, res) => {
|
|
|
|
db.query('select username,title from user_meta where live=1;').then((result) => {
|
|
|
|
njkconf.list = result;
|
|
|
|
res.render('live.njk', njkconf);
|
|
|
|
njkconf.list = '';
|
|
|
|
});
|
|
|
|
});
|
2019-09-28 21:43:25 -05:00
|
|
|
app.get('/users/*', (req, res) => {
|
2019-11-10 08:27:00 -06:00
|
|
|
db.query('select username,title,about from user_meta where username='+db.raw.escape(req.url.split('/')[2].toLowerCase())).then((result) => {
|
2019-10-05 14:34:57 -05:00
|
|
|
if(result[0]){
|
2019-11-10 08:27:00 -06:00
|
|
|
njkconf.user = result[0].username;
|
2019-10-05 14:34:57 -05:00
|
|
|
njkconf.streamtitle = result[0].title;
|
|
|
|
njkconf.about = result[0].about;
|
|
|
|
res.render('user.njk', njkconf);
|
|
|
|
}
|
|
|
|
else res.render('404.njk', njkconf);
|
|
|
|
});
|
2019-09-28 21:43:25 -05:00
|
|
|
});
|
2019-10-05 14:34:57 -05:00
|
|
|
app.get('/vods/*', (req, res) => {
|
|
|
|
njkconf.user = req.url.split('/')[2].toLowerCase();
|
|
|
|
db.query('select username from user_meta where username='+db.raw.escape(njkconf.user)).then((result) => {
|
|
|
|
if(result[0]){
|
|
|
|
fs.readdir('./site/live/'+njkconf.user, {withFileTypes: true} , (err, files) => {
|
|
|
|
if(files) njkconf.list = files.filter(fn => fn.name.endsWith('.mp4'));
|
|
|
|
else njkconf.list = [];
|
|
|
|
res.render('vods.njk', njkconf);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else res.render('404.njk', njkconf);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
app.get('/register', (req, res) => {
|
2019-09-28 21:43:25 -05:00
|
|
|
res.render('registration.njk', njkconf);
|
|
|
|
});
|
2019-10-05 14:34:57 -05:00
|
|
|
app.get('/profile', (req, res) => {
|
|
|
|
res.render('profile.njk', njkconf);
|
|
|
|
});
|
|
|
|
app.get('/changepwd', (req, res) => {
|
|
|
|
res.render('changepwd.njk', njkconf);
|
|
|
|
});
|
|
|
|
app.get('/changesk', (req, res) => {
|
|
|
|
res.render('changesk.njk', njkconf);
|
|
|
|
});
|
2019-10-20 16:09:28 -05:00
|
|
|
app.get('/chat', (req, res) => {
|
|
|
|
res.render('chat.html', njkconf);
|
|
|
|
});
|
2019-11-05 16:30:15 -06:00
|
|
|
app.get('/help', (req, res) => {
|
|
|
|
res.render('help.njk', njkconf);
|
|
|
|
});
|
2019-10-05 14:34:57 -05:00
|
|
|
//api handlers
|
2019-09-28 21:43:25 -05:00
|
|
|
app.post('/api/register', (req, res) => {
|
2019-10-05 14:34:57 -05:00
|
|
|
api.register(req.body.username, req.body.password, req.body.confirm).then( (result) => {
|
|
|
|
res.send(result);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
app.post('/api/user', (req, res) => {
|
|
|
|
api.update(req.body.username, req.body.password, req.body.title, req.body.bio, req.body.record).then((result) => {
|
|
|
|
res.send(result);
|
2019-09-28 21:43:25 -05:00
|
|
|
});
|
|
|
|
});
|
2019-10-05 14:34:57 -05:00
|
|
|
app.post('/api/user/password', (req, res) => {
|
|
|
|
api.changepwd(req.body.username, req.body.password, req.body.newpassword).then((result) => {
|
|
|
|
res.send(result);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
app.post('/api/user/streamkey', (req, res) => {
|
|
|
|
api.changesk(req.body.username, req.body.password).then((result) => {
|
|
|
|
res.send(result);
|
|
|
|
})
|
|
|
|
});
|
|
|
|
//static files if nothing else matches first
|
2019-09-28 21:43:25 -05:00
|
|
|
app.use(express.static('site'));
|
2019-10-05 14:34:57 -05:00
|
|
|
//404 Handler
|
|
|
|
app.use(function (req, res, next) {
|
|
|
|
res.status(404).render('404.njk', njkconf);
|
|
|
|
});
|
2019-11-05 17:22:52 -06:00
|
|
|
//irc peering
|
|
|
|
if(ircconf.enable){
|
|
|
|
await irc.connect({
|
|
|
|
port: ircconf.port,
|
|
|
|
sid: ircconf.sid,
|
|
|
|
pass: ircconf.pass,
|
|
|
|
server: ircconf.server,
|
|
|
|
vhost: ircconf.vhost
|
|
|
|
});
|
|
|
|
irc.events.on('message', (nick, channel, msg) => {
|
|
|
|
io.to(channel).emit('MSG', {nick: nick, msg: msg});
|
|
|
|
});
|
|
|
|
}
|
2019-10-17 16:01:35 -05:00
|
|
|
//socket.io chat logic
|
2019-10-20 16:09:28 -05:00
|
|
|
io.on('connection', async (socket) => {
|
|
|
|
socket.nick = await newNick(socket);
|
2019-11-05 17:22:52 -06:00
|
|
|
if(ircconf.enable) irc.registerUser(socket.nick);
|
2019-10-20 16:09:28 -05:00
|
|
|
socket.on('JOINROOM', async (data) => {
|
|
|
|
let t: any = await db.query('select username from users where username='+db.raw.escape(data));
|
|
|
|
if(t[0]){
|
|
|
|
socket.join(data);
|
|
|
|
io.to(data).emit('JOINED', {nick: socket.nick});
|
2019-11-05 17:22:52 -06:00
|
|
|
if(ircconf.enable) irc.join(socket.nick, data);
|
2019-10-20 16:09:28 -05:00
|
|
|
}
|
|
|
|
else socket.emit('ALERT', 'Room does not exist');
|
|
|
|
});
|
|
|
|
socket.on('LEAVEROOM', (data) => {
|
|
|
|
socket.leave(data);
|
2019-11-05 17:22:52 -06:00
|
|
|
if(ircconf.enable) irc.part(socket.nick, data);
|
2019-10-20 16:09:28 -05:00
|
|
|
io.to(data).emit('LEFT', {nick: socket.nick});
|
|
|
|
});
|
|
|
|
socket.on('disconnecting', (reason) => {
|
|
|
|
let rooms = Object.keys(socket.rooms);
|
|
|
|
for(let i=1;i<rooms.length;i++){
|
2019-11-05 17:22:52 -06:00
|
|
|
if(ircconf.enable) irc.part(socket.nick, rooms[i]);
|
2019-10-20 16:09:28 -05:00
|
|
|
io.to(rooms[i]).emit('ALERT', socket.nick+' disconnected');
|
|
|
|
}
|
2019-11-05 17:48:12 -06:00
|
|
|
if(ircconf.enable) irc.unregisterUser(socket.nick);
|
2019-10-20 16:09:28 -05:00
|
|
|
store.rm(socket.nick);
|
|
|
|
});
|
|
|
|
socket.on('NICK', async (data) => {
|
|
|
|
data.nick = data.nick.replace(' ','');
|
|
|
|
if(store.get(data.nick)){
|
|
|
|
socket.emit('ALERT', 'Nickname is already in use');
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
let user = await db.query('select username from users where username='+db.raw.escape(data.nick));
|
|
|
|
if(user[0]){
|
|
|
|
if(!data.password){
|
|
|
|
socket.emit('ALERT','Incorrect username or password');
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if(await db.validatePassword(data.nick, data.password)){
|
|
|
|
chgNick(socket, data.nick);
|
|
|
|
}
|
|
|
|
else socket.emit('ALERT','Incorrect username or password');
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
chgNick(socket, data.nick);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
socket.on('MSG', (data) => {
|
2019-11-10 09:07:23 -06:00
|
|
|
if(data.msg === "") return;
|
2019-10-20 16:09:28 -05:00
|
|
|
io.to(data.room).emit('MSG', {nick: socket.nick, msg: data.msg});
|
2019-11-05 17:22:52 -06:00
|
|
|
if(ircconf.enable) irc.send(socket.nick, data.room, data.msg);
|
2019-10-20 16:09:28 -05:00
|
|
|
});
|
|
|
|
socket.on('KICK', (data) => {
|
|
|
|
if(socket.nick === data.room){
|
|
|
|
//find client with data.nick
|
|
|
|
let id: string = store.get(data.nick);
|
|
|
|
if(id){
|
|
|
|
let target = io.sockets.connected[id];
|
|
|
|
io.in(data.room).emit('ALERT', data.nick+' has been kicked.');
|
|
|
|
target.disconnect(true);
|
|
|
|
}
|
|
|
|
else socket.emit('ALERT', 'No such user found.');
|
|
|
|
}
|
|
|
|
else socket.emit('ALERT', 'Not authorized to do that.');
|
|
|
|
});
|
2019-10-17 16:01:35 -05:00
|
|
|
});
|
|
|
|
server.listen(port);
|
2019-09-28 21:43:25 -05:00
|
|
|
}
|
|
|
|
|
2019-10-20 16:09:28 -05:00
|
|
|
async function newNick(socket) {
|
|
|
|
let n: string = 'Guest'+Math.floor(Math.random() * Math.floor(100));
|
|
|
|
if(store.get(n)) return newNick(socket);
|
|
|
|
else {
|
|
|
|
store.set(n, socket.id);
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
async function chgNick(socket, nick) {
|
|
|
|
let rooms = Object.keys(socket.rooms);
|
|
|
|
for(let i=1;i<rooms.length;i++){
|
|
|
|
io.to(rooms[i]).emit('ALERT', socket.nick+' is now known as '+nick);
|
|
|
|
}
|
|
|
|
store.rm(socket.nick);
|
|
|
|
store.set(nick, socket.id);
|
|
|
|
socket.nick = nick;
|
|
|
|
}
|
|
|
|
|
2019-09-28 21:43:25 -05:00
|
|
|
export { init };
|