var express = require("express") , passport = require("passport") , passportLocal = require("passport-local") , fs = require("fs") , path = require("path") , proxy = require("./util/simple-http-proxy") , CouchDB = require('./util/couch') , HTTPResult = require('./util/http-result') , _ = require("underscore") ; exports.app = function(env) { assertSetting("couchServerURL", env, _.isString); assertSetting("dbName", env, _.isString); assertSetting("mode", env, _.isString); var couch = new CouchDB(env.couchServerURL,env.dbName); var schema = require("./config/couchdb-schema.json"); var views = require("./config/couchdb-design-docs.js"); return couch.get("schemaInfo") .then(function(schemaInfo){ if ( schemaInfo.version !== schema.version ) { return HTTPResult.fail( new Error("Found schema version "+schemaInfo.version+ ", expected "+schema.version)); } else if ( schemaInfo.viewsVersion !== views.schemaInfo.viewsVersion ) { return HTTPResult.fail( new Error("Found views version "+schemaInfo.viewsVersion+ ", expected "+views.schemaInfo.viewsVersion)); } else { return configureApp(env,couch,schema); } }); }; function configureApp(env,couch,schema) { var apiUtil = require('./api/util')(couch,schema); function clientPath(relativePath) { return path.resolve(__dirname+'/../client/'+relativePath); } passport.use( new passportLocal.Strategy( function(username, password, done){ if ( username === "igor" && password === "mayer" ) { done(null,{ username: "igor" }); } else { done(null,false,{ message: 'Invalid credentials.' }); } })); passport.serializeUser(function(user, done) { done(null, user.username); }); passport.deserializeUser(function(id, done) { done(null, {username: id}); }); var app = express(); app.use(express.logger()); app.use(express.compress()); app.use(express.favicon()); // cookies and session app.use(express.cookieParser()); app.use(express.session({ secret: "quasi experimental design" })); app.use('/api',express.bodyParser()); // passport app.use(passport.initialize()); app.use(passport.session()); // various middlewares function ensureAuthenticated(req,res,next){ if (!req.user) { return res.send(401,{error:"Login before accessing API."}); } else { return next(); } } function returnUser(req,res) { res.send(200, req.user); } function notImplemented(req,res) { res.send(501,{error:"API not implemented yet."}); } // static resources app.get('/', function(req, res){ res.sendfile(clientPath('index.html')); }); app.get('/*.html', function(req, res) { res.sendfile(clientPath(req.path)); }); _.each(['/dojo', '/dijit', '/dojox', '/qed', '/qed-client'], function(dir){ app.use(dir, express.static(clientPath(dir))); }); // post to this url to login app.post( '/api/login', passport.authenticate('local'), returnUser); // return the info for the current logged in user app.get( '/api/login', ensureAuthenticated, returnUser); // explicitly logout this user app.post( '/api/logout', ensureAuthenticated, function(req,res){ req.logout(); res.send(200,{}); }); app.use('/api/questions', ensureAuthenticated); app.use('/api/questions', require('./api/questions')(couch,schema).app); app.use('/api/categories', ensureAuthenticated); app.use('/api/categories', require('./api/categories')(couch,schema).app); app.use('/api/topics', ensureAuthenticated); app.use('/api/topics', require('./api/topics')(couch,schema).app); app.use('/api/surveys', ensureAuthenticated); app.use('/api/surveys', require('./api/surveys')(couch,schema).app); app.use('/api/surveyRuns', ensureAuthenticated); app.use('/api/surveyRuns', require('./api/surveyRuns')(couch,schema).app); app.use('/api/responses', ensureAuthenticated); app.use('/api/responses', require('./api/responses')(couch,schema).app); app.use('/api/open', require('./api/open')(couch,schema).app); app.get('/api/mode', apiUtil.ensureMIME(apiUtil.JSON_MIME), function(req,res){ res.send({mode:env.mode}); }); return app; } function assertSetting(name, settings, validate) { if ( typeof settings[name] === 'undefined' ) { throw new Error("Required setting '"+name+"' undefined."); } if ( _.isFunction(validate) && !validate(settings[name]) ) { throw new Error("Setting '"+name+"' with value '"+settings[name]+"' is invalid."); } }