2016-05-31 21:54:21 -06:00
|
|
|
/* IMPORTS */ { var
|
2016-05-01 22:59:47 -06:00
|
|
|
express = require('express'),
|
2016-03-21 18:03:37 -06:00
|
|
|
bodyParser = require('body-parser'),
|
|
|
|
cookieParser = require('cookie-parser'),
|
|
|
|
session = require('express-session'),
|
|
|
|
mongoose = require('mongoose'),
|
|
|
|
nunjucks = require('nunjucks'),
|
|
|
|
passport = require('passport'),
|
|
|
|
flash = require('connect-flash'),
|
|
|
|
secret = require('./config/secrets.js'),
|
|
|
|
User = require('./config/models/user.js'),
|
|
|
|
app = express(),
|
|
|
|
http = require('http').Server(app),
|
2016-06-12 18:18:34 -06:00
|
|
|
// mongo_express = require('mongo-express/lib/middleware'),
|
2016-05-31 21:54:21 -06:00
|
|
|
io = require('socket.io')(http);
|
|
|
|
}
|
2016-03-31 20:38:45 -06:00
|
|
|
|
2016-05-31 21:54:21 -06:00
|
|
|
/* SETUP */ {
|
|
|
|
/* Database */ mongoose.connect(secret.mongoSetup, {
|
2016-05-01 22:59:47 -06:00
|
|
|
server:{socketOptions:{
|
|
|
|
keepAlive:1, connectTimeoutMS:30000 }},
|
|
|
|
replset:{socketOptions:{
|
|
|
|
keepAlive:1, connectTimeoutMS:30000 }}
|
|
|
|
});
|
|
|
|
|
2016-05-31 21:54:21 -06:00
|
|
|
/* Templates */ nunjucks.configure(__dirname+'/views', {
|
|
|
|
autoescape: true,
|
|
|
|
express: app
|
2016-05-01 22:59:47 -06:00
|
|
|
});
|
|
|
|
|
2016-05-31 21:54:21 -06:00
|
|
|
/* Session */ {
|
|
|
|
app.use(session({
|
|
|
|
secret: secret.session,
|
|
|
|
saveUninitialized: true,
|
|
|
|
resave: true
|
|
|
|
}));
|
|
|
|
app.use(bodyParser.json());
|
|
|
|
app.use(bodyParser.urlencoded({
|
|
|
|
extended: true
|
|
|
|
}));
|
|
|
|
app.use(cookieParser(secret.cookie));
|
|
|
|
app.use(flash());
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Auth */ {
|
|
|
|
app.use(passport.initialize());
|
|
|
|
app.use(passport.session());
|
|
|
|
require('./config/auth.js');
|
|
|
|
passport.serializeUser(function(user,done) {
|
|
|
|
done(null, user.id);
|
|
|
|
});
|
|
|
|
passport.deserializeUser(function(id,done) {
|
|
|
|
User.findById(id, function(err, user) {
|
|
|
|
if(!err) done(null, user);
|
|
|
|
else done(err, null);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Routes */ {
|
|
|
|
app.use('/',
|
|
|
|
require('./config/routes/index.js'),
|
|
|
|
require('./config/routes/auth.js'),
|
|
|
|
require('./config/routes/misc.js')
|
|
|
|
);
|
2016-06-12 18:56:37 -06:00
|
|
|
app.use(['/map','/trac'], require('./config/routes/map.js'));
|
2016-05-31 21:54:21 -06:00
|
|
|
app.use('/invited', require('./config/routes/invite.js'));
|
|
|
|
app.use('/admin', require('./config/routes/admin.js'));
|
|
|
|
app.use('/static', express.static(__dirname+'/static'));
|
2016-06-30 14:40:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Errors */ {
|
|
|
|
// Catch-all for 404s
|
2016-05-31 21:54:21 -06:00
|
|
|
app.use(function(req,res,next) {
|
|
|
|
if (!res.headersSent) {
|
|
|
|
var err = new Error('404: Not found: '+req.url);
|
|
|
|
err.status = 404;
|
|
|
|
next(err);
|
|
|
|
}
|
|
|
|
});
|
2016-06-30 14:40:21 -06:00
|
|
|
|
|
|
|
// Handlers
|
2016-05-31 21:54:21 -06:00
|
|
|
if (secret.env=='production') {
|
2016-05-01 22:59:47 -06:00
|
|
|
app.use(function(err,req,res,next) {
|
|
|
|
if (res.headersSent) { return next(err); }
|
|
|
|
res.status(err.status||500);
|
|
|
|
res.render('error.html', {
|
2016-05-31 21:54:21 -06:00
|
|
|
code: err.status
|
2016-05-01 22:59:47 -06:00
|
|
|
});
|
|
|
|
});
|
2016-06-30 14:40:21 -06:00
|
|
|
}
|
|
|
|
else /* Development */{
|
2016-05-01 22:59:47 -06:00
|
|
|
app.use(function(err,req,res,next) {
|
2016-05-31 21:54:21 -06:00
|
|
|
console.log(err);
|
2016-05-01 22:59:47 -06:00
|
|
|
if (res.headersSent) { return next(err); }
|
|
|
|
res.status(err.status||500);
|
|
|
|
res.render('error.html', {
|
2016-05-31 21:54:21 -06:00
|
|
|
code: err.status,
|
|
|
|
message: err.message,
|
|
|
|
error: err
|
2016-05-01 22:59:47 -06:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2016-03-21 18:03:37 -06:00
|
|
|
}
|
2016-05-01 22:59:47 -06:00
|
|
|
|
2016-03-21 18:03:37 -06:00
|
|
|
}
|
|
|
|
|
2016-05-31 21:54:21 -06:00
|
|
|
/* RUNTIME */ {
|
2016-06-12 18:18:34 -06:00
|
|
|
|
2016-05-01 22:59:47 -06:00
|
|
|
// Check for tracking users
|
|
|
|
function checkForUsers(room) {
|
|
|
|
if (room) {
|
|
|
|
io.to('app-'+room).emit('activate',
|
|
|
|
(io.of("/").adapter.rooms[room])?'true':'false'
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
User.find({}, function(err, users){
|
|
|
|
if (err) { console.log('Sockets error finding all users in all rooms: '+err); }
|
|
|
|
users.forEach( function(user){
|
|
|
|
checkForUsers(user.id);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2016-03-21 18:03:37 -06:00
|
|
|
|
2016-06-12 18:18:34 -06:00
|
|
|
// Websockets
|
|
|
|
io.on('connection', function(sock) {
|
2016-05-01 22:59:47 -06:00
|
|
|
|
2016-06-12 18:18:34 -06:00
|
|
|
// Set room to map user ID
|
|
|
|
sock.on('room', function(room) {
|
|
|
|
sock.join(room);
|
2016-05-01 22:59:47 -06:00
|
|
|
if (room.slice(0,4)!='app-'){
|
2016-06-12 18:18:34 -06:00
|
|
|
// External user
|
2016-05-01 22:59:47 -06:00
|
|
|
User.findById({_id:room}, function(err, user) {
|
|
|
|
if (err) { console.log('Sockets error finding tracked user of room '+room+'\n'+err); }
|
|
|
|
if (user) {
|
|
|
|
io.to('app-'+room).emit('activate','true'); }
|
|
|
|
});
|
2016-06-12 18:18:34 -06:00
|
|
|
} else { // Sets location
|
2016-05-01 22:59:47 -06:00
|
|
|
checkForUsers(room.slice(4));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-06-12 18:18:34 -06:00
|
|
|
// Recieving beacon
|
|
|
|
sock.on('app', function(loc){
|
2016-05-01 22:59:47 -06:00
|
|
|
loc.time = Date.now();
|
2016-06-12 18:18:34 -06:00
|
|
|
|
|
|
|
// Check for sk32 token
|
|
|
|
if (loc.tok) {
|
|
|
|
// Get loc.usr
|
|
|
|
User.findById(loc.usr, function(err, user) {
|
|
|
|
if (err) { console.log('Error finding user:',err); }
|
|
|
|
if (!user) { console.log('User not found'); }
|
|
|
|
else {
|
|
|
|
// Confirm sk32 token
|
|
|
|
if (loc.tok!=user.sk32) { console.log('loc.tok!=user.sk32 || ',loc.tok,'!=',user.sk32); }
|
|
|
|
else {
|
|
|
|
// Broadcast location to spectators
|
|
|
|
io.to(loc.usr).emit('trac', loc);
|
|
|
|
// Echo broadcast to transmittors
|
|
|
|
io.to('app-'+loc.usr).emit('trac', loc);
|
|
|
|
// Save in db as last seen
|
|
|
|
user.last = {
|
|
|
|
lat: parseFloat(loc.lat),
|
|
|
|
lon: parseFloat(loc.lon),
|
|
|
|
dir: parseFloat(loc.dir||0),
|
|
|
|
spd: parseFloat(loc.spd||0),
|
|
|
|
time: loc.time
|
|
|
|
};
|
|
|
|
user.save(function(err) {
|
|
|
|
if (err) { console.log('Error saving user last location:'+loc.user+'\n'+err); }
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2016-05-01 22:59:47 -06:00
|
|
|
});
|
2016-06-12 18:18:34 -06:00
|
|
|
|
|
|
|
// Shutdown (check for users)
|
|
|
|
sock.onclose = function(reason){
|
2016-05-01 22:59:47 -06:00
|
|
|
var closedroom = Object.keys(
|
2016-06-12 18:18:34 -06:00
|
|
|
sock.adapter.sids[sock.id]).slice(1)[0];
|
2016-05-01 22:59:47 -06:00
|
|
|
setTimeout(function() {
|
|
|
|
checkForUsers(closedroom);
|
|
|
|
}, 3000);
|
|
|
|
Object.getPrototypeOf(this).onclose.call(this,reason);
|
2016-06-12 18:18:34 -06:00
|
|
|
};
|
2016-05-01 22:59:47 -06:00
|
|
|
|
2016-03-21 18:03:37 -06:00
|
|
|
});
|
|
|
|
|
2016-05-01 22:59:47 -06:00
|
|
|
// Listen
|
|
|
|
http.listen(secret.port, function(){
|
2016-06-30 14:40:21 -06:00
|
|
|
console.log(
|
|
|
|
'==========================================\n'+
|
|
|
|
'Listening at '+secret.url+
|
|
|
|
'\n=========================================='
|
|
|
|
);
|
2016-05-01 22:59:47 -06:00
|
|
|
checkForUsers();
|
2016-03-21 18:03:37 -06:00
|
|
|
});
|
2016-05-01 22:59:47 -06:00
|
|
|
}
|
2016-03-21 18:03:37 -06:00
|
|
|
|
2016-03-31 20:38:45 -06:00
|
|
|
module.exports = app;
|