diff --git a/backend/api/controllers/presets.js b/backend/api/controllers/presets.js new file mode 100644 index 000000000..d25b797bd --- /dev/null +++ b/backend/api/controllers/presets.js @@ -0,0 +1,43 @@ +import PresetsDAO from "../../dao/presetsDAO"; +import { isTagPresetNameValid, validateConfig } from "../../handlers/validation"; + +class PresetsController { + static async addPreset(req, res, next) { + try { + const { name, config } = req.body; + const { uid } = req.decodedToken; + if(!isTagPresetNameValid(name)) next("Invalid preset name."); + validateConfig(config); + const createdInfo = await PresetsDAO.addPreset(uid, name, config); + return res.sendStatus(200).json(createdInfo); + } catch (e) { + return next(e); + } + } + + static async editPreset(req, res, next) { + try { + const { id, name, config } = req.body; + const { uid } = req.decodedToken; + if(!isTagPresetNameValid(name)) next("Invalid preset name."); + validateConfig(config); + await PresetsDAO.editPreset(uid, id, name, config); + return res.sendStatus(200); + } catch (e) { + return next(e); + } + } + + static async removePreset(req, res, next) { + try { + const { id } = req.body; + const { uid } = req.decodedToken; + await PresetsDAO.removePreset(uid, id); + return res.sendStatus(200); + } catch (e) { + return next(e); + } + } +} + +module.exports = PresetsController; diff --git a/backend/api/routes/presets.js b/backend/api/routes/presets.js new file mode 100644 index 000000000..a1cf091e9 --- /dev/null +++ b/backend/api/routes/presets.js @@ -0,0 +1,14 @@ +import { authenticateRequest } from "../../middlewares/auth"; +import PresetsController from "../controllers/presets"; + +const { Router } = require("express"); + +const router = Router(); + +router.post("/presets/add", authenticateRequest, PresetsController.addPreset); + +router.post("/presets/edit", authenticateRequest, PresetsController.editPreset); + +router.get("/presets/remove", authenticateRequest, PresetsController.removePreset); + +module.exports = router; diff --git a/backend/dao/presetsDAO.js b/backend/dao/presetsDAO.js new file mode 100644 index 000000000..5db884a93 --- /dev/null +++ b/backend/dao/presetsDAO.js @@ -0,0 +1,33 @@ +const MonkeyError = require("../handlers/error"); +const { mongoDB } = require("../init/mongodb"); +const uuid = require("uuid"); + +class PresetsDAO { + + static async addPreset(uid, name, config) { + const count = await mongoDB().collection('presets').find({uid}).count(); + if(count >= 10) throw new MonkeyError(409, "Too many presets"); + return await mongoDB() + .collection("presets") + .insertOne({ id: uuid.v4(), uid, name, config }); + } + + static async editPreset(uid, id, name, config) { + const preset = await mongoDB().collection('presets').findOne({uid, id}); + if(!preset) throw new MonkeyError(404, "Preset not found"); + return await mongoDB() + .collection("presets") + .updateOne({ uid, id }, { $set: { name , config} }); + } + + static async removePreset(uid, id) { + const preset = await mongoDB().collection('presets').findOne({uid, id}); + if(!preset) throw new MonkeyError(404, "Preset not found"); + return await mongoDB() + .collection("presets") + .remove({ uid, id }); + } + +} + +module.exports = PresetsDAO; diff --git a/backend/handlers/preset.js b/backend/handlers/preset.js index aaef00157..e69de29bb 100644 --- a/backend/handlers/preset.js +++ b/backend/handlers/preset.js @@ -1,157 +0,0 @@ - -app.post("/addPreset", authenticateToken, (req, res) => { - try { - if (!isTagPresetNameValid(req.body.obj.name)) { - return { resultCode: -1 }; - } else if (req.uid === undefined || req.body.obj === undefined) { - console.error(`error saving config for ${req.uid} - missing input`); - res.json({ - resultCode: -1, - message: "Missing input", - }); - } else { - let config = req.body.obj.config; - let errorMessage = ""; - let err = false; - Object.keys(config).forEach((key) => { - if (err) return; - if (!isConfigKeyValid(key)) { - err = true; - console.error(`${key} failed regex check`); - errorMessage = `${key} failed regex check`; - } - if (err) return; - if (key === "resultFilters") return; - if (key === "customBackground") return; - let val = config[key]; - if (Array.isArray(val)) { - val.forEach((valarr) => { - if (!isConfigKeyValid(valarr)) { - err = true; - console.error(`${key}: ${valarr} failed regex check`); - errorMessage = `${key}: ${valarr} failed regex check`; - } - }); - } else { - if (!isConfigKeyValid(val)) { - err = true; - console.error(`${key}: ${val} failed regex check`); - errorMessage = `${key}: ${val} failed regex check`; - } - } - }); - if (err) { - console.error( - `error adding preset for ${req.uid} - bad input - ${JSON.stringify( - req.body.obj - )}` - ); - res.json({ - resultCode: -1, - message: "Bad input. " + errorMessage, - }); - } - - User.findOne({ uid: req.uid }, (err, user) => { - if (user.presets.length >= 10) { - res.json({ - resultCode: -2, - message: "Preset limit", - }); - } else { - user.presets.push(req.body.obj); - user.save(); - } - }) - .then((updatedUser) => { - User.findOne({ uid: req.uid }, (err, user) => { - res.json({ - resultCode: 1, - message: "Saved", - id: user.presets[user.presets.length - 1]._id, - }); - }); - }) - .catch((e) => { - console.error( - `error adding preset to DB for ${req.uid} - ${e.message}` - ); - res.json({ - resultCode: -1, - message: e.message, - }); - }); - } - } catch (e) { - console.error(`error adding preset for ${req.uid} - ${e}`); - res.json({ - resultCode: -999, - message: e, - }); - } -}); - -app.post("/editPreset", authenticateToken, (req, res) => { - try { - if (!isTagPresetNameValid(req.body.presetName)) { - res.json({ resultCode: -1 }); - } else { - User.findOne({ uid: req.uid }, (err, user) => { - for (i = 0; i < user.presets.length; i++) { - if (user.presets[i]._id.toString() == req.body.presetid.toString()) { - user.presets[i] = { - config: req.body.config, - name: req.body.presetName, - }; - break; - } - } - user.save(); - }) - .then((e) => { - console.log( - `user ${req.uid} updated a preset: ${req.body.presetName}` - ); - res.json({ - resultCode: 1, - }); - }) - .catch((e) => { - console.error( - `error while updating preset for user ${req.uid}: ${e.message}` - ); - res.json({ resultCode: -999, message: e.message }); - }); - } - } catch (e) { - console.error(`error updating preset for ${req.uid} - ${e}`); - res.json({ resultCode: -999, message: e.message }); - } -}); - -app.post("/removePreset", authenticateToken, (req, res) => { - try { - User.findOne({ uid: req.uid }, (err, user) => { - for (i = 0; i < user.presets.length; i++) { - if (user.presets[i]._id.toString() == req.body.presetid.toString()) { - user.presets.splice(i, 1); - break; - } - } - user.save(); - }) - .then((e) => { - console.log(`user ${req.uid} deleted a preset`); - res.send({ resultCode: 1 }); - }) - .catch((e) => { - console.error( - `error deleting preset for user ${req.uid}: ${e.message}` - ); - res.send({ resultCode: -999 }); - }); - } catch (e) { - console.error(`error deleting preset for ${req.uid} - ${e}`); - res.send({ resultCode: -999 }); - } -}); diff --git a/backend/handlers/validation.js b/backend/handlers/validation.js index 6d0e55663..e28c0282c 100644 --- a/backend/handlers/validation.js +++ b/backend/handlers/validation.js @@ -1,3 +1,5 @@ +const MonkeyError = require("./error"); + module.exports = { isUsernameValid(name) { if (name === null || name === undefined || name === "") return false; @@ -67,5 +69,27 @@ module.exports = { if (name === null || name === undefined || name === "") return false; if (name.length > 30) return false; return /^[0-9a-zA-Z_.\-#+]+$/.test(name); + }, + validateConfig(config){ + Object.keys(config).forEach((key) => { + if (!isConfigKeyValid(key)) { + throw `InvalidConfig: ${key} failed regex check`; + } + if (key === "resultFilters") return; + if (key === "customBackground") return; + let val = config[key]; + if (Array.isArray(val)) { + val.forEach((valarr) => { + if (!isConfigKeyValid(valarr)) { + throw `InvalidConfig: ${key}:${valarr} failed regex check`; + } + }); + } else { + if (!isConfigKeyValid(val)) { + throw `InvalidConfig: ${key}:${val} failed regex check`; + } + } + }); + return true; } };