const express = require("express"); const app = express(); const config = require("./config") const fs = require("node:fs") const bcrypt = require("bcrypt") const bodyParser = require("body-parser") // Middleware app.use(express.json()); app.disable("x-powered-by") let ipLog = {} let adminCodes = {} let accounts = JSON.parse(fs.readFileSync("./db/useraccounts.json")) let apikeys = JSON.parse(fs.readFileSync("./db/apikeys.json")) let chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" app.use( bodyParser.urlencoded({extended:true}) ); // Route handler app.get("/v1/auth", (req, res) => { let logTime = getLogTime() console.log(logTime); // console.log(req.headers); // Simple ratelimit if(ipLog[req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip] !== undefined){ if(ipLog[req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip] > Date.now()){ ipLog[req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip] = Date.now() + config.ratelimit fs.writeFile("access.log", `${logTime} : ${req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip} HIT RATE LIMIT\n`, { flag: "a" }, callback => {}); return } } ipLog[req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip] = Date.now() + config.ratelimit let passed = true if(req.headers.username === undefined || req.headers.username.trim() === "" || req.headers.password === undefined || req.headers.password.trim() === "") passed = false if(accounts[req.headers.username] === undefined) passed = false if(!bcrypt.compareSync(req.headers.password, accounts[req.headers.username])) passed = false if(passed){ res.status(200).json(apikeys); } else{ res.status(401).send("You are not authorised"); } fs.writeFile("access.log", `${logTime} : ${req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip} API KEY REQUEST ${passed?"SUCCESS":"FAILED"}\n`, { flag: "a" }, callback => {}); }); app.get("/admin", (req, res) => { let logTime = getLogTime() fs.writeFile("access.log", `${logTime} : ${req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip} ACCESSED ADMIN PANEL\n`, { flag: "a" }, callback => {}); res.sendFile(__dirname + "/ui/index.html") }) app.get("/v1/admin-auth", (req,res) => { let logTime = getLogTime() let passed = false if(req.headers.password === undefined || req.headers.password.trim() === ""){ res.status(400).json({response:"Password field missing or empty", code:1}) return } if(bcrypt.compareSync(req.headers.password, accounts.admin)){ passed = true let code = "" for (let i = 0; i < 28; i++) { code += chars[Math.floor(Math.random() * chars.length)] } adminCodes[code] = Date.now() res.json({auth:code, code:0}) }else{ res.status(401).json({response:"Unauthorised", code:1}) } fs.writeFile("access.log", `${logTime} : ${req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip} LOGGED IN TO ADMIN PANEL ${passed?"SUCCESS":"FAILED"}\n`, { flag: "a" }, callback => {}); }) // API KEYS app.put("/v1/api-key", (req, res) => { req.body = JSON.parse(Object.keys(req.body)[0]) let logTime = getLogTime() let keypassed = checkKey(req.headers.key) if(!keypassed){ fs.writeFile("access.log", `${logTime} : ${req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip} TRIED TO ADD NEW API KEY : ${req.body.field} ${req.body.value}\n`, { flag: "a" }, callback => {}); return } if(req.body.value === undefined || req.body.value.trim() === "" || req.body.field === undefined || req.body.field.trim() === ""){ res.json({response:"please make sure to set the fields 'value' and 'field' in the request body", code:1}) return } apikeys[req.body.field] = req.body.value fs.writeFile("./db/apikeys.json", JSON.stringify(apikeys, null, 4), "utf8", c => {}) fs.writeFile("access.log", `${logTime} : ${req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip} ADDED A NEW API KEY : ${req.body.field} ${req.body.value}\n`, { flag: "a" }, callback => {}); res.json({response:"key added", code:0}) }) app.delete("/v1/api-key", (req, res) => { req.body = JSON.parse(Object.keys(req.body)[0]) let logTime = getLogTime() let keypassed = checkKey(req.headers.key) if(!keypassed){ fs.writeFile("access.log", `${logTime} : ${req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip} TRIED TO DELETE API KEY : ${req.body.field}\n`, { flag: "a" }, callback => {}); return } if(req.body.field === undefined || req.body.field.trim() === ""){ res.json({response:"please make sure to set the field 'field' in the request body", code:1}) return } delete apikeys[req.body.field] fs.writeFile("./db/apikeys.json", JSON.stringify(apikeys, null, 4), "utf8", c => {}) fs.writeFile("access.log", `${logTime} : ${req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip} DELETED API KEY : ${req.body.field}\n`, { flag: "a" }, callback => {}); res.json({response:"key removed", code:0}) }) app.get("/v1/api-key", (req, res) => { let logTime = getLogTime() let keypassed = checkKey(req.headers.key) if(!keypassed){ fs.writeFile("access.log", `${logTime} : ${req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip} TRIED TO GET API KEYS\n`, { flag: "a" }, callback => {}); return } res.json(apikeys) }) // ACCOUNT MANAGEMENT app.put("/v1/user", (req, res) => { req.body = JSON.parse(Object.keys(req.body)[0]) let logTime = getLogTime() let keypassed = checkKey(req.headers.key) if(!keypassed){ fs.writeFile("access.log", `${logTime} : ${req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip} TRIED TO ADD NEW USER : ${req.body.username}\n`, { flag: "a" }, callback => {}); return } if(req.body.username === undefined || req.body.username.trim() === "" || req.body.password === undefined || req.body.password.trim() === ""){ res.json({response:"please make sure to set the fields 'username' and 'password' in the request body", code:1}) return } accounts[req.body.username] = bcrypt.hashSync(req.body.password, 12) fs.writeFile("./db/useraccounts.json", JSON.stringify(accounts, null, 4), "utf8", c => {}) fs.writeFile("access.log", `${logTime} : ${req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip} ADDED A NEW USER : ${req.body.username}\n`, { flag: "a" }, callback => {}); res.json({response:"user added", code:0}) }) app.delete("/v1/user", (req, res) => { req.body = JSON.parse(Object.keys(req.body)[0]) let logTime = getLogTime() let keypassed = checkKey(req.headers.key) if(!keypassed){ fs.writeFile("access.log", `${logTime} : ${req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip} TRIED TO DELETE USER : ${req.body.username}\n`, { flag: "a" }, callback => {}); return } if(req.body.username === undefined || req.body.username.trim() === ""){ res.json({response:"please make sure to set the field 'field' in the request body", code:1}) return } delete accounts[req.body.username] fs.writeFile("./db/useraccounts.json", JSON.stringify(accounts, null, 4), "utf8", c => {}) fs.writeFile("access.log", `${logTime} : ${req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip} DELETED USER : ${req.body.field}\n`, { flag: "a" }, callback => {}); res.json({response:"user removed", code:0}) }) app.get("/v1/user", (req, res) => { let logTime = getLogTime() let keypassed = checkKey(req.headers.key) if(!keypassed){ fs.writeFile("access.log", `${logTime} : ${req.headers["x-forwarded-for"] != undefined ? req.headers["x-forwarded-for"] : req.ip} TRIED TO GET USERS\n`, { flag: "a" }, callback => {}); return } res.json(accounts) }) // Run server app.listen(config.port, () => { console.log( `------------------------------ Server listening on port ${config.port} -------------------------------`) }); function getLogTime(){ let curTime = new Date(); return `${curTime.getDate()<10?"0" + curTime.getDate(): curTime.getDate()}/${(curTime.getMonth()+1) < 10 ? "0" + (curTime.getMonth()+1) : curTime.getMonth()+1}/${curTime.getFullYear()} ${curTime.getHours() < 10 ? "0" + curTime.getHours() : curTime.getHours()}:${curTime.getMinutes() < 10 ? "0" + curTime.getMinutes() : curTime.getMinutes()}:${curTime.getSeconds() < 10 ? "0" + curTime.getSeconds() : curTime.getSeconds()}.${curTime.getMilliseconds() < 100 ? (curTime.getMilliseconds()+"").padStart(3,"0") : curTime.getMilliseconds()}` } function checkKey(key){ if(key.trim() === "" || key === undefined) return false if(adminCodes[key] === undefined) return false if(adminCodes[key] < Date.now() - config.keyDuration) return false return true } // Admin auth key cleanup setInterval(() => { Object.keys(adminCodes).forEach(el => { if(adminCodes[el] < Date.now() - config.keyDuration) delete adminCodes[el] }) }, 1000 * 60);