Ongoing work on challenges + games for correspondance play
[vchess.git] / server / routes / problems.js
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;