From 1f49533df1dafc5f83b815a9c89b8ccaccde2d6d Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Tue, 12 Mar 2019 12:21:15 +0100
Subject: [PATCH] 'update'

---
 server/models/Challenge.js  |  36 +++++++------
 server/models/User.js       |  10 ++++
 server/routes/challenges.js | 103 +++++++++++++++++++-----------------
 3 files changed, 86 insertions(+), 63 deletions(-)

diff --git a/server/models/Challenge.js b/server/models/Challenge.js
index 6d8f5c1e..e9772672 100644
--- a/server/models/Challenge.js
+++ b/server/models/Challenge.js
@@ -13,6 +13,7 @@ var db = require("../utils/database");
  * Structure table WillPlay:
  *   cid: ref challenge id
  *   uid: ref user id
+ *   yes: boolean (false means "not decided yet")
  */
 
 const ChallengeModel =
@@ -25,13 +26,22 @@ const ChallengeModel =
     if (!c.timeControl.match(/^[0-9dhms +]+$/))
       return "Wrong characters in time control";
 
-    if (!c.nbPlayers.match(/^[0-9]+$/))
-			return "Wrong number of players";
-
 		if (!c.fen.match(/^[a-zA-Z0-9, /-]+$/))
 			return "Bad FEN string";
 	},
 
+  initializeWillPlay: function(uids, cid, cb)
+  {
+    let query = "INSERT INTO WillPlay VALUES ";
+    for (let i=0; i<uids.length; i++)
+    {
+      query += "(false," + cid + "," + uids[i] + ")";
+      if (i < uids.length-1)
+        query += ",";
+    }
+    db.run(query, cb);
+  },
+
 	// fen cannot be undefined
 	create: function(c, cb)
 	{
@@ -45,16 +55,12 @@ const ChallengeModel =
 				if (!!err)
 					return cb(err);
 				db.get("SELECT last_insert_rowid() AS rowid", (err2,lastId) => {
-					
-          // TODO: also insert "will play" "no" for other players ?
-          // willplay = "maybe" by default ?
-          
           query =
 						"INSERT INTO WillPlay VALUES " +
 						"(true," + lastId["rowid"] + "," + c.uid + ")";
-						db.run(query, (err,ret) => {
-							cb(err, lastId); //all we need is the challenge ID
-						});
+					db.run(query, (err,ret) => {
+						cb(err, lastId); //all we need is the challenge ID
+					});
 				});
 			});
 		});
@@ -120,14 +126,14 @@ const ChallengeModel =
 		});
 	},
 
