var express = require("express") , cryptoken = require("../util/crypto-token") , HTTPResult = require("../util/http-result") , etags = require("../util/etags") ; module.exports = function(couch,schema) { var exports = {}; var util = require('./util')(couch,schema); var app = exports.app = express(); var isSurveyRunRunning = exports.isSurveyRunRunning = function(surveyRun) { var now = new Date(); var afterStart = !surveyRun.startDate || now >= new Date(surveyRun.startDate); var beforeEnd = !surveyRun.endDate || now <= new Date(surveyRun.endDate); return afterStart && beforeEnd; }; app.get('/responses/:id', util.ensureMIME(util.JSON_MIME), function(req,res) { var id = req.params.id; var rev = etags.parse(req.header('If-Non-Match'))[0]; var secret = req.query.secret; util.getDocument(id,rev,'Response') .handle({ 200: function(response) { if ( response.secret === secret ) { return util.getDocument(response.surveyRunId,[],'SurveyRun') .handle({ 200: function(surveyRun) { if ( !isSurveyRunRunning(surveyRun) ) { return new HTTPResult(404,{error:"Survey is not running anymore."}); } else { response._surveyRun = surveyRun; return response; } } }); } else { return new HTTPResult(403,{error: "Wrong secret for response"}); } } }) .handle(res.send.bind(res)); }); app.post('/responses', util.ensureMIME(util.JSON_MIME), function(req,res) { var secret = req.query.secret; var response = req.body; delete response._surveyRun; util.getDocument(response.surveyRunId,[],'SurveyRun') .handle({ 200: function(surveyRun) { if ( surveyRun.secret !== secret ) { return new HTTPResult(403,{error:"Wrong secret for surveyRun."}); } else if ( !isSurveyRunRunning(surveyRun) ) { return new HTTPResult(404,{error:"Survey is not running anymore."}); } else if ( surveyRun.mode === 'closed' ) { return new HTTPResult(403,{error:"Survey is closed and doesn't allow new responses."}); } else { return cryptoken() .then(function(token) { response.secret = token; return util.postDocument('Response',response) .then(function(doc){ doc._surveyRun = surveyRun; return doc; }); }); } } }) .handle(res.send.bind(res)); }); app.put('/responses/:id', util.ensureMIME(util.JSON_MIME), function(req,res){ var id = req.params.id; var doc = req.body; var rev = etags.parse(req.header('If-Match'))[0] || (doc && doc._rev); var secret = req.query.secret || doc.secret; delete doc._surveyRun; util.getDocument(id,[],'Response') .handle({ 200: function(prev) { if ( prev.secret !== secret ) { return new HTTPResult(403,{error: "Secrets are not the same."}); } else if ( prev.surveyRunId !== doc.surveyRunId ) { return new HTTPResult(400,{error:"Response cannot change it's surveyRunId."}); } else { doc.secret = secret; // restore in case it got lost or was changed return util.getDocument(doc.surveyRunId,[],'SurveyRun') .handle({ 200: function(surveyRun) { if ( !isSurveyRunRunning(surveyRun) ) { return new HTTPResult(404,{error:"Survey is not running anymore."}); } else { return util.putDocument(id,rev,'Response',doc) .handle({ 200: function(doc) { doc._surveyRun = surveyRun; return new HTTPResult(201,doc); } }); } } }); } } }) .handle(res.send.bind(res)); }); app.delete('/responses/:id', util.ensureMIME(util.JSON_MIME), function(req,res){ var id = req.params.id; var doc = req.body; var rev = etags.parse(req.header('If-Match'))[0] || (doc && doc._rev); var secret = req.query.secret || doc.secret; delete doc._surveyRun; util.getDocument(id,[],'Response') .handle({ 200: function(prev) { if ( prev.secret !== secret ) { return new HTTPResult(403,{error: "Secrets are not the same."}); } else { return util.getDocument(doc.surveyRunId,[],'SurveyRun') .handle({ 200: function(surveyRun) { if ( surveyRun.respondentCanDeleteOwnResponse === true ) { return util.deleteDocument(id,rev,doc); } else { return new HTTPResult(403,{error:"Not allowed to delete response."}); } } }); } } }) .handle(res.send.bind(res)); }); return exports; };