tellform/config/express.js
2016-11-02 12:11:41 -07:00

315 lines
8.3 KiB
JavaScript
Executable file

'use strict';
/**
* Module dependencies.
*/
var fs = require('fs-extra'),
http = require('http'),
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'),
multer = require('multer'),
passport = require('passport'),
raven = require('raven'),
MongoStore = require('connect-mongo')(session),
flash = require('connect-flash'),
config = require('./config'),
consolidate = require('consolidate'),
path = require('path'),
device = require('express-device'),
client = new raven.Client(config.DSN),
connect = require('connect');
var mongoose = require('mongoose');
/**
* Configure Socket.io
*/
var configureSocketIO = function (app, db) {
// Load the Socket.io configuration
var server = require('./socket.io')(app, db);
// Return server object
return server;
};
module.exports = function(db) {
// Initialize express app
var app = express();
var url = require('url');
// Globbing model files
config.getGlobbedFiles('./app/models/**/*.js').forEach(function(modelPath) {
require(path.resolve(modelPath));
});
// Setting application local variables
app.locals.google_analytics_id = config.app.google_analytics_id;
app.locals.title = config.app.title;
app.locals.signupDisabled = config.signupDisabled;
app.locals.description = config.app.description;
app.locals.keywords = config.app.keywords;
app.locals.socketPort = config.socketPort;
app.locals.bowerJSFiles = config.getBowerJSAssets();
app.locals.bowerCssFiles = config.getBowerCSSAssets();
app.locals.bowerOtherFiles = config.getBowerOtherAssets();
app.locals.jsFiles = config.getJavaScriptAssets();
app.locals.formJSFiles = config.getFormJavaScriptAssets();
app.locals.cssFiles = config.getCSSAssets();
app.use(function (req, res, next) {
var User = mongoose.model('User');
var path = '/' + 'subdomain' + '/';
var subdomains = req.subdomains;
var host = req.hostname;
if(subdomains.slice(0, 4).join('.')+'' === '1.0.0.127'){
subdomains = subdomains.slice(4);
}
// continue if no subdomains
if (!subdomains.length) return next();
var urlPath = url.parse(req.url).path.split('/');
if(urlPath.indexOf('static') > -1){
//console.log("STATIC FILE\n\n\n\n");
urlPath.splice(1,1);
req.root = 'https://' + config.baseUrl + urlPath.join('/');
console.log(req.root);
return next();
}
if(urlPath.indexOf('users') > -1 && urlPath.indexOf('me') > -1){
return next();
}
if(subdomains.indexOf('stage') > -1 || subdomains.indexOf('admin') > -1){
return next();
}
console.log(req.subdomains.reverse()[0]);
//console.log("is api subdomain: "+ (subdomains.indexOf("api") > -1));
//console.log(req.url);
if(subdomains.indexOf('api') > -1){
// rebuild url
path += 'api' + req.url;
console.log(req.url);
// TODO: check path and query strings are preserved
// reassign url
req.url = path;
console.log(req.url);
return next();
}
User.findOne({username: req.subdomains.reverse()[0]}).exec(function (err, user) {
if (err) {
console.log(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
path += subdomains.join('/') + req.url;
// TODO: check path and query strings are preserved
// reassign url
console.log("path: "+path);
req.url = path;
req.userId = user._id;
console.log('\n\n\ngot subdomain: '+ req.subdomains.reverse()[0]);
// Q.E.D.
next();
});
});
//Setup Prerender.io
app.use(require('prerender-node').set('prerenderToken', process.env.PRERENDER_TOKEN));
// Passing the request url to environment locals
app.use(function(req, res, next) {
if(config.baseUrl === ''){
config.baseUrl = req.protocol + '://' + req.headers.host;
}
res.locals.url = req.protocol + '://' + req.headers.host + req.url;
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
level: 3
}));
// 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)
app.use(morgan(logger.getLogFormat(), logger.getLogOptions()));
// 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({
extended: true
}));
app.use(bodyParser.json());
app.use(methodOverride());
// Use helmet to secure Express headers
app.use(helmet.xframe());
app.use(helmet.xssFilter());
app.use(helmet.nosniff());
app.use(helmet.ienoopen());
app.disable('x-powered-by');
// Setting the app router and static folder
app.use('/static', express.static(path.resolve('./public')));
app.use('/uploads', express.static(path.resolve('./uploads')));
// CookieParser should be above session
app.use(cookieParser());
// Express MongoDB session storage
app.use(session({
saveUninitialized: true,
resave: true,
secret: config.sessionSecret,
store: new MongoStore({
mongooseConnection: db.connection,
collection: config.sessionCollection
}),
cookie: config.sessionCookie,
name: config.sessionName
}));
// 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);
});
// Add headers for Sentry
app.use(function (req, res, next) {
// Website you wish to allow to connect
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();
});
// Sentry (Raven) middleware
app.use(raven.middleware.express.requestHandler(config.DSN));
// Should come before any other error middleware
app.use(raven.middleware.express.errorHandler(config.DSN));
// 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();
// Log it
console.error(err.stack);
client.captureError(err);
// 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'));
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;
}
app = configureSocketIO(app, db);
// Return Express server instance
return app;
};