source: Dev/trunk/src/server/app.js @ 534

Last change on this file since 534 was 534, checked in by hendrikvanantwerpen, 10 years ago

Treat non-api URLs as client URLs.

File size: 5.2 KB
Line 
1var express = require("express")
2  , passport = require("passport")
3  , passportLocal = require("passport-local")
4  , fs = require("fs")
5  , path = require("path")
6  , proxy = require("./util/simple-http-proxy")
7  , CouchDB = require('./util/couch')
8  , HTTPResult = require('./util/http-result')
9  , _ = require("underscore")
10  ;
11
12exports.app = function(env) {
13
14    assertSetting("couchServerURL", env, _.isString);
15    assertSetting("dbName", env, _.isString);
16    assertSetting("mode", env, _.isString);
17    var couch = new CouchDB(env.couchServerURL,env.dbName);
18   
19    var schema = require("./config/couchdb-schema.json");
20    var views = require("./config/couchdb-design-docs.js");
21    return couch.get("schemaInfo")
22    .then(function(schemaInfo){
23        if ( schemaInfo.version !== schema.version ) {
24            return HTTPResult.fail(
25                new Error("Found schema version "+schemaInfo.version+
26                          ", expected "+schema.version));
27        } else if ( schemaInfo.viewsVersion !== views.schemaInfo.viewsVersion ) {
28            return HTTPResult.fail(
29                new Error("Found views version "+schemaInfo.viewsVersion+
30                          ", expected "+views.schemaInfo.viewsVersion));
31        } else {
32            return configureApp(env,couch,schema);
33        }
34    });
35
36};
37
38function configureApp(env,couch,schema) {
39
40    var apiUtil = require('./api/util')(couch,schema);
41
42    function clientPath(relativePath) {
43        return path.resolve(__dirname+'/../client/'+relativePath);
44    }
45
46    passport.use(
47        new passportLocal.Strategy(
48            function(username, password, done){
49                if ( username === "igor" && password === "mayer" ) {
50                    done(null,{ username: "igor" });
51                } else {
52                    done(null,false,{ message: 'Invalid credentials.' });
53                }
54            }));
55    passport.serializeUser(function(user, done) {
56        done(null, user.username);
57    });
58    passport.deserializeUser(function(id, done) {
59        done(null, {username: id});
60    });
61
62    var app = express();
63    app.use(express.logger());
64    app.use(express.compress());
65    app.use(express.favicon());
66
67    // cookies and session
68    app.use(express.cookieParser());
69    app.use(express.session({ secret: "quasi experimental design" }));
70    app.use('/api',express.bodyParser());
71
72    // passport
73    app.use(passport.initialize());
74    app.use(passport.session());
75   
76    // various middlewares
77    function ensureAuthenticated(req,res,next){
78        if (!req.user) {
79            return res.send(401,{error:"Login before accessing API."});
80        } else {
81            return next();
82        }
83    }
84    function returnUser(req,res) {
85        res.send(200, req.user);
86    }
87    function notImplemented(req,res) {
88        res.send(501,{error:"API not implemented yet."});
89    }
90
91    // static resources
92    app.get('/', function(req, res){
93        res.sendfile(clientPath('index.html'));
94    });
95    app.get('/*.html', function(req, res) {
96        res.sendfile(clientPath(req.path));
97    });
98    _.each(['/dojo', '/dijit', '/dojox', '/qed', '/qed-client'], function(dir){
99        app.use(dir, express.static(clientPath(dir)));
100    });
101
102    // post to this url to login
103    app.post(
104        '/api/login',
105        passport.authenticate('local'),
106        returnUser);
107
108    // return the info for the current logged in user
109    app.get(
110        '/api/login',
111        ensureAuthenticated,
112        returnUser);
113
114    // explicitly logout this user
115    app.post(
116        '/api/logout',
117        ensureAuthenticated,
118        function(req,res){
119            req.logout();
120            res.send(200,{});
121        });
122
123    app.use('/api/questions', ensureAuthenticated);
124    app.use('/api/questions',
125            require('./api/questions')(couch,schema).app);
126
127    app.use('/api/categories', ensureAuthenticated);
128    app.use('/api/categories',
129            require('./api/categories')(couch,schema).app);
130
131    app.use('/api/topics', ensureAuthenticated);
132    app.use('/api/topics',
133            require('./api/topics')(couch,schema).app);
134
135    app.use('/api/surveys', ensureAuthenticated);
136    app.use('/api/surveys',
137            require('./api/surveys')(couch,schema).app);
138
139    app.use('/api/surveyRuns', ensureAuthenticated);
140    app.use('/api/surveyRuns',
141            require('./api/surveyRuns')(couch,schema).app);
142
143    app.use('/api/responses', ensureAuthenticated);
144    app.use('/api/responses',
145            require('./api/responses')(couch,schema).app);
146
147    app.use('/api/open',
148            require('./api/open')(couch,schema).app);
149
150    app.get('/api/mode',
151        apiUtil.ensureMIME(apiUtil.JSON_MIME),
152        function(req,res){
153            res.send({mode:env.mode});
154        });
155
156    // anything not handled before is redirected
157    // as if it was a client URL
158    app.use('/',function(req,res){
159        res.redirect('#!'+req.path);
160    });
161
162    return app;
163}
164
165function assertSetting(name, settings, validate) {
166    if ( typeof settings[name] === 'undefined' ) {
167        throw new Error("Required setting '"+name+"' undefined.");
168    }
169    if ( _.isFunction(validate) && !validate(settings[name]) ) {
170        throw new Error("Setting '"+name+"' with value '"+settings[name]+"' is invalid.");
171    }
172}
Note: See TracBrowser for help on using the repository browser.