tracman-server/server.js

197 lines
4.7 KiB
JavaScript
Executable File

/* IMPORTS */
const express = require('express')
const bodyParser = require('body-parser')
const expressValidator = require('express-validator')
const cookieParser = require('cookie-parser')
const cookieSession = require('cookie-session')
const debug = require('debug')('tracman-server')
const mongoose = require('mongoose')
const nunjucks = require('nunjucks')
const passport = require('passport')
const flash = require('connect-flash-plus')
const env = require('./config/env/env.js')
const User = require('./config/models.js').user
const mail = require('./config/mail.js')
const demo = require('./config/demo.js')
const app = express()
const http = require('http').Server(app)
const io = require('socket.io')(http)
const sockets = require('./config/sockets.js')
/* SETUP */ {
/* Database */ {
// Setup with native ES6 promises
mongoose.Promise = global.Promise;
// Connect to database
mongoose.connect(env.mongoSetup, {
server:{socketOptions:{
keepAlive:1, connectTimeoutMS:30000 }},
replset:{socketOptions:{
keepAlive:1, connectTimeoutMS:30000 }}
})
.then( () => { console.log(`💿 Mongoose connected to mongoDB`); })
.catch( (err) => { console.error(`${err.stack}`); });
}
/* Templates */ {
nunjucks.configure(__dirname+'/views', {
autoescape: true,
express: app
})
app.set('view engine','html')
}
/* Session */ {
app.use(cookieParser(env.cookie))
app.use(cookieSession({
cookie: {maxAge:60000},
secret: env.session,
saveUninitialized: true,
resave: true
}))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))
app.use(expressValidator())
app.use(flash())
}
/* Auth */ {
require('./config/passport.js')(passport);
app.use(passport.initialize());
app.use(passport.session());
}
/* Routes */ {
// Static files (keep this before default locals)
app.use('/static', express.static( __dirname+'/static', {dotfiles:'allow'} ));
// Default locals available to all views (keep this after static files)
app.get( '*', (req,res,next)=>{
// Path for redirects
let nextPath = ((req.query.next)?req.query.next: req.path.substring(0,req.path.indexOf('#')) || req.path );
if ( nextPath.substring(0,6)!=='/login' && nextPath.substring(0,7)!=='signup' && nextPath.substring(0,7)!=='/logout' && nextPath.substring(0,7)!=='/static' && nextPath.substring(0,6)!=='/admin' ){
req.session.next = nextPath+'#';
debug(`Set redirect path to ${nextPath}#`);
}
// User account
res.locals.user = req.user;
// Flash messages
res.locals.successes = req.flash('success');
res.locals.dangers = req.flash('danger');
res.locals.warnings = req.flash('warning');
next();
} );
// Auth routes
require('./config/routes/auth.js')(app, passport);
// Main routes
app.use( '/', require('./config/routes/index.js') );
// Contact form
app.use( '/contact', require('./config/routes/contact.js') );
// Settings
app.use( '/settings', require('./config/routes/settings.js') );
// Map
app.use( ['/map','/trac'], require('./config/routes/map.js') );
// Site administration
app.use( '/admin', require('./config/routes/admin.js') );
// Testing
if (env.mode == 'development') {
app.use( '/test', require('./config/routes/test.js' ) );
}
}
/* Errors */ {
// Catch-all for 404s
app.use( (req,res,next)=>{
if (!res.headersSent) {
var err = new Error(`Not found: ${req.url}`);
err.status = 404;
next(err);
}
} );
// Production handlers
if (env.mode!=='development') {
app.use( (err,req,res,next)=>{
if (err.status!==404&&err.status!==401){ console.error(`${err.stack}`); }
if (res.headersSent) { return next(err); }
res.status(err.status||500);
res.render('error', {
code: err.status||500,
message: (err.status<=499)?err.message:"Server error"
});
} );
}
// Development handlers
else {
app.use( (err,req,res,next)=>{
if (err.status!==404) { console.error(`${err.stack}`); }
if (res.headersSent) { return next(err); }
res.status(err.status||500);
res.render('error', {
code: err.status||500,
message: err.message,
stack: err.stack
});
} );
}
}
/* Sockets */ {
sockets.init(io);
}
}
/* RUNTIME */ {
console.log('🖥 Starting Tracman server...');
// Test SMTP server
mail.verify();
// Listen
http.listen( env.port, ()=>{
console.log(`🌐 Listening in ${env.mode} mode on port ${env.port}... `);
// Check for clients for each user
User.find({})
.then( (users)=>{
users.forEach( (user)=>{
sockets.checkForUsers( io, user.id );
});
})
.catch( (err)=>{
console.error(`${err.stack}`);
});
// Start transmitting demo
demo(io);
});
}
module.exports = app;