-// AJAX methods to get, create, update or delete a problem
-
let router = require("express").Router();
const access = require("../utils/access");
+const params = require("../config/parameters");
const ProblemModel = require("../models/Problem");
-const sanitizeHtml = require('sanitize-html');
-const MaxNbProblems = 20;
+const sanitizeHtml_pkg = require('sanitize-html');
-function sanitizeUserInput(fen, instructions, solution)
-{
- if (!fen.match(/^[a-zA-Z0-9, /-]*$/))
- return "Bad characters in FEN string";
- instructions = sanitizeHtml(instructions);
- solution = sanitizeHtml(solution);
- if (instructions.length == 0)
- return "Empty instructions";
- if (solution.length == 0)
- return "Empty solution";
- return {
- fen: fen,
- instructions: instructions,
- solution: solution
- };
+const allowedTags = [
+ 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol', 'li', 'b',
+ 'i', 'strong', 'em', 'strike', 'code', 'hr', 'br', 'div', 'table',
+ 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre'
+];
+function sanitizeHtml(text) {
+ return sanitizeHtml_pkg(text, { allowedTags: allowedTags });
}
-// Get one problem (TODO: vid unused, here for URL de-ambiguification)
-router.get("/problems/:vid([0-9]+)/:id([0-9]+)", access.ajax, (req,res) => {
- const pid = req.params["id"];
- ProblemModel.getOne(pid, (err,problem) => {
- if (!!err)
- return res.json(err);
- return res.json({problem: problem});
- });
-});
-
-// Fetch N previous or next problems
-router.get("/problems/:vid([0-9]+)", access.ajax, (req,res) => {
- const vid = req.params["vid"];
- const directionStr = (req.query.direction == "forward" ? ">" : "<");
- const lastDt = req.query.last_dt;
- const type = req.query.type;
- if (!lastDt.match(/[0-9]+/))
- return res.json({errmsg: "Bad timestamp"});
- if (!["others","mine"].includes(type))
- return res.json({errmsg: "Bad type"});
- ProblemModel.fetchN(vid, req.userId, type, directionStr, lastDt, MaxNbProblems,
- (err,problems) => {
- if (!!err)
- return res.json(err);
- return res.json({problems: problems});
- }
- );
+router.post("/problems", access.logged, access.ajax, (req,res) => {
+ if (ProblemModel.checkProblem(req.body.prob)) {
+ const problem = {
+ vid: req.body.prob.vid,
+ fen: req.body.prob.fen,
+ uid: req.userId,
+ instruction: sanitizeHtml(req.body.prob.instruction),
+ solution: sanitizeHtml(req.body.prob.solution),
+ };
+ ProblemModel.create(problem, (err, ret) => {
+ res.json(err || ret);
+ });
+ }
+ else
+ res.json({});
});
-// Upload a problem (sanitize inputs)
-router.post("/problems/:vid([0-9]+)", access.logged, access.ajax, (req,res) => {
- const vid = req.params["vid"];
- const s = sanitizeUserInput(
- req.body["fen"], req.body["instructions"], req.body["solution"]);
- if (typeof s === "string")
- return res.json({errmsg: s});
- ProblemModel.create(req.userId, vid, s.fen, s.instructions, s.solution,
- (err,pid) => {
- if (!!err)
- return res.json(err);
- res.json({id: pid["rowid"]});
- }
- );
+router.get("/problems", access.ajax, (req,res) => {
+ const probId = req.query["id"];
+ const cursor = req.query["cursor"];
+ if (!!probId && !!probId.match(/^[0-9]+$/)) {
+ ProblemModel.getOne(probId, (err, problem) => {
+ res.json(err || {problem: problem});
+ });
+ } else if (!!cursor && !!cursor.match(/^[0-9]+$/)) {
+ const onlyMine = (req.query["mode"] == "mine");
+ const uid = parseInt(req.query["uid"]);
+ ProblemModel.getNext(uid, onlyMine, cursor, (err, problems) => {
+ res.json(err || { problems: problems });
+ });
+ }
});
-// Update a problem (also sanitize inputs)
-router.put("/problems/:id([0-9]+)", access.logged, access.ajax, (req,res) => {
- const pid = req.params["id"]; //problem ID
- const s = sanitizeUserInput(
- req.body["fen"], req.body["instructions"], req.body["solution"]);
- if (typeof s === "string")
- return res.json({errmsg: s});
- ProblemModel.update(pid, req.userId, s.fen, s.instructions, s.solution,
- err => {
- if (!!err)
- return res.json(err);
- res.json({});
- }
- );
+router.put("/problems", access.logged, access.ajax, (req,res) => {
+ let obj = req.body.prob;
+ if (ProblemModel.checkProblem(obj)) {
+ obj.instruction = sanitizeHtml(obj.instruction);
+ obj.solution = sanitizeHtml(obj.solution);
+ ProblemModel.safeUpdate(obj, req.userId, params.devs);
+ }
+ res.json({});
});
-// Delete a problem
-router.delete("/problems/:id([0-9]+)", access.logged, access.ajax, (req,res) => {
- const pid = req.params["id"]; //problem ID
- ProblemModel.remove(pid, req.userId);
- res.json({});
+router.delete("/problems", access.logged, access.ajax, (req,res) => {
+ const pid = req.query.id;
+ if (pid.toString().match(/^[0-9]+$/))
+ ProblemModel.safeRemove(pid, req.userId, params.devs);
+ res.json({});
});
module.exports = router;