url: process.env.MONGODB || process.env.MONGOLAB_URI, autoReconnect: true }) })); app.use(passport.initialize()); app.use(passport.session()); app.use(flash()); app.use(function(req, res, next) { if (req.path === '/api/upload') { next(); } else { lusca.csrf()(req, res, next); } }); app.use(lusca.xframe('SAMEORIGIN')); app.use(lusca.xssProtection(true)); app.use(function(req, res, next) { res.locals.user = req.user; next(); }); app.use(function(req, res, next) { if (/api/i.test(req.path)) { req.session.returnTo = req.path; } next(); }); app.use(express.static(path.join(__dirname, 'public'), { maxAge: 31557600000 })); /** * Primary app routes. */
/** * Setups up authentication * * @method auth * @param {Object} obj Tenso instance * @param {Object} config Tenso configuration * @return {Object} Updated Tenso configuration */ function auth ( obj, config ) { var ssl = config.ssl.cert && config.ssl.key, proto = "http" + ( ssl ? "s" : "" ), realm = proto + "://" + ( config.hostname === "localhost" ? "127.0.0.1" : config.hostname ) + ( config.port !== 80 && config.port !== 443 ? ":" + config.port : "" ), async = ( config.auth.facebook.enabled || config.auth.google.enabled || config.auth.linkedin.enabled || config.auth.twitter.enabled ), stateless = ( config.auth.basic.enabled || config.auth.bearer.enabled ), stateful = ( async || config.auth.local.enabled || config.security.csrf ), authMap = {}, authUris = [], keys, sesh, fnCookie, fnSesh, luscaCsrf, luscaCsp, luscaXframe, luscaP3p, luscaHsts, luscaXssProtection, protection, passportAuth, passportInit, passportSession; function asyncFlag () { arguments[0].protectAsync = true; arguments[2](); } function init ( session ) { passportInit = passport.initialize(); obj.server.use( passportInit ).blacklist( passportInit ); if ( session ) { passportSession = passport.session(); obj.server.use( passportSession ).blacklist( passportSession ); } } function guard ( req, res, next ) { if ( req.isAuthenticated() ) { return next(); } else { res.redirect( "/login" ); } } function redirect () { arguments[1].redirect( config.auth.redirect ); } obj.server.blacklist( asyncFlag ); config.auth.protect = ( config.auth.protect || [] ).map( function ( i ) { return new RegExp( "^" + i !== "/login" ? i.replace( /\.\*/g, "*" ).replace( /\*/g, ".*" ) : "$", "i" ); } ); if ( async ) { iterate( config.auth, function ( v, k ) { if ( v.enabled ) { authMap[k + "_uri"] = "/auth/" + k; config.auth.protect.push( new RegExp( "^/auth/" + k ) ); } } ); } authUris = array.keys( authMap ); if ( config.auth.local.enabled ) { authUris.push( config.auth.redirect ); authUris.push( "/login" ); } if ( stateful ) { sesh = { secret: config.session.secret || uuid(), saveUninitialized: true, rolling: true, resave: true }; if ( config.session.store === "redis" ) { sesh.store = new RedisStore( config.session.redis ); } fnCookie = cookie(); fnSesh = session( sesh ); obj.server.use( fnSesh ).blacklist( fnSesh ); obj.server.use( fnCookie ).blacklist( fnCookie ); if ( config.security.csrf ) { luscaCsrf = lusca.csrf( {key: config.security.key} ); obj.server.use( luscaCsrf ).blacklist( luscaCsrf ); } } if ( config.security.csp instanceof Object ) { luscaCsp = lusca.csp( config.security.csp ); obj.server.use( luscaCsp ).blacklist( luscaCsp ); } if ( !string.isEmpty( config.security.xframe ) ) { luscaXframe = lusca.xframe( config.security.xframe ); obj.server.use( luscaXframe ).blacklist( luscaXframe ); } if ( !string.isEmpty( config.security.p3p ) ) { luscaP3p = lusca.p3p( config.security.p3p ); obj.server.use( luscaP3p ).blacklist( luscaP3p ); } if ( config.security.hsts instanceof Object ) { luscaHsts = lusca.hsts( config.security.hsts ); obj.server.use( luscaHsts ).blacklist( luscaHsts ); } if ( config.security.xssProtection instanceof Object ) { luscaXssProtection = lusca.xssProtection( config.security.xssProtection ); obj.server.use( luscaXssProtection ).blacklist( luscaXssProtection ); } protection = zuul( config.auth.protect ); obj.server.use( protection ).blacklist( protection ); if ( stateless && !stateful ) { init( false ); } else { init( true ); passport.serializeUser( function ( user, done ) { done( null, user ); } ); passport.deserializeUser( function ( obj, done ) { done( null, obj ); } ); if ( authUris.length > 0 ) { keys = array.keys( authMap ).length > 0; if ( keys ) { config.routes.get["/auth"] = authMap; } ( function () { var regex = "(?!/auth/("; array.each( authUris, function ( i ) { regex += i.replace( "_uri", "" ) + "|"; } ); regex = regex.replace( /\|$/, "" ) + ")).*$"; obj.server.use( regex, guard ).blacklist( guard ); } )(); config.routes.get["/login"] = config.auth.local.enabled ? ( keys ? {login_uri: "/auth", instruction: "POST 'username' & 'password' to authenticate"} : {instruction: "POST 'username' & 'password' to authenticate"} ) : {login_uri: "/auth"}; } else if ( config.auth.local.enabled ) { config.routes.get["/login"] = {instruction: "POST 'username' & 'password' to authenticate"}; } config.routes.get["/logout"] = function ( req, res ) { if ( req.session ) { req.session.destroy(); } res.redirect( config.auth.redirect ); }; } if ( config.auth.basic.enabled ) { (function () { var x = {}; function validate ( arg, cb ) { if ( x[arg] ) { cb( null, x[arg] ); } else { cb( new Error( "Unauthorized" ), null ); } } array.each( config.auth.basic.list || [], function ( i ) { var args = i.split( ":" ); if ( args.length > 0 ) { x[args[0]] = {password: args[1]}; } } ); passport.use( new BasicStrategy( function ( username, password, done ) { validate( username, function ( err, user ) { if ( err ) { delete err.stack; return done( err ); } if ( !user || user.password !== password ) { return done( null, false ); } return done( null, user ); } ); } ) ); passportAuth = passport.authenticate( "basic", {session: stateful} ); if ( async || config.auth.local.enabled ) { obj.server.get( "/auth/basic", passportAuth ).blacklist( passportAuth ); obj.server.get( "/auth/basic", redirect ); } else { obj.server.use( passportAuth ).blacklist( passportAuth ); } } )(); } if ( config.auth.bearer.enabled ) { ( function () { var x = config.auth.bearer.tokens || []; function validate ( arg, cb ) { if ( array.contains( x, arg ) ) { cb( null, arg ); } else { cb( new Error( "Unauthorized" ), null ); } } passport.use( new BearerStrategy( function ( token, done ) { validate( token, function ( err, user ) { if ( err ) { delete err.stack; return done( err ); } if ( !user ) { return done( null, false ); } return done( null, user, {scope: "read"} ); } ); } ) ); passportAuth = passport.authenticate( "bearer", {session: stateful} ); if ( async || config.auth.local.enabled ) { obj.server.get( "/auth/bearer", passportAuth ).blacklist( passportAuth ); obj.server.get( "/auth/bearer", redirect ); } else { obj.server.use( passportAuth ).blacklist( passportAuth ); } } )(); } if ( config.auth.facebook.enabled ) { passport.use( new FacebookStrategy( { clientID : config.auth.facebook.client_id, clientSecret: config.auth.facebook.client_secret, callbackURL : realm + "/auth/facebook/callback" }, function ( accessToken, refreshToken, profile, done ) { config.auth.facebook.auth( accessToken, refreshToken, profile, function ( err, user ) { if ( err ) { delete err.stack; return done( err ); } done( null, user ); } ); } ) ); obj.server.get( "/auth/facebook", asyncFlag ); obj.server.get( "/auth/facebook", passport.authenticate( "facebook" ) ); obj.server.get( "/auth/facebook/callback", asyncFlag ); obj.server.get( "/auth/facebook/callback", passport.authenticate( "facebook", {failureRedirect: "/login"} ) ); obj.server.get( "/auth/facebook/callback", redirect ); } if ( config.auth.google.enabled ) { passport.use( new GoogleStrategy( { returnURL: realm + "/auth/google/callback", realm : realm }, function ( identifier, profile, done ) { config.auth.google.auth.call( obj, identifier, profile, function ( err, user ) { if ( err ) { delete err.stack; return done( err ); } done( null, user ); } ); } ) ); obj.server.get( "/auth/google", asyncFlag ); obj.server.get( "/auth/google", passport.authenticate( "google" ) ); obj.server.get( "/auth/google/callback", asyncFlag ); obj.server.get( "/auth/google/callback", passport.authenticate( "google", {failureRedirect: "/login"} ) ); obj.server.get( "/auth/google/callback", redirect ); } if ( config.auth.linkedin.enabled ) { passport.use( new LinkedInStrategy( { consumerKey : config.auth.linkedin.client_id, consumerSecret: config.auth.linkedin.client_secret, callbackURL : realm + "/auth/linkedin/callback" }, function ( token, tokenSecret, profile, done ) { config.auth.linkedin.auth( token, tokenSecret, profile, function ( err, user ) { if ( err ) { delete err.stack; return done( err ); } done( null, user ); } ); } ) ); obj.server.get( "/auth/linkedin", asyncFlag ); obj.server.get( "/auth/linkedin", passport.authenticate( "linkedin", {"scope": config.auth.linkedin.scope || ["r_basicprofile", "r_emailaddress"]} ) ); obj.server.get( "/auth/linkedin/callback", asyncFlag ); obj.server.get( "/auth/linkedin/callback", passport.authenticate( "linkedin", {failureRedirect: "/login"} ) ); obj.server.get( "/auth/linkedin/callback", redirect ); } if ( config.auth.local.enabled ) { passport.use( new LocalStrategy( function( username, password, done ) { config.auth.local.auth( username, password, function ( err, user ) { if ( err ) { delete err.stack; return done( err ); } done( null, user ); } ); } ) ); config.routes.post = config.routes.post || {}; config.routes.post["/login"] = function ( req, res ) { var final, mid; final = function () { passport.authenticate( "local", {successRedirect: config.auth.redirect} )( req, res, function ( e ) { if ( e ) { res.error( 401, "Unauthorized" ); } } ); }; mid = function () { passportSession( req, res, final ); }; passportInit( req, res, mid ); }; } if ( config.auth.oauth2.enabled ) { passport.use( new OAuth2Strategy( { authorizationURL: config.auth.oauth2.auth_url, tokenURL : config.auth.oauth2.token_url, clientID : config.auth.oauth2.client_id, clientSecret : config.auth.oauth2.client_secret, callbackURL : realm + "/auth/oauth2/callback" }, function ( accessToken, refreshToken, profile, done ) { config.auth.oauth2.auth( accessToken, refreshToken, profile, function ( err, user ) { if ( err ) { delete err.stack; return done( err ); } done( null, user ); } ); } ) ); obj.server.get( "/auth/oauth2", asyncFlag ); obj.server.get( "/auth/oauth2", passport.authenticate( "oauth2" ) ); obj.server.get( "/auth/oauth2/callback", asyncFlag ); obj.server.get( "/auth/oauth2/callback", passport.authenticate( "oauth2", {failureRedirect: "/login"} ) ); obj.server.get( "/auth/oauth2/callback", redirect ); } if ( config.auth.saml.enabled ) { ( function () { var config = config.auth.saml; config.callbackURL = realm + "/auth/saml/callback"; delete config.enabled; delete config.path; passport.use( new SAMLStrategy( config, function ( profile, done ) { config.auth.saml.auth( profile, function ( err, user ) { if ( err ) { delete err.stack; return done( err ); } done( null, user ); } ); } ) ); } )(); obj.server.get( "/auth/saml", asyncFlag ); obj.server.get( "/auth/saml", passport.authenticate( "saml" ) ); obj.server.get( "/auth/saml/callback", asyncFlag ); obj.server.get( "/auth/saml/callback", passport.authenticate( "saml", {failureRedirect: "/login"} ) ); obj.server.get( "/auth/saml/callback", redirect ); } if ( config.auth.twitter.enabled ) { passport.use( new TwitterStrategy( { consumerKey : config.auth.twitter.consumer_key, consumerSecret: config.auth.twitter.consumer_secret, callbackURL : realm + "/auth/twitter/callback" }, function ( token, tokenSecret, profile, done ) { config.auth.twitter.auth( token, tokenSecret, profile, function ( err, user ) { if ( err ) { delete err.stack; return done( err ); } done( null, user ); } ); } ) ); obj.server.get( "/auth/twitter", asyncFlag ); obj.server.get( "/auth/twitter", passport.authenticate( "twitter" ) ); obj.server.get( "/auth/twitter/callback", asyncFlag ); obj.server.get( "/auth/twitter/callback", passport.authenticate( "twitter", {successRedirect: config.auth.redirect, failureRedirect: "/login"} ) ); } return config; }
secret: process.env.SESSION_SECRET || 'secret', resave: true, saveUninitialized: true}; if(false) sessionParams.cookie ={maxAge: 60000}; else sessionParams.store = new MongoStore({ mongooseConnection: mongoose.connection }); app.use(session(sessionParams)); app.use(passport.initialize()); app.use(passport.session()); app.use(flash()); // security middleware app.use(lusca.xframe('SAMEORIGIN')); // Enables X-FRAME-OPTIONS headers to help prevent Clickjacking. app.use(lusca.xssProtection(true)); // Enables X-XSS-Protection headers to help prevent cross site scripting (XSS) attacks in older IE browsers (IE8) app.use(function(req, res, next) { res.locals.user = req.user; next(); }); app.use(function(req, res, next) { if (/api/i.test(req.path)) { req.session.returnTo = req.path; } next(); }); /** * Primary app routes. */
function startHTTPServers() { // check the database is initialized or not var servers = new Array(); var errorhandler = function errorhandler(err, req, res, next) { console.error(err.stack); // emailService.sendSystemAlertNotifications(err.message, err.stack); if (err.domain) { try { //make sure we close down within 30 seconds var killtimer = setTimeout(function() { process.exit(1); }, 30000); // But don't keep the process open just for that! killtimer.unref(); // stop taking new requests. for (var i=0; i < servers.length; i++) { servers[i].close(); } // Let the master know we're dead. This will trigger a // 'disconnect' in the cluster master, and then it will fork // a new worker. cluster.worker.disconnect(); // try to send an error to the request that triggered the problem res.statusCode = 500; res.setHeader('content-type', 'text/plain'); res.end('Oops, there was a problem!\n'); } catch (er2) { // oh well, not much we can do at this point. console.error('Error sending 500!', er2.stack); } } } var httpServerConfig = setting.get('public-server'); if (httpServerConfig != null) { var app = express(); var httpServer = http.createServer(app); servers.push(httpServer); var sessionStore = new MongoStore({ url: httpServerConfig['session-store'], autoReconnect: true }); /** * Express configuration. */ app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); app.use(compress()); app.use(logger('dev')); app.use(expressValidator()); app.use(session({ resave:true, saveUninitialized:true, cookie: { path: '/', httpOnly: false, maxAge: null}, secret: "session_id", store: sessionStore })); app.use(flash()); app.use(function(req, res, next) { lusca.csrf()(req, res, next); }); app.use(lusca.xframe('SAMEORIGIN')); app.use(lusca.xssProtection(true)); app.use(function(req, res, next) { res.locals.user = req.user; next(); }); app.use(express.static(path.join(__dirname, 'public'), { maxAge: 31557600000 })); /** * Start Express server. */ var context = { app: app, cookieParser: cookieParser(httpServerConfig['cookie-secret']), errorhandler: errorhandler, express: express, mongoose: mongoose, session: session, sessionKey: 'session_id', sessionStore: sessionStore, bodyParser:bodyParser, //sio: io.listen(httpServer), path: path, } // Initialize Submodule require('./app/route/routes')(context); //require('./app/public/config/socket_io')(context); // Listen ports var httpPort = httpServerConfig['http-port']; httpServer.listen(httpPort); console.log("Public server listens port "+httpPort+"."); }; }
mongoose.connect(config.mongoose.url, function(err) { if (!err) { var Schema = mongoose.Schema; var userSchema = new Schema({ username: { type: String, required: true, trim: true }, twitch: { type: Object, required: true, trim: true } }); var User = mongoose.model('users', userSchema); function ensureAuthenticated(req, res, next) { if (req.isAuthenticated()) { return next(); } return res.redirect("/#/homepage"); } passport.serializeUser(function(user, done) { User.findOne({ username: user._json.display_name }, function(err, result) { if (result) { result.twitch = user._json; result.save(); } else { user.username = user._json.display_name; user.twitch = user._json; new User(user).save(function(err) {}); } }); done(null, user); }); passport.deserializeUser(function(obj, done) { User.findOne({ username: obj._json.display_name }, function(err, result) { if (result) { obj.active = result.active; } done(null, obj); }); }); passport.use(new strategy({ clientID: config.passport.clientID, clientSecret: config.passport.clientSecret, callbackURL: config.passport.callbackURL, scope: config.passport.scopes }, function(accessToken, refreshToken, profile, done) { process.nextTick(function() { return done(null, profile); }); } )); app.use(express.static(__dirname + '/public')); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); app.use(methodOverride()); app.set('views', __dirname + '/views'); app.engine('.html', require('ejs').renderFile); app.set('view engine', 'html'); app.set('view options', { layout: false }); app.use(express.Router()); var sessiondb = session({ store: new mongoSession({ url: config.mongoose.url, maxAge: 300000 }), resave: true, saveUninitialized: true, secret: config.security.sessionSecret, auto_reconnect: true, cookie: { httpOnly: true } }); app.use(sessiondb); app.use(passport.initialize()); app.use(passport.session()); if (config.security.csrf.enabled) { conditionalCSRF = function(req, res, next) { if (Boolean(config.security.csrf.freeRoutes[req.path])) { next(); } else { csrf(req, res, next); } } app.use(conditionalCSRF); } if (config.security.csp.enabled) { app.use(lusca.csp({ reportOnly: config.security.csp.reportOnly, reportUri: config.security.csp.reportUri, policy: { "connect-src": config.security.csp.policy['connect-src'], "default-src": config.security.csp.policy['default-src'], "font-src": config.security.csp.policy['font-src'], "frame-src": config.security.csp.policy['frame-src'], "object-src": config.security.csp.policy['object-src'], "script-src": config.security.csp.policy['script-src'], "style-src": config.security.csp.policy['style-src'] } })); } if (config.security.xframe.enabled) { app.use(lusca.xframe(config.security.xframe.value)); } if (config.security.p3p.enabled) { app.use(lusca.p3p(config.security.p3p.value)); } if (config.security.hsts.enabled) { app.use(lusca.hsts({ maxAge: config.security.hsts.maxAge, includeSubDomains: config.security.hsts.includeSubDomains })); } app.use(lusca.xssProtection(config.security.xssProtection)); if (config.livereload) { app.use(require('connect-livereload')({ port: 35729, ignore: ['.js', '.svg'] })); } app.use(function(err, req, res, next) { console.error(err.stack); res.redirect('/#/error'); }); app.get('/', function(req, res) { res.render('index.html'); }); app.get('/api/user', function(req, res) { res.send(req.isAuthenticated() ? req.user : {}); }); app.get('/auth/twitch', passport.authenticate('twitch', { scope: config.passport.scopes.split(',') }), function(req, res) { // }); app.get('/auth/twitch/callback', passport.authenticate('twitch', { failureRedirect: '/#/homepage' }), function(req, res) { res.redirect('/#/homepage'); }); app.get('/logout', function(req, res) { req.logout(); res.redirect('/#/homepage'); }); app.get('*', ensureAuthenticated, function(req, res) { res.render('index.html'); }); var server = app.listen(config.port, function() { console.log('Listening on port %d', server.address().port); }); } });
module.exports = function (app) { /** * Load environment variables from .env file, where API keys and passwords are configured. * * Default path: .env (You can remove the path argument entirely, after renaming `.env.example` to `.env`) */ if ((process.env.NODE_ENV || 'dev') === 'dev') { require('dotenv').load(); } /** * Express configuration. */ app.set('port', process.env.PORT || 3000); app.set('views', path.normalize(path.join(__dirname, '../views'))); app.set('view engine', 'jade'); app.use(compress()); app.use(sass({ src: path.normalize(path.join(__dirname, '../public')), dest: path.normalize(path.join(__dirname, '../public')), sourceMap: true })); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use(expressValidator()); app.use(session({ resave: true, saveUninitialized: true, secret: process.env.SESSION_SECRET, store: new MongoStore({ url: process.env.MONGOLAB_URI || process.env.MONGODB, autoReconnect: true }) })); app.use(passport.initialize()); app.use(passport.session()); app.use(flash()); app.use(lusca.xframe('SAMEORIGIN')); app.use(lusca.xssProtection(true)); app.use(function (req, res, next) { res.locals.user = req.user; next(); }); app.use(function (req, res, next) { // After successful login, redirect back to /api, /contact or / if (/(api)|(contact)|(^\/$)/i.test(req.path)) { req.session.returnTo = req.path; } next(); }); app.use(express.static(path.normalize(path.join(__dirname, '../public')), { maxAge: 31557600000 })); /** * Error Handler. */ app.use(errorHandler()); }