-	remove: function(id)
+	remove: function(id, uid)
 	{
-		db.parallelize(function() {
+		db.serialize(function() {
 			let query =
 				"DELETE FROM Challenges " +
-				"WHERE id = " + id;
-			db.run(query);
-			query =
+				"WHERE id = " + id + " AND uid = " + uid;
+			db.run(query, (err,ret) => {
+			  if (!!err && query = //TODO
 				"DELETE FROM WillPlay " +
 				"WHERE cid = " + id;
 			db.run(query);
diff --git a/server/models/User.js b/server/models/User.js
index cf4c5293..9401133a 100644
--- a/server/models/User.js
+++ b/server/models/User.js
@@ -63,6 +63,16 @@ const UserModel =
 		});
 	},
 
+  getByName: function(names, cb) {
+		db.serialize(function() {
+			const query =
+				"SELECT id
+        "FROM Users " +
+				"WHERE name IN ('" + names.join("','") + "')";;
+			db.all(query, cb);
+		});
+  },
+
 	/////////
 	// MODIFY
 
diff --git a/server/routes/challenges.js b/server/routes/challenges.js
index 663072f5..b1e06941 100644
--- a/server/routes/challenges.js
+++ b/server/routes/challenges.js
@@ -6,62 +6,69 @@ const ChallengeModel = require("../models/Challenge");
 const UserModel = require("../models/User"); //for name check
 
 router.post("/challenges", access.logged, access.ajax, (req,res) => {
-	const error = ChallengeModel.checkChallenge(req.body.chall);
-  // TODO: treat "to" field separately (search users by name)
-  // --> replace "to" by an array of uid (in chall), then call:
-	const from = req.userId;
-//	let to = !!req.body.to ? ObjectID(req.body.to) : undefined;
-//	let nameTo = !!req.body.nameTo ? req.body.nameTo : undefined;
-//	let vid = ObjectID(req.body.vid);
-//	if (!to && !!nameTo)
-//	{
-//		UserModel.getByName(nameTo, (err,user) => {
-//			access.checkRequest(res, err, user, "Opponent not found", () => {
-//				createChallenge(vid, from, user._id, res);
-//			});
-//		});
-//	}
-//	else if (!!to)
-//		createChallenge(vid, from, to, res);
-//	else
-//		createChallenge(vid, from, undefined, res); //automatch
-	ChallengeModel.create(req.body.chall, (err,lastId) => {
-		res.json(err || {cid: lastId["rowid"]});
-	});
+  const error = ChallengeModel.checkChallenge(req.body.chall);
+  if (!!error)
+    return res.json({errmsg:error});
+  const challenge =
+  {
+    fen: req.body.chall.fen,
+    timeControl: req.body.chall.timeControl,
+    vid: req.body.chall.vid,
+    uid: req.userId,
+    nbPlayers: req.body.chall.to.length,
+  };
+  ChallengeModel.create(challenge, (err,lastId) => {
+    if (!!err)
+      return res.json(err);
+    if (!!req.body.chall.to[0])
+    {
+      UserModel.getByName(req.body.chall.to, (err,users) => {
+        if (!!err)
+          return res.json(err);
+        if (users.length < req.body.chall.to.length)
+          return res.json({errmsg: "Typo in player(s) name(s)"});
+        ChallengeModel.initializeWillPlay(
+          users.map(u => u.id),
+          lastId["rowid"],
+          (err) => {
+            if (!!err)
+              return res.json(err);
+            res.json({cid: lastId["rowid"]});
+          }
+        );
+      });
+    }
+    else
+      res.json({cid: lastId["rowid"]});
+  });
 });
 
 //// index
 //router.get("/challenges", access.logged, access.ajax, (req,res) => {
-//	if (req.query["uid"] != req.user._id)
-//		return res.json({errmsg: "Not your challenges"});
-//	let uid = ObjectID(req.query["uid"]);
-//	ChallengeModel.getByPlayer(uid, (err, challengeArray) => {
-//		res.json(err || {challenges: challengeArray});
-//	});
+//  if (req.query["uid"] != req.user._id)
+//    return res.json({errmsg: "Not your challenges"});
+//  let uid = ObjectID(req.query["uid"]);
+//  ChallengeModel.getByPlayer(uid, (err, challengeArray) => {
+//    res.json(err || {challenges: challengeArray});
+//  });
 //});
 //
 //function createChallenge(vid, from, to, res)
 //{
-//	ChallengeModel.create(vid, from, to, (err, chall) => {
-//		res.json(err || {
-//			// A challenge can be sent using only name, thus 'to' is returned
-//			to: chall.to,
-//			cid: chall._id
-//		});
-//	});
+//  ChallengeModel.create(vid, from, to, (err, chall) => {
+//    res.json(err || {
+//      // A challenge can be sent using only name, thus 'to' is returned
+//      to: chall.to,
+//      cid: chall._id
+//    });
+//  });
 //}
-//
-//router.delete("/challenges", access.logged, access.ajax, (req,res) => {
-//	let cid = ObjectID(req.query.cid);
-//	ChallengeModel.getById(cid, (err,chall) => {
-//		access.checkRequest(res, err, chall, "Challenge not found", () => {
-//			if (!chall.from.equals(req.user._id) && !!chall.to && !chall.to.equals(req.user._id))
-//				return res.json({errmsg: "Not your challenge"});
-//			ChallengeModel.remove(cid, err => {
-//				res.json(err || {});
-//			});
-//		});
-//	});
-//});
+
+router.delete("/challenges", access.logged, access.ajax, (req,res) => {
+  const cid = req.query.cid;
+  ChallengeModel.remove(cid, req.userId, err => {
+    res.json(err || {});
+  });
+});
 
 module.exports = router;
-- 
2.44.0