|
|
@ -28,17 +28,14 @@ exports.WebServer = class {
|
|
|
|
this.setReferenceObjects(referenceObjects);
|
|
|
|
this.setReferenceObjects(referenceObjects);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* TODO: Encrypt the password on client side.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
configureExpress() {
|
|
|
|
configureExpress() {
|
|
|
|
this.app.set('view engine', 'pug');
|
|
|
|
this.app.set('view engine', 'pug');
|
|
|
|
this.app.set('trust proxy', 1);
|
|
|
|
this.app.set('trust proxy', 1);
|
|
|
|
this.app.set('views', './web/http/');
|
|
|
|
this.app.set('views', './web/http/');
|
|
|
|
|
|
|
|
|
|
|
|
if (this.app.get('env') === 'devlopment') {
|
|
|
|
if (this.app.get('env') === 'devlopment')
|
|
|
|
this.app.use(require('cors')());
|
|
|
|
this.app.use(require('cors')());
|
|
|
|
}
|
|
|
|
|
|
|
|
this.app.use(require('cors')());
|
|
|
|
this.app.use(require('cors')());
|
|
|
|
this.app.use(session({
|
|
|
|
this.app.use(session({
|
|
|
|
secret: config.webservice.sessionSecret,
|
|
|
|
secret: config.webservice.sessionSecret,
|
|
|
@ -52,11 +49,11 @@ exports.WebServer = class {
|
|
|
|
|
|
|
|
|
|
|
|
this.app.use(compression({
|
|
|
|
this.app.use(compression({
|
|
|
|
filter: (req, res) => {
|
|
|
|
filter: (req, res) => {
|
|
|
|
if (req.headers['x-no-compression']) {
|
|
|
|
if (req.headers['x-no-compression'])
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
else
|
|
|
|
return compression.filter(req, res);
|
|
|
|
return compression.filter(req, res);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
this.app.use('/graphql', graphqlHTTP({
|
|
|
|
this.app.use('/graphql', graphqlHTTP({
|
|
|
@ -67,22 +64,11 @@ exports.WebServer = class {
|
|
|
|
this.app.use(compileSass({
|
|
|
|
this.app.use(compileSass({
|
|
|
|
root: './web/http/'
|
|
|
|
root: './web/http/'
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
this.app.get('/', (req, res, next) => {
|
|
|
|
|
|
|
|
if (req.session.user) {
|
|
|
|
|
|
|
|
next();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
res.render('login');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}, (req, res) => {
|
|
|
|
|
|
|
|
res.render('index');
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
this.app.use('/scripts', express.static('./web/http/scripts'));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.app.post('/', (req, res) => {
|
|
|
|
this.app.post('/', (req, res) => {
|
|
|
|
if (!req.body.username || !req.body.password) {
|
|
|
|
if (!req.body.username || !req.body.password)
|
|
|
|
res.render('login', {msg: 'Please enter username and password.'});
|
|
|
|
res.render('login', {msg: 'Please enter username and password.'});
|
|
|
|
} else {
|
|
|
|
else
|
|
|
|
this.maindb.get('SELECT * FROM users WHERE username = ? AND password = ?', [req.body.username, sha512(req.body.password)], (err, user) => {
|
|
|
|
this.maindb.get('SELECT * FROM users WHERE username = ? AND password = ?', [req.body.username, req.body.password], (err, user) => {
|
|
|
|
if (err || !user) {
|
|
|
|
if (err || !user) {
|
|
|
|
if (err)
|
|
|
|
if (err)
|
|
|
|
logger.warn(err.message);
|
|
|
|
logger.warn(err.message);
|
|
|
@ -93,7 +79,15 @@ exports.WebServer = class {
|
|
|
|
res.render('index');
|
|
|
|
res.render('index');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
this.app.use('/scripts', express.static('./web/http/scripts'));
|
|
|
|
|
|
|
|
this.app.use((req, res, next) => {
|
|
|
|
|
|
|
|
if (req.session.user)
|
|
|
|
|
|
|
|
next();
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
res.render('login');
|
|
|
|
|
|
|
|
}, (req, res) => {
|
|
|
|
|
|
|
|
res.render('index');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -160,33 +154,6 @@ exports.WebServer = class {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
authenticateByToken(req, res, next) {
|
|
|
|
|
|
|
|
if (req.headers.authorization
|
|
|
|
|
|
|
|
&& req.headers.authorization.split(' ')[0] === 'Bearer') {
|
|
|
|
|
|
|
|
let bearer = req.headers.authorization.split(' ')[1];
|
|
|
|
|
|
|
|
this.maindb.get('SELECT * FROM users WHERE token = ?', [bearer], (err, user) => {
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
|
|
|
|
logger.warn(err.message);
|
|
|
|
|
|
|
|
logger.debug('Unauthorized access');
|
|
|
|
|
|
|
|
res.status(401);
|
|
|
|
|
|
|
|
res.end('Unauthorized Access');
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (!user) {
|
|
|
|
|
|
|
|
res.status(401);
|
|
|
|
|
|
|
|
res.end('Unauthorized Access');
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
req.user = user;
|
|
|
|
|
|
|
|
next();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
logger.debug('Unauthorized access');
|
|
|
|
|
|
|
|
res.status(401);
|
|
|
|
|
|
|
|
res.end('Unauthorized Access');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Setting all objects that web can query
|
|
|
|
* Setting all objects that web can query
|
|
|
|
* @param objects
|
|
|
|
* @param objects
|
|
|
@ -200,19 +167,19 @@ exports.WebServer = class {
|
|
|
|
token VARCHAR(255) UNIQUE NOT NULL,
|
|
|
|
token VARCHAR(255) UNIQUE NOT NULL,
|
|
|
|
scope INTEGER NOT NULL DEFAULT 0
|
|
|
|
scope INTEGER NOT NULL DEFAULT 0
|
|
|
|
)`, (err) => {
|
|
|
|
)`, (err) => {
|
|
|
|
if (err) {
|
|
|
|
if (err)
|
|
|
|
logger.error(err.message);
|
|
|
|
logger.error(err.message);
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
this.root = {
|
|
|
|
this.root = {
|
|
|
|
client: {
|
|
|
|
client: {
|
|
|
|
guilds: (args) => {
|
|
|
|
guilds: (args) => {
|
|
|
|
let dcGuilds = objects.client.guilds.values();
|
|
|
|
let dcGuilds = objects.client.guilds.values();
|
|
|
|
if (args.id) {
|
|
|
|
if (args.id)
|
|
|
|
return [Array.from(dcGuilds)
|
|
|
|
return [Array.from(dcGuilds)
|
|
|
|
.map((x) => new Guild(x, objects.getGuildHandler(x)))
|
|
|
|
.map((x) => new Guild(x, objects.getGuildHandler(x)))
|
|
|
|
.find(x => (x.id === args.id))];
|
|
|
|
.find(x => (x.id === args.id))];
|
|
|
|
} else {
|
|
|
|
else
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
return Array.from(dcGuilds)
|
|
|
|
return Array.from(dcGuilds)
|
|
|
|
.slice(args.offset, args.offset + args.first)
|
|
|
|
.slice(args.offset, args.offset + args.first)
|
|
|
@ -221,7 +188,7 @@ exports.WebServer = class {
|
|
|
|
logger.error(err.stack);
|
|
|
|
logger.error(err.stack);
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
guildCount: () => {
|
|
|
|
guildCount: () => {
|
|
|
|
return Array.from(objects.client.guilds.values()).length;
|
|
|
|
return Array.from(objects.client.guilds.values()).length;
|
|
|
@ -242,14 +209,14 @@ exports.WebServer = class {
|
|
|
|
let dcGuilds = Array.from(objects.client.guilds.values());
|
|
|
|
let dcGuilds = Array.from(objects.client.guilds.values());
|
|
|
|
return dcGuilds.filter((x) => {
|
|
|
|
return dcGuilds.filter((x) => {
|
|
|
|
let gh = objects.guildHandlers[x.id];
|
|
|
|
let gh = objects.guildHandlers[x.id];
|
|
|
|
if (gh) {
|
|
|
|
if (gh)
|
|
|
|
if (gh.dj)
|
|
|
|
if (gh.dj)
|
|
|
|
return gh.dj.playing;
|
|
|
|
return gh.dj.playing;
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
}).length;
|
|
|
|
}).length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
@ -270,18 +237,18 @@ exports.WebServer = class {
|
|
|
|
logEntries.push(new LogEntry(JSON.parse(line)));
|
|
|
|
logEntries.push(new LogEntry(JSON.parse(line)));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
lineReader.on('close', () => {
|
|
|
|
lineReader.on('close', () => {
|
|
|
|
if (args.level) {
|
|
|
|
if (args.level)
|
|
|
|
logEntries = logEntries
|
|
|
|
logEntries = logEntries
|
|
|
|
.filter(x => (utils.logLevels[x.level] >= utils.logLevels[args.level]));
|
|
|
|
.filter(x => (utils.logLevels[x.level] >= utils.logLevels[args.level]));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args.id) {
|
|
|
|
if (args.id)
|
|
|
|
logEntries = [logEntries.find(x => (x.id === args.id))];
|
|
|
|
logEntries = [logEntries.find(x => (x.id === args.id))];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args.first) {
|
|
|
|
if (args.first)
|
|
|
|
logEntries = logEntries.slice(args.offset, args.offset + args.first);
|
|
|
|
logEntries = logEntries.slice(args.offset, args.offset + args.first);
|
|
|
|
} else {
|
|
|
|
else
|
|
|
|
logEntries = logEntries.slice(logEntries.length - args.last);
|
|
|
|
logEntries = logEntries.slice(logEntries.length - args.last);
|
|
|
|
}
|
|
|
|
|
|
|
|
resolve(logEntries);
|
|
|
|
resolve(logEntries);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
@ -291,7 +258,7 @@ exports.WebServer = class {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* generating an unique id
|
|
|
|
* generating an id
|
|
|
|
* @param valArr
|
|
|
|
* @param valArr
|
|
|
|
* @returns {*}
|
|
|
|
* @returns {*}
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -305,6 +272,11 @@ function generateID(valArr) {
|
|
|
|
return md5(b64);
|
|
|
|
return md5(b64);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* generating an unique id
|
|
|
|
|
|
|
|
* @param input
|
|
|
|
|
|
|
|
* @returns {*}
|
|
|
|
|
|
|
|
*/
|
|
|
|
function generateUUID(input) {
|
|
|
|
function generateUUID(input) {
|
|
|
|
return generateID([input, (new Date()).getMilliseconds()]) + Date.now();
|
|
|
|
return generateID([input, (new Date()).getMilliseconds()]) + Date.now();
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -327,11 +299,11 @@ class DJ {
|
|
|
|
thumbnail: utils.YouTube.getVideoThumbnailUrlFromUrl(x.url)
|
|
|
|
thumbnail: utils.YouTube.getVideoThumbnailUrlFromUrl(x.url)
|
|
|
|
};
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
if (args.id) {
|
|
|
|
if (args.id)
|
|
|
|
return [queue.find(x => (x.id === args.id))];
|
|
|
|
return [queue.find(x => (x.id === args.id))];
|
|
|
|
} else {
|
|
|
|
else
|
|
|
|
return queue.slice(args.offset, args.offset + args.first);
|
|
|
|
return queue.slice(args.offset, args.offset + args.first);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
get playing() {
|
|
|
|
get playing() {
|
|
|
@ -377,6 +349,9 @@ class DJ {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Used for graphql access to the discord.js Guild and lib/guilding/GuildHandler
|
|
|
|
|
|
|
|
*/
|
|
|
|
class Guild {
|
|
|
|
class Guild {
|
|
|
|
constructor(discordGuild, guildHandler) {
|
|
|
|
constructor(discordGuild, guildHandler) {
|
|
|
|
this.id = generateID(['Guild', discordGuild.id]);
|
|
|
|
this.id = generateID(['Guild', discordGuild.id]);
|
|
|
@ -405,14 +380,14 @@ class Guild {
|
|
|
|
logger.error(err.message);
|
|
|
|
logger.error(err.message);
|
|
|
|
resolve(null);
|
|
|
|
resolve(null);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
for (let row of rows) {
|
|
|
|
for (let row of rows)
|
|
|
|
saved.push({
|
|
|
|
saved.push({
|
|
|
|
id: generateID(['Media', row.url]),
|
|
|
|
id: generateID(['Media', row.url]),
|
|
|
|
name: row.name,
|
|
|
|
name: row.name,
|
|
|
|
url: row.url,
|
|
|
|
url: row.url,
|
|
|
|
thumbnail: utils.YouTube.getVideoThumbnailUrlFromUrl(row.url)
|
|
|
|
thumbnail: utils.YouTube.getVideoThumbnailUrlFromUrl(row.url)
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
resolve(saved);
|
|
|
|
resolve(saved);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
@ -425,7 +400,7 @@ class Guild {
|
|
|
|
saved(args) {
|
|
|
|
saved(args) {
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
this.querySaved().then((result) => {
|
|
|
|
this.querySaved().then((result) => {
|
|
|
|
if (result) {
|
|
|
|
if (result)
|
|
|
|
if (args.id) {
|
|
|
|
if (args.id) {
|
|
|
|
resolve([result.find(x => (x.id === args.id))]);
|
|
|
|
resolve([result.find(x => (x.id === args.id))]);
|
|
|
|
} else if (args.name) {
|
|
|
|
} else if (args.name) {
|
|
|
@ -433,31 +408,34 @@ class Guild {
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
resolve(result.slice(args.offset, args.offset + args.first));
|
|
|
|
resolve(result.slice(args.offset, args.offset + args.first));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
else
|
|
|
|
resolve(null);
|
|
|
|
resolve(null);
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
roles(args) {
|
|
|
|
roles(args) {
|
|
|
|
if (args.id) {
|
|
|
|
if (args.id)
|
|
|
|
return [this.prRoles.find(x => (x.id === args.id))];
|
|
|
|
return [this.prRoles.find(x => (x.id === args.id))];
|
|
|
|
} else {
|
|
|
|
else
|
|
|
|
return this.prRoles.slice(args.offset, args.offset + args.first);
|
|
|
|
return this.prRoles.slice(args.offset, args.offset + args.first);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
members(args) {
|
|
|
|
members(args) {
|
|
|
|
if (args.id) {
|
|
|
|
if (args.id)
|
|
|
|
return [this.prMembers.find(x => (x.id === args.id))];
|
|
|
|
return [this.prMembers.find(x => (x.id === args.id))];
|
|
|
|
} else {
|
|
|
|
else
|
|
|
|
return this.prMembers.slice(args.offset, args.offset + args.first);
|
|
|
|
return this.prMembers.slice(args.offset, args.offset + args.first);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Used for graphql access to the discord.js Role
|
|
|
|
|
|
|
|
*/
|
|
|
|
class Role {
|
|
|
|
class Role {
|
|
|
|
constructor(discordRole) {
|
|
|
|
constructor(discordRole) {
|
|
|
|
this.id = generateID(['Role', discordRole.id]);
|
|
|
|
this.id = generateID(['Role', discordRole.id]);
|
|
|
@ -469,14 +447,17 @@ class Role {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
members(args) {
|
|
|
|
members(args) {
|
|
|
|
if (args.id) {
|
|
|
|
if (args.id)
|
|
|
|
return [this.prMembers.find(x => (x.id === args.id))];
|
|
|
|
return [this.prMembers.find(x => (x.id === args.id))];
|
|
|
|
} else {
|
|
|
|
else
|
|
|
|
return this.prMembers.slice(args.offset, args.offset + args.first);
|
|
|
|
return this.prMembers.slice(args.offset, args.offset + args.first);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Used for graphql access to the discord.js GuildMember
|
|
|
|
|
|
|
|
*/
|
|
|
|
class GuildMember {
|
|
|
|
class GuildMember {
|
|
|
|
constructor(discordGuildMember) {
|
|
|
|
constructor(discordGuildMember) {
|
|
|
|
this.id = generateID(['GuildMember', discordGuildMember.id]);
|
|
|
|
this.id = generateID(['GuildMember', discordGuildMember.id]);
|
|
|
@ -489,14 +470,17 @@ class GuildMember {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
roles(args) {
|
|
|
|
roles(args) {
|
|
|
|
if (args.id) {
|
|
|
|
if (args.id)
|
|
|
|
return [this.prRoles.find(x => (x.id === args.id))];
|
|
|
|
return [this.prRoles.find(x => (x.id === args.id))];
|
|
|
|
} else {
|
|
|
|
else
|
|
|
|
return this.prRoles.slice(args.offset, args.offset + args.first);
|
|
|
|
return this.prRoles.slice(args.offset, args.offset + args.first);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Used for graphql access to the discord.js User
|
|
|
|
|
|
|
|
*/
|
|
|
|
class User {
|
|
|
|
class User {
|
|
|
|
constructor(discordUser) {
|
|
|
|
constructor(discordUser) {
|
|
|
|
this.id = generateID(['User', discordUser.id]);
|
|
|
|
this.id = generateID(['User', discordUser.id]);
|
|
|
@ -513,6 +497,9 @@ class User {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Used for graphql access to log entries
|
|
|
|
|
|
|
|
*/
|
|
|
|
class LogEntry {
|
|
|
|
class LogEntry {
|
|
|
|
constructor(entry) {
|
|
|
|
constructor(entry) {
|
|
|
|
this.id = generateID(['LogEntry', entry.level, entry.timestamp]);
|
|
|
|
this.id = generateID(['LogEntry', entry.level, entry.timestamp]);
|