Changeset 492 for Dev/trunk/src/server


Ignore:
Timestamp:
03/09/14 14:23:42 (11 years ago)
Author:
hendrikvanantwerpen
Message:
  • Enable/disable buttons on content change.
  • One place to do date formatting, because it was going wrong again.
  • Serialize questions in survey properly.
  • _ComplexValueMixin consumes submit events, but does trigger outer forms if present.
  • Trigger dialog show/hide for login only after previous effect is finished.
  • Check that documents are actually valid, not just that validator returned a result.
  • Validate email and timestamp formats.
  • Prepared for live runs.
Location:
Dev/trunk/src/server
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • Dev/trunk/src/server/app.js

    r490 r492  
    88  , CouchDB = require('./util/couch').CouchDB
    99  , _ = require("underscore")
    10   , tv4 = require("tv4")
     10  , validator = require("./util/validator")
    1111  , HTTPResult = require("./util/http-result")
    1212  , etags = require("./util/etags")
     
    151151        return new HTTPResult(500,{error: error.reason});
    152152    }
    153     function handleUnknownError(error){
     153    function handleUnknownError(error) {
    154154        return new HTTPResult(500, {error: "Unknown error", innerError: error});
    155155    }
     
    159159    function handleRowDocs(result) {
    160160        return _.map(result.rows, function(item) { return item.doc; });
     161    }
     162    function handleRowFirstDoc(result) {
     163        if ( result.rows.length > 0 ) {
     164            return result.rows[0].doc;
     165        } else {
     166            return new HTTPResult(404,{error:"No document found."});
     167        }
     168    }
     169    function handleRowFirstValue(result) {
     170        if ( result.rows.length > 0 ) {
     171            return result.rows[0].value;
     172        } else {
     173            return new HTTPResult(404,{error:"No document found."});
     174        }
     175    }
     176    function handleRowDictOfDocs(result) {
     177        return _.reduce(result.rows, function(dict,item) {
     178            dict[item.key] = item.doc;
     179            return dict;
     180        }, {});
     181    }
     182    function handleRowDictOfValues(result) {
     183        return _.reduce(result.rows, function(dict,item) {
     184            dict[item.key] = item.value;
     185            return dict;
     186        }, {});
    161187    }
    162188
     
    199225    function putDocument(id,rev,type,doc) {
    200226        var priv = stripAndReturnPrivates(doc);
    201         if ( doc.type === type && tv4.validateResult(doc, schema) ) {
     227        if ( doc.type === type && validator(doc, schema).valid ) {
    202228            var opts = rev ? {headers:{'If-Match':'"'+rev+'"'}} : {};
    203229            return HTTPResult.fromResponsePromise(couch.put(id,doc,opts).response,
     
    236262    function postDocument(type,doc) {
    237263        var priv = stripAndReturnPrivates(doc);
    238         if ( doc.type === type && tv4.validateResult(doc, schema) ) {
     264        if ( doc.type === type && validator(doc, schema).valid ) {
    239265            return HTTPResult.fromResponsePromise(couch.post(doc).response,
    240266                                                  handleUnknownError)
     
    321347        .handle({
    322348            200: handleRowDocs,
     349            default: handleUnknownResponse
     350        });
     351    }
     352    function getQuestionsAndCodes() {
     353        var url = '_design/questions/_view/by_code';
     354        var query = {include_docs:true};
     355        return HTTPResult.fromResponsePromise(couch.get(url,{query:query}).response,
     356                                              handleUnknownError)
     357        .handle({
     358            200: handleRowDictOfDocs,
    323359            default: handleUnknownResponse
    324360        });
     
    760796                        return new HTTPResult(403,{error: "Secrets are not the same."});
    761797                    } else {
    762                         return deleteDocument(id,rev,doc);
     798                        return getDocument(doc.surveyRunId,[],'SurveyRun')
     799                        .handle({
     800                            200: function(surveyRun) {
     801                                if ( surveyRun.respondentCanDeleteOwnResponse === true ) {
     802                                    return deleteDocument(id,rev,doc);
     803                                } else {
     804                                    return new HTTPResult(403,{error:"Not allowed to delete response."});
     805                                }
     806                            }
     807                        });
    763808                    }
    764809                }
  • Dev/trunk/src/server/config/check-couchdb.js

    r487 r492  
    11var Q = require('q')
    22  , _ = require('underscore')
    3   , tv4 = require('tv4')
     3  , validator = require('../util/validator')
    44  , CouchDB = require('../util/couch').CouchDB
    55  ;
     
    1010    var server = new CouchDB(couchServerURL,dbName);
    1111    var designRe = /^_design\//;
     12
     13    var codes = {};
     14    function codeUnique(code) {
     15        if ( code in codes ) {
     16            return false;
     17        } else {
     18            codes[code] = true;
     19            return true;
     20        }
     21    }
     22
    1223    return server.get('/_all_docs')
    1324    .then(function(allDocs){
     
    2031                return server.get(doc.id)
    2132                .then(function(doc){
    22                     var valid = tv4.validateResult(doc,schema);
     33                    var valid = validator(doc,schema);
     34                    if ( doc.type === "Question" && !codeUnique(doc.code) ) {
     35                        valid.valid = false;
     36                        valid.error = "Question code "+doc.code+" is not unique.";
     37                    }
    2338                    result[doc._id] = valid;
    2439                    return result;
  • Dev/trunk/src/server/config/couchdb-design-docs.js

    r487 r492  
    125125    },
    126126
     127    "qed/_design/surveyRuns": {
     128        __configAction: "replace",
     129        _id: "_design/surveys",
     130        language: "javascript",
     131        views: {
     132            by_dates: {
     133                map: function(doc){
     134                    if ( doc.type !== 'SurveyRun' ) { return; }
     135                    var startDate = doc.startDate || "";
     136                    var endDate = doc.endDate || {};
     137                    emit([startDate,endDate,doc.liveName||null],doc);
     138                }
     139            }
     140        }
     141    },
     142
    127143    "qed/_design/responses": {
    128144        __configAction: "replace",
  • Dev/trunk/src/server/config/couchdb-schema.json

    r487 r492  
    3636          "_rev": { "type": "string" },
    3737          "categories": { "type": "array", "items": { "type": "string" } },
    38           "code": { "type": "string" },
     38          "code": { "type": "string", "minLength": 1 },
    3939          "content": { "type": "array", "items": { "$ref": "#/definitions/content/any" } },
    4040          "description": { "type": "string" },
     
    5252          "_id": { "type": "string" },
    5353          "_rev": { "type": "string" },
     54          "description": { "type": "string" },
    5455          "publicationDate": { "type": "string", "format": "datetime" },
    5556          "questions": { "type": "array", "items": { "$ref": "#/definitions/docs/Question" } },
     
    6768          "description": { "type": "string" },
    6869          "endDate": { "type": "string", "format": "datetime" },
     70          "liveName": { "type": "string" },
    6971          "mode": { "type": "string", "enum": [ "open", "closed" ] },
    70           "secret": { "type": "string", "minLength": 8 },
     72          "respondentCanDeleteOwnResponse": { "type": "boolean" },
     73          "secret": { "type": "string", "minLength": 1 },
    7174          "startDate": { "type": "string", "format": "datetime" },
    7275          "survey": { "$ref": "#/definitions/docs/Survey" },
     
    8386          "_rev": { "type": "string" },
    8487          "answers": { "type": "object" },
     88          "email": { "type": "string", "format": "email" },
    8589          "publicationDate": { "type": "string", "format": "datetime" },
    86           "secret": { "type": "string", "minLength": 8 },
     90          "secret": { "type": "string", "minLength": 1 },
    8791          "surveyRunId": { "type": "string" }
    8892        },
  • Dev/trunk/src/server/config/upgrade-couchdb.js

    r487 r492  
    11var Q = require('q')
    22  , _ = require('underscore')
    3   , tv4 = require('tv4')
    43  , CouchDB = require('../util/couch').CouchDB
    54  ;
Note: See TracChangeset for help on using the changeset viewer.