tellform/config/express.js

330 lines
8.7 KiB
JavaScript
Raw Normal View History

2015-06-29 22:51:29 +00:00
'use strict';
/**
* Module dependencies.
*/
var fs = require('fs-extra'),
https = require('https'),
express = require('express'),
morgan = require('morgan'),
logger = require('./logger'),
bodyParser = require('body-parser'),
session = require('express-session'),
compression = require('compression'),
methodOverride = require('method-override'),
cookieParser = require('cookie-parser'),
helmet = require('helmet'),
passport = require('passport'),
2015-07-13 22:11:40 +00:00
raven = require('raven'),
2016-04-21 20:25:29 +00:00
MongoStore = require('connect-mongo')(session),
2015-06-29 22:51:29 +00:00
flash = require('connect-flash'),
config = require('./config'),
consolidate = require('consolidate'),
path = require('path'),
device = require('express-device'),
client = new raven.Client(config.DSN);
2016-06-09 03:32:33 +00:00
var mongoose = require('mongoose');
2015-06-29 22:51:29 +00:00
2016-06-07 00:37:09 +00:00
/**
* Configure Socket.io
*/
var configureSocketIO = function (app, db) {
// Load the Socket.io configuration
var server = require('./socket.io')(app, db);
2015-08-07 21:02:44 +00:00
2016-06-07 00:37:09 +00:00
// Return server object
return server;
};
2015-07-13 22:11:40 +00:00
2015-06-29 22:51:29 +00:00
module.exports = function(db) {
// Initialize express app
var app = express();
2016-06-09 03:32:33 +00:00
var url = require('url');
2016-05-10 07:25:00 +00:00
2016-04-11 23:12:05 +00:00
// Globbing model files
config.getGlobbedFiles('./app/models/**/*.js').forEach(function(modelPath) {
require(path.resolve(modelPath));
});
2015-06-29 22:51:29 +00:00
// Setting application local variables
2016-04-24 18:41:27 +00:00
app.locals.google_analytics_id = config.app.google_analytics_id;
2015-06-29 22:51:29 +00:00
app.locals.title = config.app.title;
2016-05-10 07:25:00 +00:00
app.locals.signupDisabled = config.signupDisabled;
2015-06-29 22:51:29 +00:00
app.locals.description = config.app.description;
app.locals.keywords = config.app.keywords;
2017-03-28 00:04:03 +00:00
app.locals.subdomainsDisabled = config.subdomainsDisabled;
2017-08-02 22:46:11 +00:00
if(config.socketPort && process.env.NODE_ENV !== 'production'){
app.locals.socketPort = config.socketPort;
}
2017-03-27 20:32:06 +00:00
if(config.socketUrl){
app.locals.socketUrl = config.socketUrl;
}
app.locals.bowerJSFiles = config.getBowerJSAssets();
app.locals.bowerCssFiles = config.getBowerCSSAssets();
app.locals.bowerOtherFiles = config.getBowerOtherAssets();
2015-06-29 22:51:29 +00:00
app.locals.jsFiles = config.getJavaScriptAssets();
2016-06-09 03:32:33 +00:00
app.locals.formJSFiles = config.getFormJavaScriptAssets();
2015-06-29 22:51:29 +00:00
app.locals.cssFiles = config.getCSSAssets();
2016-06-09 03:32:33 +00:00
app.use(function (req, res, next) {
var urlPath;
2017-03-28 00:04:03 +00:00
if(!config.subdomainsDisabled) {
var User = mongoose.model('User');
var subdomainPath = '/subdomain/';
2017-03-28 00:04:03 +00:00
var subdomains = req.subdomains;
2017-03-28 00:04:03 +00:00
if (subdomains.slice(0, 4).join('.') + '' === '1.0.0.127') {
subdomains = subdomains.slice(4);
2016-06-09 03:32:33 +00:00
}
2017-03-28 00:04:03 +00:00
// continue if no subdomains
if (!subdomains.length) {
return next();
}
urlPath = url.parse(req.url).path.split('/');
2017-03-28 00:04:03 +00:00
if (urlPath.indexOf('static') > -1) {
urlPath.splice(1, 1);
if(process.env.NODE_ENV === 'development'){
2017-03-28 00:04:03 +00:00
req.root = req.protocol + '://' + config.baseUrl + ':' + config.port + urlPath.join('/');
} else {
req.root = req.protocol + '://' + config.baseUrl + urlPath.join('/');
}
return next();
2016-06-09 03:32:33 +00:00
}
2017-03-28 00:04:03 +00:00
if (urlPath.indexOf('users') > -1 && urlPath.indexOf('me') > -1) {
return next();
}
2016-06-09 03:32:33 +00:00
2017-03-28 00:04:03 +00:00
if (subdomains.indexOf('stage') > -1 || subdomains.indexOf('admin') > -1) {
return next();
}
2016-06-09 03:32:33 +00:00
2017-03-28 00:04:03 +00:00
if (subdomains.indexOf('api') > -1) {
// rebuild url
subdomainPath += 'api' + req.url;
2017-03-28 00:04:03 +00:00
// TODO: check path and query strings are preserved
// reassign url
req.url = subdomainPath;
2017-03-28 00:04:03 +00:00
return next();
}
2017-03-27 20:32:06 +00:00
2017-03-28 00:04:03 +00:00
User.findOne({username: req.subdomains.reverse()[0]}).exec(function (err, user) {
if (err) {
req.subdomains = null;
// Error page
return res.status(404).render('404', {
error: 'Page Does Not Exist'
});
}
if (user === null) {
// Error page
return res.status(404).render('404', {
error: 'Page Does Not Exist'
});
}
// rebuild url
subdomainPath += subdomains.join('/') + req.url;
2017-03-28 00:04:03 +00:00
// TODO: check path and query strings are preserved
// reassign url
req.url = subdomainPath;
2017-03-28 00:04:03 +00:00
req.userId = user._id;
// Q.E.D.
return next();
2017-03-28 00:04:03 +00:00
});
} else {
urlPath = url.parse(req.url).path.split('/');
2017-03-28 00:04:03 +00:00
if (urlPath.indexOf('static') > -1 && urlPath.indexOf('view') === urlPath.indexOf('static')-1) {
urlPath.splice(1, 1);
req.url = urlPath.join('/');
}
2016-06-09 03:32:33 +00:00
2017-03-28 00:04:03 +00:00
return next();
}
2016-06-09 03:32:33 +00:00
});
2016-04-23 04:00:44 +00:00
//Setup Prerender.io
app.use(require('prerender-node').set('prerenderToken', process.env.PRERENDER_TOKEN));
2016-05-10 07:25:00 +00:00
2017-04-11 07:10:36 +00:00
2015-06-29 22:51:29 +00:00
// Passing the request url to environment locals
app.use(function(req, res, next) {
2015-07-27 18:11:43 +00:00
if(config.baseUrl === ''){
config.baseUrl = req.protocol + '://' + req.headers.host;
}
res.locals.url = req.protocol + '://' + req.headers.host + req.url;
2015-06-29 22:51:29 +00:00
next();
});
// Should be placed before express.static
app.use(compression({
// only compress files for the following content types
filter: function(req, res) {
return (/json|text|javascript|css/).test(res.getHeader('Content-Type'));
},
// zlib option for compression level
2017-04-11 07:10:36 +00:00
level: 9
2015-06-29 22:51:29 +00:00
}));
// Showing stack errors
app.set('showStackError', true);
// Set swig as the template engine
app.engine('server.view.html', consolidate[config.templateEngine]);
// Set views path and view engine
app.set('view engine', 'server.view.html');
app.set('views', './app/views');
// Enable logger (morgan)
2017-07-20 23:09:21 +00:00
app.use(morgan(logger.getLogFormat(), logger.getMorganOptions()));
2015-06-29 22:51:29 +00:00
// Environment dependent middleware
if (process.env.NODE_ENV === 'development') {
// Disable views cache
app.set('view cache', false);
} else if (process.env.NODE_ENV === 'production') {
app.locals.cache = 'memory';
}
// Request body parsing middleware should be above methodOverride
app.use(bodyParser.urlencoded({
2017-03-06 19:43:42 +00:00
extended: true,
limit: '100mb'
2015-06-29 22:51:29 +00:00
}));
2017-03-06 19:43:42 +00:00
app.use(bodyParser.json({ limit: '100mb' }));
2015-06-29 22:51:29 +00:00
app.use(methodOverride());
2016-03-30 03:45:16 +00:00
// Use helmet to secure Express headers
app.use(helmet.frameguard());
2016-03-30 03:45:16 +00:00
app.use(helmet.xssFilter());
app.use(helmet.noSniff());
app.use(helmet.ieNoOpen());
app.use(helmet.dnsPrefetchControl());
app.use(helmet.hidePoweredBy());
2016-03-30 03:45:16 +00:00
2016-05-10 07:25:00 +00:00
2015-06-29 22:51:29 +00:00
// Setting the app router and static folder
2016-06-09 03:32:33 +00:00
app.use('/static', express.static(path.resolve('./public')));
2015-07-27 18:11:43 +00:00
app.use('/uploads', express.static(path.resolve('./uploads')));
2015-06-29 22:51:29 +00:00
// CookieParser should be above session
app.use(cookieParser());
// Express MongoDB session storage
2016-05-05 10:00:24 +00:00
2015-06-29 22:51:29 +00:00
app.use(session({
saveUninitialized: true,
resave: true,
secret: config.sessionSecret,
2015-11-05 22:07:56 +00:00
store: new MongoStore({
mongooseConnection: db.connection,
collection: config.sessionCollection
}),
2015-06-29 22:51:29 +00:00
cookie: config.sessionCookie,
2015-11-03 19:55:11 +00:00
name: config.sessionName
2015-06-29 22:51:29 +00:00
}));
2016-05-10 07:25:00 +00:00
2016-04-11 23:12:05 +00:00
// use passport session
app.use(passport.initialize());
app.use(passport.session());
// setup express-device
app.use(device.capture({ parseUserAgent: true }));
// connect flash for flash messages
app.use(flash());
// Globbing routing files
config.getGlobbedFiles('./app/routes/**/*.js').forEach(function(routePath) {
require(path.resolve(routePath))(app);
});
2015-06-29 22:51:29 +00:00
2016-05-10 07:25:00 +00:00
// Add headers for Sentry
2016-06-07 00:37:09 +00:00
2015-08-07 21:02:44 +00:00
app.use(function (req, res, next) {
// Website you wish to allow to connect
2016-06-07 00:37:09 +00:00
res.setHeader('Access-Control-Allow-Origin', 'https://sentry.polydaic.com');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
2016-06-07 00:37:09 +00:00
// Sentry (Raven) middleware
2016-06-09 03:32:33 +00:00
app.use(raven.middleware.express.requestHandler(config.DSN));
// Should come before any other error middleware
2016-06-09 03:32:33 +00:00
app.use(raven.middleware.express.errorHandler(config.DSN));
2015-06-29 22:51:29 +00:00
// Assume 'not found' in the error msgs is a 404. this is somewhat silly, but valid, you can do whatever you like, set properties, use instanceof etc.
app.use(function(err, req, res, next) {
// If the error object doesn't exists
if (!err) {
return next();
}
2015-06-29 22:51:29 +00:00
// Log it
client.captureError(err);
2015-06-29 22:51:29 +00:00
// Error page
res.status(500).render('500', {
error: err.stack
});
});
// Assume 404 since no middleware responded
app.use(function(req, res) {
client.captureError(new Error('Page Not Found'));
2015-06-29 22:51:29 +00:00
res.status(404).render('404', {
url: req.originalUrl,
error: 'Not Found'
});
});
if (process.env.NODE_ENV === 'secure') {
// Load SSL key and certificate
var privateKey = fs.readFileSync('./config/sslcerts/key.pem', 'utf8');
var certificate = fs.readFileSync('./config/sslcerts/cert.pem', 'utf8');
// Create HTTPS Server
var httpsServer = https.createServer({
key: privateKey,
cert: certificate
}, app);
// Return HTTPS server instance
return httpsServer;
}
2016-06-09 03:32:33 +00:00
2016-06-07 00:37:09 +00:00
app = configureSocketIO(app, db);
2015-06-29 22:51:29 +00:00
// Return Express server instance
return app;
};