settings.js | |
---|---|
| |
Settings | |
Express | var express = require('express')
, port = 3000
, cacheAge = 24 * 60 * 60 * 1000 |
Common | , fs = require('fs')
, colors = require('colors')
, mime = require('mime')
, sys = require('sys')
, gzippo = require('gzippo') |
Good and badTODO: this should be added to Marak's Don't use error/success since that could conflict with callbacks. | , good = " ✔ ".green
, bad = " ✗ ".red |
ConfigBased on your project's needs, you should configure TODO: Upgrade to 0.6.x which supports using require('config.json') | , config = JSON.parse(fs.readFileSync(__dirname + '/config.json', 'utf8')) |
Mongo Session Store | , MongoStore = require('connect-mongo') |
Cross Site Request Forgery | , csrf = require('express-csrf') |
Stylesheets | , stylus = require('stylus')
, nib = require('nib') |
Logs | , logs = {
set: true,
string: '\\n ' + ':date'.bold.underline + '\\n\\n' + ' IP: '.cyan.bold
+ ' ' + ':remote-addr'.white + '\\n' + ' Method: '.red.bold
+ ':method'.white + '\\n' + ' URL: '.blue.bold + ':url'.white
+ '\\n' + ' Status: '.yellow.bold + ':status'.white + '\\n'
+ ' User Agent: '.magenta.bold + ':user-agent'.white
}
, css = {
count: 0,
debug: false,
set: true,
string: function() {
return ''
+ '\n' + good + ' Stylus has detected changes and compiled new assets'
+ ' ' + this.count + ' times so far' + '\n';
}
} |
Set cache busting for development purposes as a view middleware helperThis gets turned off in production mode, see below (e.g. | , cacheBusting = true |
Stylus Compiler | , compress = false // this is set to true in prod
, linenos = true // this is set to false in prod
, compiler = function(str, path) {
if (css.set) {
css.count++;
var cssString = css.string();
sys.puts(cssString);
}
return stylus(str)
.set('filename', path)
.set('compress', compress)
.set('warn', false)
.set('force', false)
.set('firebug', false)
.set('linenos', linenos)
.use(nib());
}; |
Helper functions | |
function mongoStoreConnectionArgs(db) {
return {
db: db.connections[0].db.databaseName
, host: db.connections[0].db.serverConfig.host
, port: db.connections[0].db.serverConfig.port
, username: db.connections[0].user
, password: db.connections[0].pass
};
} | |
Logout middleware helper | function logout(req, res, next) {
req.logout = function() {
delete req.session.auth;
};
next();
} |
Login middleware helper | function loggedIn(req, res, next) {
if(req.session.auth) {
req.loggedIn = true;
} else {
req.loggedIn = false;
}
next();
} |
Create a "Super Admin" user/group if one does not already exist | function createSuperAdmin(db) {
var Group = require('./schemas/group')(db)
, User = require('./schemas/user')(db)
, superGroup = {
name: "Super Admin"
}
, superUser = {
email: "hello@expressling.com"
, name: { first: "Bro", last: "Grammer" }
, company: "Brogrammers"
, password: "expressling"
};
Group.count(superGroup, function(err, count) {
if(err) console.log(err);
if(count === 0) {
Group.create(superGroup, function(err, group) {
if(err) console.log(err);
if(group) {
superUser._group = group._id;
User.register(superUser, function(err, user) {
if(err) console.log(bad + err);
if(user) console.log(good + "Super Admin user/group created");
});
}
});
}
});
} |
Application Configuration | exports.bootApplication = function(app, db) { |
Create Super AdminTODO: Move this elsewhere so it doesn't run every time... | createSuperAdmin(db); |
Default Settings | app.configure(function() {
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser()); |
Load Mongo session store | app.use(express.session({
secret: "##### CHANGE THIS SECRET TO SOMETHING PRIVATE AND HASHED #####"
, maxAge: cacheAge
, store: new MongoStore(mongoStoreConnectionArgs(db))
})); |
Check for csrf using express-csrf module | app.use(csrf.check());
app.use(express.favicon(__dirname + '/public/favicon.ico'));
app.use(logout);
app.use(loggedIn);
}); |
Development Settings | app.configure('development', function() {
app.use(stylus.middleware({
src: __dirname + '/views',
dest: __dirname + '/public',
debug: css.debug,
compile: compiler
}));
app.use(express.static(__dirname + '/public', { maxAge: cacheAge }));
app.set('showStackError', true);
if(logs.set) app.use(express.logger(logs.string));
}); |
Staging SettingsTODO: Build out the configuration for this mode.
| |
Production Settings
| app.configure('production', function() {
cacheBusting = false;
compress = true;
linenos = false;
app.use(stylus.middleware({
src: __dirname + '/views',
dest: __dirname + '/public',
debug: css.debug,
compile: compiler
})); |
Enable gzip compression is for production mode only | app.use(gzippo.staticGzip(__dirname + '/public', { maxAge: cacheAge })); |
Disable stack error output | app.set('showStackError', false); |
Enable view caching | app.enable('view cache');
}); |
Dynamic View Helpers | app.dynamicHelpers({
request: function(req) {
return req;
},
base: function() { |
Return the app's mount-point so that urls can adjust | return '/' === app.route ? '' : app.route;
}, |
messages: require('express-messages'), | |
dateformat: function(req, res) {
return require('./lib/dateformat').strftime;
},
loggedIn: function(req) {
if (req.session.auth) {
return true;
} else {
return false;
}
},
cacheBusting: function() {
return cacheBusting;
},
user: function (req, res) {
return req.session.auth;
},
access: function (req, res) {
return function(groupName) {
if(this.loggedIn) {
if(typeof groupName === "undefined") {
return false;
} else {
if(this.loggedIn && this.user !== "undefined") {
if(typeof this.user._group === "undefined") {
return false;
} else {
if(typeof this.user._group.name !== "undefined") {
if(groupName instanceof Array) {
var _ = require('underscore');
if(_.indexOf(groupName, this.user._group.name) !== -1) {
return true;
} else {
return false;
}
} else {
if((groupName === this.user.group_name) || (groupName === "Super Admin")) {
return true;
} else {
return false;
}
}
} else {
return false;
}
}
} else {
return false;
}
}
} else {
return false;
}
};
}, | |
Generate token using
express-csrf
and in your Jade view use the following:
| csrf: csrf.token
});
}; |
Error Configuration | exports.bootErrorConfig = function(app) { |
Since this is the last non-error-handling middleware use()d, we assume 404, as nothing else responded. | app.use(function(req, res, next) { |
The status option, or res.statusCode = 404 are equivalent, however with the option we get the "status" local available as well | res.render('404', {
layout: false,
status: 404,
title: 'Page not found :('
});
}); |
| app.use(function(err, req, res, next) { |
We may use properties of the error object here and next(err) appropriately, or if we possibly recovered from the error, simply next(). | res.render('500', {
layout: false,
status: err.status || 500,
error: err,
showStack: app.settings.showStackError,
title: 'Something went wrong, oops!'
});
});
}; |
Load Routes | exports.bootRoutes = function(app, db) {
var dir = __dirname + '/routes';
fs.readdirSync(dir).forEach(function(file) {
var path = dir + '/' + file;
require(dir + '/' + file)(app, db);
});
};
|