| 1 | // AJAX methods to get, create, update or delete a problem |
| 2 | |
| 3 | let router = require("express").Router(); |
| 4 | const access = require("../utils/access"); |
| 5 | const ProblemModel = require("../models/Problem"); |
| 6 | const sanitizeHtml = require('sanitize-html'); |
| 7 | const MaxNbProblems = 20; |
| 8 | |
| 9 | function sanitizeUserInput(fen, instructions, solution) |
| 10 | { |
| 11 | if (!fen.match(/^[a-zA-Z0-9, /-]*$/)) |
| 12 | return "Bad characters in FEN string"; |
| 13 | instructions = sanitizeHtml(instructions); |
| 14 | solution = sanitizeHtml(solution); |
| 15 | if (instructions.length == 0) |
| 16 | return "Empty instructions"; |
| 17 | if (solution.length == 0) |
| 18 | return "Empty solution"; |
| 19 | return { |
| 20 | fen: fen, |
| 21 | instructions: instructions, |
| 22 | solution: solution |
| 23 | }; |
| 24 | } |
| 25 | |
| 26 | // Get one problem (TODO: vid unused, here for URL de-ambiguification) |
| 27 | router.get("/problems/:vid([0-9]+)/:id([0-9]+)", access.ajax, (req,res) => { |
| 28 | const pid = req.params["id"]; |
| 29 | ProblemModel.getOne(pid, (err,problem) => { |
| 30 | if (!!err) |
| 31 | return res.json(err); |
| 32 | return res.json({problem: problem}); |
| 33 | }); |
| 34 | }); |
| 35 | |
| 36 | // Fetch N previous or next problems |
| 37 | router.get("/problems/:vid([0-9]+)", access.ajax, (req,res) => { |
| 38 | const vid = req.params["vid"]; |
| 39 | const directionStr = (req.query.direction == "forward" ? ">" : "<"); |
| 40 | const lastDt = req.query.last_dt; |
| 41 | const type = req.query.type; |
| 42 | if (!lastDt.match(/[0-9]+/)) |
| 43 | return res.json({errmsg: "Bad timestamp"}); |
| 44 | if (!["others","mine"].includes(type)) |
| 45 | return res.json({errmsg: "Bad type"}); |
| 46 | ProblemModel.fetchN(vid, req.userId, type, directionStr, lastDt, MaxNbProblems, |
| 47 | (err,problems) => { |
| 48 | if (!!err) |
| 49 | return res.json(err); |
| 50 | return res.json({problems: problems}); |
| 51 | } |
| 52 | ); |
| 53 | }); |
| 54 | |
| 55 | // Upload a problem (sanitize inputs) |
| 56 | router.post("/problems/:vid([0-9]+)", access.logged, access.ajax, (req,res) => { |
| 57 | const vid = req.params["vid"]; |
| 58 | const s = sanitizeUserInput( |
| 59 | req.body["fen"], req.body["instructions"], req.body["solution"]); |
| 60 | if (typeof s === "string") |
| 61 | return res.json({errmsg: s}); |
| 62 | ProblemModel.create(req.userId, vid, s.fen, s.instructions, s.solution, |
| 63 | (err,pid) => { |
| 64 | if (!!err) |
| 65 | return res.json(err); |
| 66 | res.json({id: pid["rowid"]}); |
| 67 | } |
| 68 | ); |
| 69 | }); |
| 70 | |
| 71 | // Update a problem (also sanitize inputs) |
| 72 | router.put("/problems/:id([0-9]+)", access.logged, access.ajax, (req,res) => { |
| 73 | const pid = req.params["id"]; //problem ID |
| 74 | const s = sanitizeUserInput( |
| 75 | req.body["fen"], req.body["instructions"], req.body["solution"]); |
| 76 | if (typeof s === "string") |
| 77 | return res.json({errmsg: s}); |
| 78 | ProblemModel.update(pid, req.userId, s.fen, s.instructions, s.solution, |
| 79 | err => { |
| 80 | if (!!err) |
| 81 | return res.json(err); |
| 82 | res.json({}); |
| 83 | } |
| 84 | ); |
| 85 | }); |
| 86 | |
| 87 | // Delete a problem |
| 88 | router.delete("/problems/:id([0-9]+)", access.logged, access.ajax, (req,res) => { |
| 89 | const pid = req.params["id"]; //problem ID |
| 90 | ProblemModel.remove(pid, req.userId); |
| 91 | res.json({}); |
| 92 | }); |
| 93 | |
| 94 | module.exports = router; |