From ba96584300a8eefef663aa56e3f9884439f58c10 Mon Sep 17 00:00:00 2001 From: Jonas Kappa Date: Fri, 2 Jan 2026 18:01:02 +0100 Subject: [PATCH] Added Editing of Questions --- src/cdn.js | 30 ++++++++++++++- src/games.js | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/util.js | 24 ++++++++++++ 3 files changed, 153 insertions(+), 2 deletions(-) diff --git a/src/cdn.js b/src/cdn.js index 3c6bd4d..757507e 100644 --- a/src/cdn.js +++ b/src/cdn.js @@ -30,6 +30,7 @@ export function initCdn(app, db) { app.get('/cdn/:userid/:resid', fetchFile); app.put('/cdn/:userid/:resid', renameFile); app.delete('/cdn/:userid/:resid', deleteFile); + app.get('/ressource', fetchRessource); app.post('/directory', fetchDirectory); app.put('/directory', addDirectory); app.delete('/directory', deleteDirectory); @@ -85,6 +86,33 @@ function uploadFile(req, res, next) { } } +/** + * + * @param {import('express').Request} req + * @param {import('express').Response} res + */ +async function fetchRessource(req, res) { + if (req.query.id === undefined || req.query.id.length <= 0) { + res.sendStatus(400); + return; + } + + const id = new ObjectId(req.query.id); + + ressources + .findOne({ + _id: id, + user: req.user._id, + }) + .then((ressource) => { + if (ressource) { + res.status(200).send(ressource); + } else { + res.sendStatus(404); + } + }); +} + /** * * @param {import('express').Request} req @@ -93,7 +121,7 @@ function uploadFile(req, res, next) { async function fetchFile(req, res) { let ressource = await ressources.findOne({ user: new ObjectId(req.params.userid), - filename: req.params.resid, + _id: new ObjectId(req.params.resid), }); if (ressource) { diff --git a/src/games.js b/src/games.js index c3a207d..c8d3732 100644 --- a/src/games.js +++ b/src/games.js @@ -1,5 +1,5 @@ import { Collection, Db, ObjectId } from 'mongodb'; -import { checkStringProp } from './util.js'; +import { checkNumberProp, checkObjectProp, checkStringProp } from './util.js'; /** * @type {Collection} @@ -95,6 +95,7 @@ export function initGames(app, db) { app.post('/category/rename', renameCategory); app.get('/question', fetchQuestion); + app.post('/question', updateQuestion); } /** @@ -592,6 +593,104 @@ async function deleteWallRoute(req, res) { }); } +/** + * + * @param {import('express').Request} req + * @param {import('express').Response} res + */ +async function updateQuestion(req, res) { + if ( + !checkStringProp(req.body, '_id') && + !checkStringProp(req.body, 'owner') && + !checkStringProp(req.body, 'type') && + !checkNumberProp(req.body, 'points') && + !checkObjectProp(req.body, 'data') + ) { + res.sendStatus(400); + return; + } + + if (req.body.owner !== req.user._id.toString()) { + res.sendStatus(403); + return; + } + /** + * @type {string} + */ + let _id = req.body._id; + + let replacement; + + if ( + req.body.type === QuestionType.SIMPLE || + req.body.type === QuestionType.MULTIPLE_CHOICE + ) { + replacement = toNormalQuestion(req.body); + } else if ( + req.body.type === QuestionType.IMAGE || + req.body.type === QuestionType.IMAGE_MULTIPLE_CHOICE + ) { + replacement = toImageQuestion(req.body); + } else if ( + req.body.type === QuestionType.AUDIO || + req.body.type === QuestionType.AUDIO_MULTIPLE_CHOICE + ) { + replacement = toAudioQuestion(req.body); + } + + cQuestions + .replaceOne( + { + _id: new ObjectId(_id), + owner: req.user._id, + }, + replacement, + ) + .then((result) => { + if (result.modifiedCount === 1) { + res.sendStatus(200); + } else res.sendStatus(500); + }) + .catch((err) => { + console.error(err); + res.sendStatus(500); + }); +} + +function toNormalQuestion(body) { + return { + ...body, + _id: new ObjectId(body._id), + owner: new ObjectId(body.owner), + }; +} + +function toImageQuestion(body) { + return { + ...body, + _id: new ObjectId(body._id), + owner: new ObjectId(body.owner), + data: { + ...body.data, + image: + body.data.image === null ? null : new ObjectId(body.data.image), + }, + }; +} + +function toAudioQuestion(body) { + return { + ...body, + _id: new ObjectId(body._id), + owner: new ObjectId(body.owner), + data: { + ...body.data, + audio: + body.data.audio === null ? null : new ObjectId(body.data.audio), + }, + }; +} + /** * * @param {ObjectId} _id diff --git a/src/util.js b/src/util.js index e551e82..9ad1cb0 100644 --- a/src/util.js +++ b/src/util.js @@ -11,3 +11,27 @@ export function checkStringProp(body, property) { } else return false; } else return false; } + +/** + * + * @param {any} body + * @param {string} property + */ +export function checkNumberProp(body, property) { + if (body === undefined) return false; + if (Object.hasOwn(body, property)) { + return typeof body[property] === 'number'; + } else return false; +} + +/** + * + * @param {any} body + * @param {string} property + */ +export function checkObjectProp(body, property) { + if (body === undefined) return false; + if (Object.hasOwn(body, property)) { + return typeof body[property] === 'object'; + } else return false; +}