@tiwarivikram/meanio
Version:
Extracted functionality for MEAN.io
192 lines (166 loc) • 5.61 kB
JavaScript
var express = require('express')
var cookieParser = require('cookie-parser')
var expressValidator = require('express-validator')
var methodOverride = require('method-override')
var http = require('http')
var https = require('https')
var fs = require('fs')
var ServerEngine = require('./engine')
var Grid = require('gridfs-stream')
var errorHandler = require('errorhandler')
var morgan = require('morgan')
var passport = require('passport')
var expressJwt = require('express-jwt')
var sticky = require('socketio-sticky-session')
function ExpressEngine () {
ServerEngine.call(this)
this.app = null
this.db = null
this.mean = null
}
ExpressEngine.prototype = Object.create(ServerEngine, {
constructor: {
value: ExpressEngine,
configurable: false,
writable: false,
enumerable: false
}
})
ExpressEngine.prototype.destroy = function () {
this.mean = null
this.db = null
this.app = null
ServerEngine.prototype.destroy.call(this)
}
ExpressEngine.prototype.name = function () {
return 'express'
}
ExpressEngine.prototype.initApp = function () {
var config = this.mean.getConfig()
this.app.use(function (req, res, next) {
res.setHeader('X-Powered-By', 'Mean.io')
next()
})
// The cookieParser should be above session
this.app.use(cookieParser())
// Request body parsing middleware should be above methodOverride
this.app.use(expressValidator())
this.app.use(methodOverride())
// We are going to protect /api routes with JWT
this.app.use('/api', expressJwt({
secret: config.secret,
credentialsRequired: false
}), function (req, res, next) {
if (req.user) req.user = JSON.parse(decodeURI(req.user))
next()
})
this.app.use(passport.initialize())
this.app.use(passport.session())
this.mean.register('passport', passport)
require(process.cwd() + '/config/express')(this.app, this.db)
return this.app
}
ExpressEngine.prototype.beginBootstrap = function (meanioinstance, database) {
this.mean = meanioinstance
this.db = database.connection
var config = meanioinstance.getConfig()
// Express settings
var app = express()
app.useStatic = function (a, b) {
if (typeof b === 'undefined') {
this.use(express.static(a))
} else {
this.use(a, express.static(b))
}
}
this.app = app
// Register app dependency;
meanioinstance.register('app', this.initApp.bind(this))
var gfs = new Grid(this.db.connection.db, this.db.mongo)
function themeHandler (req, res) {
res.setHeader('content-type', 'text/css')
gfs.files.findOne({
filename: 'theme.css'
}, function (err, file) {
if (!file) {
fs.createReadStream(config.root + '/bower_components/bootstrap/dist/css/bootstrap.css').pipe(res)
} else {
// streaming to gridfs
var readstream = gfs.createReadStream({
filename: 'theme.css'
})
// error handling, e.g. file does not exist
readstream.on('error', function (err) {
console.log('An error occurred!', err.message)
throw err
})
readstream.pipe(res)
}
})
}
// We override this file to allow us to swap themes
// We keep the same public path so we can make use of the bootstrap assets
app.get('/bower_components/bootstrap/dist/css/bootstrap.css', themeHandler)
// Listen on http.port (or port as fallback for old configs)
var httpServer = http.createServer(app)
meanioinstance.register('http', httpServer)
var stickyOptions = config.stickyOptions
if (config.clusterSticky && (process.env.NODE_ENV !== 'test') && (process.env.NODE_ENV !== 'development')) {
sticky(stickyOptions, httpServer).listen(config.http ? config.http.port : config.port)
} else {
httpServer.listen(config.http ? config.http.port : config.port)
}
if (config.https && config.https.port) {
var httpsOptions = {
key: fs.readFileSync(config.https.ssl.key),
cert: fs.readFileSync(config.https.ssl.cert),
ca: fs.readFileSync(config.https.ssl.ca)
}
var httpsServer = https.createServer(httpsOptions, app)
meanioinstance.register('https', httpsServer)
if (config.clusterSticky && (process.env.NODE_ENV !== 'test') && (process.env.NODE_ENV !== 'development')) {
sticky(stickyOptions, httpsServer).listen(config.https.port)
} else {
httpServer.listen(config.https.port)
}
}
meanioinstance.name = config.app.name
meanioinstance.app = app
meanioinstance.menus = new (meanioinstance.Menus)()
}
function finalRouteHandler (req, res, next) {
if (!this.template) return next()
this.template(req, res, next)
}
function NotFoundHandler (err, req, res, next) {
// Treat as 404
if (~err.message.indexOf('not found')) return next()
// Log it
console.error(err.stack)
// Error page
res.status(500).render('500', {
error: err.stack
})
}
function FourOFourHandler (req, res) {
res.status(404).render('404', {
url: req.originalUrl,
error: 'Not found'
})
}
ExpressEngine.prototype.endBootstrap = function (callback) {
// We are going to catch everything else here
this.app.route('*').get(finalRouteHandler.bind(this))
// 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.
this.app.use(NotFoundHandler)
// Assume 404 since no middleware responded
this.app.use(FourOFourHandler)
// Error handler - has to be last
if (process.env.NODE_ENV === 'development') {
this.app.use(errorHandler())
}
callback(this)
}
module.exports = ExpressEngine