diff --git a/backend/routes/backup.js b/backend/routes/backup.js index 9fb99ea..807530d 100644 --- a/backend/routes/backup.js +++ b/backend/routes/backup.js @@ -1,19 +1,19 @@ -const express = require('express'); -const { Pool } = require('pg'); -const fs = require('fs'); -const path = require('path'); -const { randomUUID } = require('crypto'); -const multer = require('multer'); +const express = require("express"); +const { Pool } = require("pg"); +const fs = require("fs"); +const path = require("path"); +const { randomUUID } = require("crypto"); +const multer = require("multer"); -const Logging = require('../classes/logging'); -const backup = require('../classes/backup'); -const triggertype = require('../logging/triggertype'); -const taskstate = require('../logging/taskstate'); -const taskName = require('../logging/taskName'); -const sanitizeFilename = require('../utils/sanitizer'); +const Logging = require("../classes/logging"); +const backup = require("../classes/backup"); +const triggertype = require("../logging/triggertype"); +const taskstate = require("../logging/taskstate"); +const taskName = require("../logging/taskName"); +const sanitizeFilename = require("../utils/sanitizer"); -const { sendUpdate } = require('../ws'); -const db = require('../db'); +const { sendUpdate } = require("../ws"); +const db = require("../db"); const router = express.Router(); @@ -22,14 +22,14 @@ const postgresUser = process.env.POSTGRES_USER; const postgresPassword = process.env.POSTGRES_PASSWORD; const postgresIp = process.env.POSTGRES_IP; const postgresPort = process.env.POSTGRES_PORT; -const postgresDatabase = process.env.POSTGRES_DB || 'jfstat'; -const backupfolder = 'backup-data'; +const postgresDatabase = process.env.POSTGRES_DB || "jfstat"; +const backupfolder = "backup-data"; // Restore function function readFile(path) { return new Promise((resolve, reject) => { - fs.readFile(path, 'utf8', (err, data) => { + fs.readFile(path, "utf8", (err, data) => { if (err) { reject(err); return; @@ -41,10 +41,10 @@ function readFile(path) { } async function restore(file, refLog) { - refLog.logData.push({ color: 'lawngreen', Message: 'Starting Restore' }); + refLog.logData.push({ color: "lawngreen", Message: "Starting Restore" }); refLog.logData.push({ - color: 'yellow', - Message: 'Restoring from Backup: ' + file, + color: "yellow", + Message: "Restoring from Backup: " + file, }); const pool = new Pool({ user: postgresUser, @@ -63,7 +63,7 @@ async function restore(file, refLog) { jsonData = await readFile(backupPath); } catch (err) { refLog.logData.push({ - color: 'red', + color: "red", key: tableName, Message: `Failed to read backup file`, }); @@ -73,7 +73,7 @@ async function restore(file, refLog) { // console.log(jsonData); if (!jsonData) { - console.log('No Data'); + console.log("No Data"); return; } @@ -81,38 +81,38 @@ async function restore(file, refLog) { const data = Object.values(table)[0]; const tableName = Object.keys(table)[0]; refLog.logData.push({ - color: 'dodgerblue', + color: "dodgerblue", key: tableName, Message: `Restoring ${tableName}`, }); for (let index in data) { - const keysWithQuotes = Object.keys(data[index]).map(key => `"${key}"`); - const keyString = keysWithQuotes.join(', '); + const keysWithQuotes = Object.keys(data[index]).map((key) => `"${key}"`); + const keyString = keysWithQuotes.join(", "); - const valuesWithQuotes = Object.values(data[index]).map(col => { + const valuesWithQuotes = Object.values(data[index]).map((col) => { if (col === null) { - return 'NULL'; - } else if (typeof col === 'string') { + return "NULL"; + } else if (typeof col === "string") { return `'${col.replace(/'/g, "''")}'`; - } else if (typeof col === 'object') { + } else if (typeof col === "object") { return `'${JSON.stringify(col).replace(/'/g, "''")}'`; } else { return `'${col}'`; } }); - const valueString = valuesWithQuotes.join(', '); + const valueString = valuesWithQuotes.join(", "); const query = `INSERT INTO ${tableName} (${keyString}) VALUES(${valueString}) ON CONFLICT DO NOTHING`; const { rows } = await pool.query(query); } } await pool.end(); - refLog.logData.push({ color: 'lawngreen', Message: 'Restore Complete' }); + refLog.logData.push({ color: "lawngreen", Message: "Restore Complete" }); } // Route handler for backup endpoint -router.get('/beginBackup', async (req, res) => { +router.get("/beginBackup", async (req, res) => { try { const last_execution = await db .query( @@ -122,11 +122,11 @@ router.get('/beginBackup', async (req, res) => { ORDER BY "TimeRun" DESC LIMIT 1` ) - .then(res => res.rows); + .then((res) => res.rows); if (last_execution.length !== 0) { if (last_execution[0].Result === taskstate.RUNNING) { - sendUpdate('TaskError', 'Error: Backup is already running'); + sendUpdate("TaskError", "Error: Backup is already running"); res.send(); return; } @@ -137,50 +137,44 @@ router.get('/beginBackup', async (req, res) => { await Logging.insertLog(uuid, triggertype.Manual, taskName.backup); await backup(refLog); Logging.updateLog(uuid, refLog.logData, taskstate.SUCCESS); - res.send('Backup completed successfully'); - sendUpdate('TaskComplete', { message: triggertype + ' Backup Completed' }); + res.send("Backup completed successfully"); + sendUpdate("TaskComplete", { message: triggertype + " Backup Completed" }); } catch (error) { console.error(error); - res.status(500).send('Backup failed'); + res.status(500).send("Backup failed"); } }); -router.get('/restore/:filename', async (req, res) => { +router.get("/restore/:filename", async (req, res) => { try { const uuid = randomUUID(); let refLog = { logData: [], uuid: uuid }; Logging.insertLog(uuid, triggertype.Manual, taskName.restore); const filename = sanitizeFilename(req.params.filename); - const filePath = path.join( - process.cwd(), - __dirname, - '..', - backupfolder, - filename - ); + const filePath = path.join(__dirname, "..", backupfolder, filename); await restore(filePath, refLog); Logging.updateLog(uuid, refLog.logData, taskstate.SUCCESS); - res.send('Restore completed successfully'); - sendUpdate('TaskComplete', { message: 'Restore completed successfully' }); + res.send("Restore completed successfully"); + sendUpdate("TaskComplete", { message: "Restore completed successfully" }); } catch (error) { console.error(error); - res.status(500).send('Restore failed'); + res.status(500).send("Restore failed"); } }); -router.get('/files', (req, res) => { +router.get("/files", (req, res) => { try { - const directoryPath = path.join(__dirname, '..', backupfolder); + const directoryPath = path.join(__dirname, "..", backupfolder); fs.readdir(directoryPath, (err, files) => { if (err) { - res.status(500).send('Unable to read directory'); + res.status(500).send("Unable to read directory"); } else { const fileData = files - .filter(file => file.endsWith('.json')) - .map(file => { + .filter((file) => file.endsWith(".json")) + .map((file) => { const filePath = path.join(directoryPath, file); const stats = fs.statSync(filePath); return { @@ -198,34 +192,22 @@ router.get('/files', (req, res) => { }); //download backup file -router.get('/files/:filename', (req, res) => { +router.get("/files/:filename", (req, res) => { const filename = sanitizeFilename(req.params.filename); - const filePath = path.join( - process.cwd(), - __dirname, - '..', - backupfolder, - filename - ); + const filePath = path.join(__dirname, "..", backupfolder, filename); res.download(filePath); }); //delete backup -router.delete('/files/:filename', (req, res) => { +router.delete("/files/:filename", (req, res) => { try { const filename = sanitizeFilename(req.params.filename); - const filePath = path.join( - process.cwd(), - __dirname, - '..', - backupfolder, - filename - ); + const filePath = path.join(__dirname, "..", backupfolder, filename); - fs.unlink(filePath, err => { + fs.unlink(filePath, (err) => { if (err) { console.error(err); - res.status(500).send('An error occurred while deleting the file.'); + res.status(500).send("An error occurred while deleting the file."); return; } @@ -233,13 +215,13 @@ router.delete('/files/:filename', (req, res) => { res.status(200).send(`${filePath} has been deleted.`); }); } catch (error) { - res.status(500).send('An error occurred while deleting the file.'); + res.status(500).send("An error occurred while deleting the file."); } }); const storage = multer.diskStorage({ destination: function (req, file, cb) { - cb(null, path.join(__dirname, '..', backupfolder)); // Set the destination folder for uploaded files + cb(null, path.join(__dirname, "..", backupfolder)); // Set the destination folder for uploaded files }, filename: function (req, file, cb) { cb(null, file.originalname); // Set the file name @@ -248,7 +230,7 @@ const storage = multer.diskStorage({ const upload = multer({ storage: storage }); -router.post('/upload', upload.single('file'), (req, res) => { +router.post("/upload", upload.single("file"), (req, res) => { // Handle the uploaded file here res.json({ fileName: req.file.originalname, @@ -258,7 +240,7 @@ router.post('/upload', upload.single('file'), (req, res) => { // Handle other routes router.use((req, res) => { - res.status(404).send({ error: 'Not Found' }); + res.status(404).send({ error: "Not Found" }); }); module.exports = router; diff --git a/backend/utils/sanitizer.js b/backend/utils/sanitizer.js index 169beaf..06a622a 100644 --- a/backend/utils/sanitizer.js +++ b/backend/utils/sanitizer.js @@ -1,7 +1,7 @@ -const sanitizer = require("sanitize-filename"); +const sanitizeFilename = require("sanitize-filename"); -const sanitizeFilename = (filename) => { - return sanitizer(filename); +const sanitizeFile = (filename) => { + return sanitizeFilename(filename); }; -module.export = { sanitizeFilename }; +module.exports = sanitizeFile;