Files
Discord-Bot-Builder/server.js
HerpieDerpie@example.com 3443ed8d3c changed up the styling a bit
2024-01-11 11:56:18 +01:00

393 lines
11 KiB
JavaScript
Executable File

/*
Importing all the required packages
*/
const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');
const bcrypt = require('bcrypt');
const fs = require('fs-extra');
const path = require('path');
const archiver = require('archiver');
const mysql = require('mysql');
const {db} = require("./config.json")
/*
Creating some handy constants
*/
const documentRoot = `${__dirname}/httpdocs`
const webserverPort = 3000
/**
* Creates a MySQL connection.
* @returns {Object} MySQL connection object
*/
const createConnection = () => {
return mysql.createConnection({
host: db.location,
user: db.username,
password: db.password,
database: db.db_name,
connectTimeout: 20000,
});
};
/**
* Setting up the express webserver
*
*/
const app = express()
app.use(express.static("styles"))
app.use(express.static("scripts"))
app.use(express.static("src"))
app.use(session({secret: 'secret',resave: true,saveUninitialized: true}));
app.use( bodyParser.json() );
app.use(express.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.urlencoded({extended: true}));
/*
Setting up the login system
*/
const requireLogin = (req, res, next) => {
if (!req.session.userId) {
res.redirect('/');
} else {
next();
}
};
/*
Setting up all the website pages
*/
app.get("/", (req, res) => {
res.sendFile(`${documentRoot}/login.html`);
})
app.get("/dashboard",requireLogin, (req, res) => {
res.sendFile(`${documentRoot}/dashboard.html`);
});
app.get("/projects/:projectId/", requireLogin, (req, res)=>{
const con = createConnection();
const sql = "SELECT MAX(project_id) as maxProjectID FROM Projects";
con.query(sql, (err, results) => {
if (err) throw err;
con.end();
const maxProjectID = results[0].maxProjectID;
if (parseInt(maxProjectID) < parseInt(req.params.projectId)) return res.redirect("/dashboard");
else {
res.sendFile(`${documentRoot}/project.html`);
}
});
})
/*
Setting up all the website posting pages.
*/
app.post("/", (req, res) => {
/**
* Login Validation
*/
const { username, password } = req.body;
const con = createConnection();
const sql = "SELECT * FROM Users WHERE username = ?";
con.query(sql, [username], (err, results) => {
if (err) {
console.error('Error executing login query:', err);
res.status(500).send('Internal Server Error');
return;
}
con.end();
if (results.length > 0) {
bcrypt.compare(password, results[0].password, (bcryptErr, isMatch) => {
if (bcryptErr) {
console.error('Error comparing passwords:', bcryptErr);
res.status(500).send('Internal Server Error');
return;
}
if (isMatch) {
req.session.userId = results[0].user_id;
res.redirect('/dashboard');
} else {
res.send('Invalid username or password');
}
});
} else {
res.send('Invalid username or password');
}
});
});
/*
Commands Grid
*/
app.get("/fetch-commands", requireLogin, (req, res)=> {
const projectId = req.query.id;
const userId = req.session.userId;
const con = createConnection();
const ownerCheck = "SELECT project_id FROM Projects WHERE project_id=? AND project_owner=?"
con.query(ownerCheck, [projectId, userId], (err, results)=>{
if (err) throw err;
if (results.length != 1)return res.json({});
const sql = "SELECT command_id, command_name, command_description, command_response FROM Commands WHERE project_id = ?";
con.query(sql, [projectId], (err, results) => {
if (err) throw err;
con.end();
let result = [];
for (let i = 0; i < results.length; i++){
result.push({"name": results[i]["command_name"], "description": results[i]["command_description"], "id": results[i]["command_id"], "response": results[i]["command_response"]});
}
res.json(result);
});
})
});
app.get("/fetch-project-data", requireLogin, (req, res)=>{
const projectId = req.query.id;
const userId = req.session.userId;
let response = {};
const con = createConnection();
const sql = "SELECT * FROM Projects WHERE project_id=? AND project_owner=?";
con.query(sql, [projectId, userId], (err, results)=>{
if (err) throw err;
if (results.length != 1) return res.json(response);
con.end();
response["projectName"] = results[0]["project_name"];
response["projectId"] = projectId;
res.json(response)
})
});
app.post("/delete-command", requireLogin, (req, res)=> {
const projectId = req.query.projectId;
const commandId = req.query.commandId;
const userId = req.session.userId;
const con = createConnection();
const ownerCheck = "SELECT project_id FROM Projects WHERE project_id=? AND project_owner=?"
con.query(ownerCheck, [projectId, userId], (err, results)=>{
if (err) throw err;
if (results.length != 1)return res.json({});
const sql = "DELETE FROM Commands WHERE command_id=?";
con.query(sql, [commandId], (err, results)=>{
if (err) throw err;
con.end();
res.status(200).send("true");
})
})
})
app.post("/create-command", requireLogin, (req, res)=> {
let name = req.body.name;
let description = req.body.description;
let response = req.body.response;
name = name.replace(" ", "-");
let projectId = req.body.projectId;
let owner = req.session.userId;
const con = createConnection();
const ownerCheck = "SELECT project_id FROM Projects WHERE project_id=? AND project_owner=?"
con.query(ownerCheck, [projectId, owner], (err, results)=>{
if (err) throw err;
if (results.length != 1)return;
const sql = "INSERT INTO Commands (project_id, command_name, command_description, command_response) VALUES (?,?,?,?)";
con.query(sql, [projectId, name, description, response], (err, results)=>{
if (err) throw err;
con.end();
res.status(200).send("true");
})
})
})
/*
Projects Grid
*/
app.get("/fetch-bots", requireLogin, (req, res)=> {
const sql = "SELECT project_name, project_id FROM Projects WHERE project_owner = ?";
const con = createConnection();
con.query(sql, [req.session.userId], (err, results) => {
if (err) throw err;
con.end();
let result = [];
for (let i = 0; i < results.length; i++){
result.push({"name": results[i]["project_name"], "id": results[i]["project_id"]});
}
res.json(result);
});
});
app.post("/create-bot", requireLogin, (req, res)=> {
let name = req.body.name;
let token = req.body.token;
let clientId = req.body.clientId;
let owner = req.session.userId;
if (name.length > 20)return;
let bot = {"name": name}
const con = createConnection();
var sql = "INSERT INTO Projects (project_name, project_owner, bot_token, bot_id) VALUES (?, ?, ?, ?)";
con.query(sql, [name, owner, token, clientId], function (err, result) {
if (err) throw err;
con.end();
});
res.send('true');
})
app.post("/rename-project", requireLogin, (req,res)=>{
let name = req.body.name;
let projectId = req.body.id;
let userId = req.session.userId;
const con = createConnection();
const ownerCheck = "SELECT project_id FROM Projects WHERE project_id=? AND project_owner=?"
con.query(ownerCheck, [projectId, userId], (err, results)=>{
if (err) throw err;
if (results.length != 1)return;
const sql = "UPDATE Projects SET project_name=? WHERE project_id=?";
con.query(sql, [name, projectId], (err, results)=>{
if (err) throw err;
con.end();
res.status(200).send("true");
})
})
})
app.post("/export", requireLogin, (req, res) => {
const projectId = req.query.id;
const userId = req.session.userId;
const con = createConnection();
const ownerCheck = "SELECT * FROM Projects WHERE project_id=? AND project_owner=?";
con.query(ownerCheck, [projectId, userId], (err, results) => {
if (err) throw err;
if (results.length !== 1) return res.json({});
const data = results[0];
const botToken = data.bot_token;
const clientId = data.bot_id;
con.query("SELECT command_id, command_name, command_description, command_response FROM Commands WHERE project_id = ?", [projectId], (err, result) => {
if (err) throw err;
con.end();
const commands = result.map(command => {
return {
name: command.command_name,
description: command.command_description,
response: command.command_response
};
});
const jsonContent = {
token: botToken,
clientId: clientId,
commands: commands
};
const botBuildsPath = `./bot_builds/${projectId}`;
// Create the directory if it doesn't exist
fs.ensureDirSync(botBuildsPath);
// Copy everything from "./example_bot" to "./botBuilds/{id}/"
const exampleBotPath = "./example_bot";
fs.copySync(exampleBotPath, botBuildsPath);
// Write JSON to a file in the new directory
const configFile = path.join(botBuildsPath, "config.json");
fs.writeFileSync(configFile, JSON.stringify(jsonContent, null, 2));
// Create a zip file
const outputZipPath = path.join(__dirname, `./bot_builds/${projectId}.zip`);
const outputZipStream = fs.createWriteStream(outputZipPath);
const archive = archiver('zip', {
zlib: { level: 9 }
});
outputZipStream.on('close', () => {
res.download(outputZipPath, (err) => {
if (err) throw err;
fs.removeSync(outputZipPath);
fs.removeSync(botBuildsPath);
});
});
archive.on('error', (err) => {
throw err;
});
archive.pipe(outputZipStream);
archive.directory(botBuildsPath, false);
archive.finalize();
});
});
});
/*
Starting up the server.
*/
app.listen(webserverPort, () => {
console.log(`Bot Builder Online at http://localhost:${webserverPort}/`)
})