Save current state (unmerged, broken, not working...)
[vchess.git] / routes / problems.js
index 62a2da1..b94aa60 100644 (file)
@@ -1,58 +1,67 @@
+// AJAX methods to get, create, update or delete a problem
+
 let router = require("express").Router();
 let router = require("express").Router();
-const sqlite3 = require('sqlite3');
-const DbPath = __dirname.replace("/routes", "/db/vchess.sqlite");
-const db = new sqlite3.Database(DbPath);
+const access = require("../utils/access");
+const ProblemModel = require("../models/Problem");
 const sanitizeHtml = require('sanitize-html');
 const MaxNbProblems = 20;
 
 const sanitizeHtml = require('sanitize-html');
 const MaxNbProblems = 20;
 
-// Fetch N previous or next problems (AJAX)
-router.get("/problems/:variant([a-zA-Z0-9]+)", (req,res) => {
-       if (!req.xhr)
-               return res.json({errmsg: "Unauthorized access"});
-       const vname = req.params["variant"];
+// Fetch N previous or next problems
+router.get("/problems/:vname([a-zA-Z0-9]+)", access.ajax, (req,res) => {
+       const vname = req.params["vname"];
        const directionStr = (req.query.direction == "forward" ? ">" : "<");
        const lastDt = req.query.last_dt;
        if (!lastDt.match(/[0-9]+/))
                return res.json({errmsg: "Bad timestamp"});
        const directionStr = (req.query.direction == "forward" ? ">" : "<");
        const lastDt = req.query.last_dt;
        if (!lastDt.match(/[0-9]+/))
                return res.json({errmsg: "Bad timestamp"});
-       db.serialize(function() {
-               const query = "SELECT * FROM Problems " +
-                       "WHERE variant='" + vname + "' " +
-                       "  AND added " + directionStr + " " + lastDt + " " +
-                       "ORDER BY added " + (directionStr=="<" ? "DESC " : "") +
-                       "LIMIT " + MaxNbProblems;
-               db.all(query, (err,problems) => {
-                       if (!!err)
-                               return res.json(err);
-                       return res.json({problems: problems});
-               });
+       ProblemModel.fetchN(vname, directionStr, lastDt, MaxNbProblems, (err,problems) => {
+               if (!!err)
+                       return res.json(err);
+               return res.json({problems: problems});
        });
 });
 
        });
 });
 
-// Upload a problem (AJAX)
-router.post("/problems/:variant([a-zA-Z0-9]+)", (req,res) => {
-       if (!req.xhr)
-               return res.json({errmsg: "Unauthorized access"});
-       const vname = req.params["variant"];
-       const timestamp = Date.now();
-       // Sanitize them
-       const fen = req.body["fen"];
+function sanitizeUserInput(fen, instructions, solution)
+{
        if (!fen.match(/^[a-zA-Z0-9, /-]*$/))
        if (!fen.match(/^[a-zA-Z0-9, /-]*$/))
-               return res.json({errmsg: "Bad characters in FEN string"});
-       const instructions = sanitizeHtml(req.body["instructions"]).trim();
-       const solution = sanitizeHtml(req.body["solution"]).trim();
+               return "Bad characters in FEN string";
+       instructions = sanitizeHtml(instructions);
+       solution = sanitizeHtml(solution);
        if (instructions.length == 0)
        if (instructions.length == 0)
-               return res.json({errmsg: "Empty instructions"});
+               return "Empty instructions";
        if (solution.length == 0)
        if (solution.length == 0)
-               return res.json({errmsg: "Empty solution"});
-       db.serialize(function() {
-               let stmt = db.prepare("INSERT INTO Problems " +
-                       "(added,variant,fen,instructions,solution) VALUES (?,?,?,?,?)");
-               stmt.run(timestamp, vname, fen, instructions, solution);
-               stmt.finalize();
-       });
-  res.json({});
+               return "Empty solution";
+       return {
+               fen: fen,
+               instructions: instructions,
+               solution: solution
+       };
+}
+
+// Upload a problem (sanitize inputs)
+router.post("/problems/:vname([a-zA-Z0-9]+)", access.logged, access.ajax, (req,res) => {
+       const vname = req.params["vname"];
+       const s = sanitizeUserInput(req.body["fen"], req.body["instructions"], req.body["solution"]);
+       if (typeof s === "string")
+               return res.json({errmsg: s});
+  ProblemModel.create(vname, s.fen, s.instructions, s.solution);
+       res.json({});
 });
 
 });
 
-// TODO: edit, delete a problem
+// 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.user._id, fen, instructions, solution);
+       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.delete(pid, req.user._id);
+       res.json({});
+});
 
 module.exports = router;
 
 module.exports = router;