source: Dev/trunk/src/server/api/open.js @ 525

Last change on this file since 525 was 525, checked in by hendrikvanantwerpen, 11 years ago
  • Allow empty subcodes.
  • Use HTTPResult exclusively on server (no more q).
  • Set readonly & disabled on ourselves as well in _ComplexValueMixin
  • Split server into several modules.
  • Check codes on the variable level, not question level.
  • We can add modules in design documents now.
File size: 6.4 KB
Line 
1var express = require("express")
2  , cryptoken = require("../util/crypto-token")
3  , HTTPResult = require("../util/http-result")
4  , etags = require("../util/etags")
5  ;
6
7module.exports = function(couch,schema) {
8    var exports = {};
9
10    var util = require('./util')(couch,schema);
11    var app = exports.app = express();
12
13    var isSurveyRunRunning = exports.isSurveyRunRunning = function(surveyRun) {
14        var now = new Date();
15        var afterStart = !surveyRun.startDate || now >= new Date(surveyRun.startDate);
16        var beforeEnd = !surveyRun.endDate || now <= new Date(surveyRun.endDate);
17        return afterStart && beforeEnd;
18    };
19
20    app.get('/responses/:id',
21        util.ensureMIME(util.JSON_MIME),
22        function(req,res) {
23            var id = req.params.id;
24            var rev = etags.parse(req.header('If-Non-Match'))[0];
25            var secret = req.query.secret;
26            util.getDocument(id,rev,'Response')
27            .handle({
28                200: function(response) {
29                    if ( response.secret === secret ) {
30                        return util.getDocument(response.surveyRunId,[],'SurveyRun')
31                        .handle({
32                            200: function(surveyRun) {
33                                if ( !isSurveyRunRunning(surveyRun) ) {
34                                    return new HTTPResult(404,{error:"Survey is not running anymore."});
35                                } else {
36                                    response._surveyRun = surveyRun;
37                                    return response;
38                                }
39                            }
40                        });
41                    } else {
42                        return new HTTPResult(403,{error: "Wrong secret for response"});
43                    }
44                }
45            })
46            .handle(res.send.bind(res));
47        });
48    app.post('/responses',
49        util.ensureMIME(util.JSON_MIME),
50        function(req,res) {
51            var secret = req.query.secret;
52            var response = req.body;
53            delete response._surveyRun;
54            util.getDocument(response.surveyRunId,[],'SurveyRun')
55            .handle({
56                200: function(surveyRun) {
57                    if ( surveyRun.secret !== secret ) {
58                        return new HTTPResult(403,{error:"Wrong secret for surveyRun."});
59                    } else if ( !isSurveyRunRunning(surveyRun) ) {
60                        return new HTTPResult(404,{error:"Survey is not running anymore."});
61                    } else if ( surveyRun.mode === 'closed' ) {
62                        return new HTTPResult(403,{error:"Survey is closed and doesn't allow new responses."});
63                    } else {
64                        return cryptoken()
65                        .then(function(token) {
66                            response.secret = token;
67                            return util.postDocument('Response',response)
68                            .then(function(doc){
69                                doc._surveyRun = surveyRun;
70                                return doc;
71                            });
72                        });
73                    }
74                }
75            })
76            .handle(res.send.bind(res));
77        });
78    app.put('/responses/:id',
79        util.ensureMIME(util.JSON_MIME),
80        function(req,res){
81            var id = req.params.id;
82            var doc = req.body;
83            var rev = etags.parse(req.header('If-Match'))[0] || (doc && doc._rev);
84            var secret = req.query.secret || doc.secret;
85            delete doc._surveyRun;
86            util.getDocument(id,[],'Response')
87            .handle({
88                200: function(prev) {
89                    if ( prev.secret !== secret ) {
90                        return new HTTPResult(403,{error: "Secrets are not the same."});
91                    } else if ( prev.surveyRunId !== doc.surveyRunId ) {
92                        return new HTTPResult(400,{error:"Response cannot change it's surveyRunId."});
93                    } else {
94                        doc.secret = secret; // restore in case it got lost or was changed
95                        return util.getDocument(doc.surveyRunId,[],'SurveyRun')
96                        .handle({
97                            200: function(surveyRun) {
98                                if ( !isSurveyRunRunning(surveyRun) ) {
99                                    return new HTTPResult(404,{error:"Survey is not running anymore."});
100                                } else {
101                                    return util.putDocument(id,rev,'Response',doc)
102                                    .handle({
103                                        200: function(doc) {
104                                            doc._surveyRun = surveyRun;
105                                            return new HTTPResult(201,doc);
106                                        }
107                                    });
108                                }
109                            }
110                        });
111                    }
112                }
113            })
114            .handle(res.send.bind(res));
115        });
116    app.delete('/responses/:id',
117        util.ensureMIME(util.JSON_MIME),
118        function(req,res){
119            var id = req.params.id;
120            var doc = req.body;
121            var rev = etags.parse(req.header('If-Match'))[0] || (doc && doc._rev);
122            var secret = req.query.secret || doc.secret;
123            delete doc._surveyRun;
124            util.getDocument(id,[],'Response')
125            .handle({
126                200: function(prev) {
127                    if ( prev.secret !== secret ) {
128                        return new HTTPResult(403,{error: "Secrets are not the same."});
129                    } else {
130                        return util.getDocument(doc.surveyRunId,[],'SurveyRun')
131                        .handle({
132                            200: function(surveyRun) {
133                                if ( surveyRun.respondentCanDeleteOwnResponse === true ) {
134                                    return util.deleteDocument(id,rev,doc);
135                                } else {
136                                    return new HTTPResult(403,{error:"Not allowed to delete response."});
137                                }
138                            }
139                        });
140                    }
141                }
142            })
143            .handle(res.send.bind(res));
144        });
145
146    return exports;
147};
Note: See TracBrowser for help on using the repository browser.