Reputation: 175
I am building a quiz website using Node/Express.
How do I ensure that users submit quiz within a specified period of time without using client-side javascript? That is, if the quiz takes 10 minutes, submission afterwards should marked as too late.
Both GET and POST requests are to the same url
Upvotes: 3
Views: 305
Reputation: 2768
I had the same question to solve in a evaluations app.
Here is the way I save a new date allowing to later check on server if the time is bigger than my limit when answering:
Client code:
startEvaluation: function (data) {
return $http.put(startUrl + '/' + data._id,data);
},
Server code:
exports.startEvaluation = function (req, res) {
if(req.body.status==="NEW")req.body.status="STARTED";
req.body.started=Date.now();
Evaluation.findOneAndUpdate({_id: req.body._id}, req.body, {upsert:true , new: true }, function(err, evaluation)
{
if (err) {
return handleError(res, err);
}
if (!evaluation) {
return res.send(404);
}
});
};
Hope it helps
EDIT:
As you said are the same urls, you can use the parameter (like new for example). This way, if you answer with a NEW condition, you just call the begin method:
exports.answer = function (req, res) {
if(req.body.status==="NEW")
{
req.body.status="STARTED";
req.body.started=Date.now();
}
else
{
//Process answer here and compare another Date.now() with the stored date, and your time limit to answer
console.log("answer");
}
Evaluation.findOneAndUpdate({_id: req.body._id}, req.body, {upsert:true , new: true }, function(err, evaluation)
{
if (err) {
return handleError(res, err);
}
if (!evaluation) {
return res.send(404);
}
//here is the updated evaluation with the started value.
return res.json(200, evaluations);
});
};
The method on the client:
$scope.saveAnswer = function ()
{
if($rootScope.evaluation.status==="NEW")
{
evaluationService.startEvaluation($rootScope.evaluation);
}
else
{
//Your answer treatment
}
}
Anyway, a little improve on server could be done checking the test must be started to allow answering.
EDIT
Here is the code for the server to control the status of the evaluation/quiz from the backside. This allows you to mark as "outdated" the evaluations the user did not finish during the allowed 20 mins after the beginning of the quiz. Note that a
setTimeout
is done to leave the task on server side, waiting to reach the max time configured (20 mins in example)
function marcarNoTerminada(id, body) {
//later you can check the status to filter answers given after limit hour
body.status="NOT FINISHED";
Evaluation.findOneAndUpdate({_id: id}, body, {upsert:true , new: true }, function(err, evaluation)
{
console.log("Evaluacion sin finalizar");
});
}
exports.startEvaluation = function (req, res) {
if(req.body.status==="NEW")req.body.status="STARTED";
req.body.started=Date.now();
req.body.validEnd= new Date(req.body.started+(60000*20));
var theTimer = setTimeout(function(){marcarNoTerminada(req.body._id, req.body);}, 60000*20);
Evaluation.findOneAndUpdate({_id: req.body._id}, req.body, {upsert:true , new: true }, function(err, evaluation)
{
if (err) {
return handleError(res, err);
}
if (!evaluation) {
return res.send(404);
}
return res.json(200, evaluation);
});
};
Upvotes: 2
Reputation: 496
Dépends on the level of security and bad-connectivity-proofness you want, but what I would do is start a timer server-side when the quizz is served to the client, and reject it if the answer is submitted after a given period (10mn plus a little margin).
And to keep the client aware, you could code a client-side timer that would use as start time a value set directly in the client html by the server when serving the page.
Hope this helps !
Upvotes: 2