Add debug to app.js to troubleshoot twitter signin in production, unable to repliate locally

This commit is contained in:
brndnb
2015-04-14 15:36:02 -04:00
parent 6f752b2437
commit 4fb119ab68

497
app.js
View File

@ -15,45 +15,47 @@ process.on('uncaughtException', function (err) {
}); });
var express = require('express'), var express = require('express'),
accepts = require('accepts'), accepts = require('accepts'),
cookieParser = require('cookie-parser'), cookieParser = require('cookie-parser'),
compress = require('compression'), compress = require('compression'),
session = require('express-session'), session = require('express-session'),
logger = require('morgan'), logger = require('morgan'),
errorHandler = require('errorhandler'), errorHandler = require('errorhandler'),
methodOverride = require('method-override'), methodOverride = require('method-override'),
bodyParser = require('body-parser'), bodyParser = require('body-parser'),
helmet = require('helmet'), helmet = require('helmet'),
MongoStore = require('connect-mongo')(session), MongoStore = require('connect-mongo')(session),
flash = require('express-flash'), flash = require('express-flash'),
path = require('path'), path = require('path'),
mongoose = require('mongoose'), mongoose = require('mongoose'),
passport = require('passport'), passport = require('passport'),
expressValidator = require('express-validator'), expressValidator = require('express-validator'),
connectAssets = require('connect-assets'), connectAssets = require('connect-assets'),
request = require('request'), request = require('request'),
debug = require('debug')('freecc:app');
/**
* Controllers (route handlers).
*/
homeController = require('./controllers/home'),
challengesController = require('./controllers/challenges'),
resourcesController = require('./controllers/resources'),
userController = require('./controllers/user'),
contactController = require('./controllers/contact'),
bonfireController = require('./controllers/bonfire'),
coursewareController = require('./controllers/courseware'),
/** /**
* Stories * Controllers (route handlers).
*/ */
storyController = require('./controllers/story'), homeController = require('./controllers/home'),
challengesController = require('./controllers/challenges'),
resourcesController = require('./controllers/resources'),
userController = require('./controllers/user'),
contactController = require('./controllers/contact'),
bonfireController = require('./controllers/bonfire'),
coursewareController = require('./controllers/courseware'),
/** /**
* API keys and Passport configuration. * Stories
*/ */
secrets = require('./config/secrets'), storyController = require('./controllers/story'),
passportConf = require('./config/passport');
/**
* API keys and Passport configuration.
*/
secrets = require('./config/secrets'),
passportConf = require('./config/passport');
/** /**
* Create Express server. * Create Express server.
@ -65,9 +67,9 @@ var app = express();
*/ */
mongoose.connect(secrets.db); mongoose.connect(secrets.db);
mongoose.connection.on('error', function () { mongoose.connection.on('error', function () {
console.error( console.error(
'MongoDB Connection Error. Please make sure that MongoDB is running.' 'MongoDB Connection Error. Please make sure that MongoDB is running.'
); );
}); });
/** /**
@ -82,32 +84,32 @@ app.use(compress());
var oneYear = 31557600000; var oneYear = 31557600000;
app.use(express.static(__dirname + '/public', {maxAge: oneYear})); app.use(express.static(__dirname + '/public', {maxAge: oneYear}));
app.use(connectAssets({ app.use(connectAssets({
paths: [ paths: [
path.join(__dirname, 'public/css'), path.join(__dirname, 'public/css'),
path.join(__dirname, 'public/js') path.join(__dirname, 'public/js')
], ],
helperContext: app.locals helperContext: app.locals
})); }));
app.use(logger('dev')); app.use(logger('dev'));
app.use(bodyParser.json()); app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true})); app.use(bodyParser.urlencoded({extended: true}));
app.use(expressValidator({ app.use(expressValidator({
customValidators: { customValidators: {
matchRegex: function (param, regex) { matchRegex: function (param, regex) {
return regex.test(param); return regex.test(param);
}
} }
}
})); }));
app.use(methodOverride()); app.use(methodOverride());
app.use(cookieParser()); app.use(cookieParser());
app.use(session({ app.use(session({
resave: true, resave: true,
saveUninitialized: true, saveUninitialized: true,
secret: secrets.sessionSecret, secret: secrets.sessionSecret,
store: new MongoStore({ store: new MongoStore({
url: secrets.db, url: secrets.db,
'auto_reconnect': true 'auto_reconnect': true
}) })
})); }));
app.use(passport.initialize()); app.use(passport.initialize());
app.use(passport.session()); app.use(passport.session());
@ -118,107 +120,107 @@ app.use(helmet.xssFilter());
app.use(helmet.noSniff()); app.use(helmet.noSniff());
app.use(helmet.xframe()); app.use(helmet.xframe());
app.use(function(req, res, next) { app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next(); next();
}); });
var trusted = [ var trusted = [
"'self'", "'self'",
'*.freecodecamp.com', '*.freecodecamp.com',
'*.gstatic.com', '*.gstatic.com',
'*.google-analytics.com', '*.google-analytics.com',
'*.googleapis.com', '*.googleapis.com',
'*.google.com', '*.google.com',
'*.gstatic.com', '*.gstatic.com',
'*.doubleclick.net', '*.doubleclick.net',
'*.twitter.com', '*.twitter.com',
'*.twitch.tv', '*.twitch.tv',
'*.twimg.com', '*.twimg.com',
"'unsafe-eval'", "'unsafe-eval'",
"'unsafe-inline'", "'unsafe-inline'",
'*.rafflecopter.com', '*.rafflecopter.com',
'*.bootstrapcdn.com', '*.bootstrapcdn.com',
'*.cloudflare.com', '*.cloudflare.com',
'https://*.cloudflare.com', 'https://*.cloudflare.com',
'localhost:3001', 'localhost:3001',
'ws://localhost:3001/', 'ws://localhost:3001/',
'http://localhost:3001', 'http://localhost:3001',
'localhost:3000', 'localhost:3000',
'ws://localhost:3000/', 'ws://localhost:3000/',
'http://localhost:3000', 'http://localhost:3000',
'*.ionicframework.com', '*.ionicframework.com',
'https://syndication.twitter.com', 'https://syndication.twitter.com',
'*.youtube.com', '*.youtube.com',
'*.jsdelivr.net', '*.jsdelivr.net',
'https://*.jsdelivr.net', 'https://*.jsdelivr.net',
'*.togetherjs.com', '*.togetherjs.com',
'https://*.togetherjs.com', 'https://*.togetherjs.com',
'wss://hub.togetherjs.com', 'wss://hub.togetherjs.com',
'*.ytimg.com', '*.ytimg.com',
'wss://fcctogether.herokuapp.com', 'wss://fcctogether.herokuapp.com',
'*.bitly.com' '*.bitly.com'
]; ];
app.use(helmet.contentSecurityPolicy({ app.use(helmet.contentSecurityPolicy({
defaultSrc: trusted, defaultSrc: trusted,
scriptSrc: ['*.optimizely.com', '*.aspnetcdn.com'].concat(trusted), scriptSrc: ['*.optimizely.com', '*.aspnetcdn.com'].concat(trusted),
'connect-src': [ 'connect-src': [
'ws://*.rafflecopter.com', 'ws://*.rafflecopter.com',
'wss://*.rafflecopter.com', 'wss://*.rafflecopter.com',
'https://*.rafflecopter.com', 'https://*.rafflecopter.com',
'ws://www.freecodecamp.com', 'ws://www.freecodecamp.com',
'http://www.freecodecamp.com' 'http://www.freecodecamp.com'
].concat(trusted), ].concat(trusted),
styleSrc: trusted, styleSrc: trusted,
imgSrc: [ imgSrc: [
'*.evernote.com', '*.evernote.com',
'*.amazonaws.com', '*.amazonaws.com',
'data:', 'data:',
'*.licdn.com', '*.licdn.com',
'*.gravatar.com', '*.gravatar.com',
'*.akamaihd.net', '*.akamaihd.net',
'graph.facebook.com', 'graph.facebook.com',
'*.githubusercontent.com', '*.githubusercontent.com',
'*.googleusercontent.com', '*.googleusercontent.com',
'*' /* allow all input since we have user submitted images for public profile*/ '*' /* allow all input since we have user submitted images for public profile*/
].concat(trusted), ].concat(trusted),
fontSrc: ['*.googleapis.com'].concat(trusted), fontSrc: ['*.googleapis.com'].concat(trusted),
mediaSrc: [ mediaSrc: [
'*.amazonaws.com', '*.amazonaws.com',
'*.twitter.com' '*.twitter.com'
].concat(trusted), ].concat(trusted),
frameSrc: [ frameSrc: [
'*.gitter.im', '*.gitter.im',
'*.gitter.im https:', '*.gitter.im https:',
'*.vimeo.com', '*.vimeo.com',
'*.twitter.com', '*.twitter.com',
'*.rafflecopter.com', '*.rafflecopter.com',
'*.ghbtns.com' '*.ghbtns.com'
].concat(trusted), ].concat(trusted),
reportOnly: false, // set to true if you only want to report errors reportOnly: false, // set to true if you only want to report errors
setAllHeaders: false, // set to true if you want to set all headers setAllHeaders: false, // set to true if you want to set all headers
safari5: false // set to true if you want to force buggy CSP in Safari 5 safari5: false // set to true if you want to force buggy CSP in Safari 5
})); }));
app.use(function (req, res, next) { app.use(function (req, res, next) {
// Make user object available in templates. // Make user object available in templates.
res.locals.user = req.user; res.locals.user = req.user;
next(); next();
}); });
app.use(function (req, res, next) { app.use(function (req, res, next) {
// Remember original destination before login. // Remember original destination before login.
var path = req.path.split('/')[1]; var path = req.path.split('/')[1];
if (/auth|login|logout|signup|fonts|favicon/i.test(path)) { if (/auth|login|logout|signup|fonts|favicon/i.test(path)) {
return next(); return next();
} }
req.session.returnTo = req.path; req.session.returnTo = req.path;
next(); next();
}); });
app.use( app.use(
express.static(path.join(__dirname, 'public'), {maxAge: 31557600000}) express.static(path.join(__dirname, 'public'), {maxAge: 31557600000})
); );
app.use(express.static(__dirname + '/public', { maxAge: 86400000 })); app.use(express.static(__dirname + '/public', { maxAge: 86400000 }));
@ -243,23 +245,23 @@ app.get('/control-shortcuts', resourcesController.controlShortcuts);
app.get('/control-shortcuts', resourcesController.deployAWebsite); app.get('/control-shortcuts', resourcesController.deployAWebsite);
app.get('/nodeschool-challenges', resourcesController.nodeSchoolChallenges); app.get('/nodeschool-challenges', resourcesController.nodeSchoolChallenges);
app.get('/stats', function(req, res) { app.get('/stats', function(req, res) {
res.redirect(301, '/learn-to-code'); res.redirect(301, '/learn-to-code');
}); });
app.get('/news', function(req, res) { app.get('/news', function(req, res) {
res.redirect(301, '/stories/hot'); res.redirect(301, '/stories/hot');
}); });
app.get('/learn-to-code', resourcesController.about); app.get('/learn-to-code', resourcesController.about);
app.get('/about', function(req, res) { app.get('/about', function(req, res) {
res.redirect(301, '/learn-to-code'); res.redirect(301, '/learn-to-code');
}); });
app.get('/signin', userController.getSignin); app.get('/signin', userController.getSignin);
app.get('/login', function(req, res) { app.get('/login', function(req, res) {
res.redirect(301, '/signin'); res.redirect(301, '/signin');
}); });
app.post('/signin', userController.postSignin); app.post('/signin', userController.postSignin);
app.get('/signout', userController.signout); app.get('/signout', userController.signout);
app.get('/logout', function(req, res) { app.get('/logout', function(req, res) {
res.redirect(301, '/signout'); res.redirect(301, '/signout');
}); });
app.get('/forgot', userController.getForgot); app.get('/forgot', userController.getForgot);
app.post('/forgot', userController.postForgot); app.post('/forgot', userController.postForgot);
@ -283,14 +285,14 @@ app.post(
contactController.postDoneWithFirst100Hours contactController.postDoneWithFirst100Hours
); );
app.get( app.get(
'/nonprofit-project-instructions', '/nonprofit-project-instructions',
passportConf.isAuthenticated, passportConf.isAuthenticated,
resourcesController.nonprofitProjectInstructions resourcesController.nonprofitProjectInstructions
); );
app.post( app.post(
'/update-progress', '/update-progress',
passportConf.isAuthenticated, passportConf.isAuthenticated,
userController.updateProgress userController.updateProgress
); );
app.get('/api/slack', function(req, res) { app.get('/api/slack', function(req, res) {
@ -351,98 +353,98 @@ app.get('/api/slack', function(req, res) {
* Main routes. * Main routes.
*/ */
app.get( app.get(
'/stories/hotStories', '/stories/hotStories',
storyController.hotJSON storyController.hotJSON
); );
app.get( app.get(
'/stories/recentStories', '/stories/recentStories',
storyController.recentJSON storyController.recentJSON
); );
app.get( app.get(
'/stories/', '/stories/',
function(req, res) { function(req, res) {
res.redirect(302, '/stories/hot'); res.redirect(302, '/stories/hot');
} }
); );
app.get( app.get(
'/stories/comments/:id', '/stories/comments/:id',
storyController.comments storyController.comments
); );
app.post( app.post(
'/stories/comment/', '/stories/comment/',
storyController.commentSubmit storyController.commentSubmit
); );
app.post( app.post(
'/stories/comment/:id/comment', '/stories/comment/:id/comment',
storyController.commentOnCommentSubmit storyController.commentOnCommentSubmit
); );
app.get( app.get(
'/stories/submit', '/stories/submit',
storyController.submitNew storyController.submitNew
); );
app.get( app.get(
'/stories/submit/new-story', '/stories/submit/new-story',
storyController.preSubmit storyController.preSubmit
); );
app.post( app.post(
'/stories/preliminary', '/stories/preliminary',
storyController.newStory storyController.newStory
); );
app.post( app.post(
'/stories/', '/stories/',
storyController.storySubmission storyController.storySubmission
); );
app.get( app.get(
'/stories/hot', '/stories/hot',
storyController.hot storyController.hot
); );
app.get( app.get(
'/stories/recent', '/stories/recent',
storyController.recent storyController.recent
); );
app.get( app.get(
'/stories/search', '/stories/search',
storyController.search storyController.search
); );
app.post( app.post(
'/stories/search', '/stories/search',
storyController.getStories storyController.getStories
); );
app.get( app.get(
'/stories/:storyName', '/stories/:storyName',
storyController.returnIndividualStory storyController.returnIndividualStory
); );
app.post( app.post(
'/stories/upvote/', '/stories/upvote/',
storyController.upvote storyController.upvote
); );
/** /**
* Challenge related routes * Challenge related routes
*/ */
app.get( app.get(
'/challenges/', '/challenges/',
challengesController.returnNextChallenge challengesController.returnNextChallenge
); );
app.get( app.get(
'/challenges/:challengeNumber', '/challenges/:challengeNumber',
challengesController.returnChallenge challengesController.returnChallenge
); );
app.all('/account', passportConf.isAuthenticated); app.all('/account', passportConf.isAuthenticated);
@ -466,11 +468,11 @@ app.post('/bonfire-json-generator', bonfireController.generateChallenge);
app.get('/bonfire-challenge-generator', bonfireController.publicGenerator); app.get('/bonfire-challenge-generator', bonfireController.publicGenerator);
app.post('/bonfire-challenge-generator', bonfireController.testBonfire) app.post('/bonfire-challenge-generator', bonfireController.testBonfire)
app.get( app.get(
'/bonfires/:bonfireName', '/bonfires/:bonfireName',
bonfireController.returnIndividualBonfire bonfireController.returnIndividualBonfire
); );
app.get('/bonfire', function(req, res) { app.get('/bonfire', function(req, res) {
res.redirect(301, '/playground'); res.redirect(301, '/playground');
}); });
app.post('/completed-bonfire/', bonfireController.completedBonfire); app.post('/completed-bonfire/', bonfireController.completedBonfire);
@ -481,8 +483,8 @@ app.post('/completed-bonfire/', bonfireController.completedBonfire);
app.get('/coursewares/', coursewareController.returnNextCourseware); app.get('/coursewares/', coursewareController.returnNextCourseware);
app.get( app.get(
'/coursewares/:coursewareName', '/coursewares/:coursewareName',
coursewareController.returnIndividualCourseware coursewareController.returnIndividualCourseware
); );
app.post('/completed-courseware/', coursewareController.completedCourseware); app.post('/completed-courseware/', coursewareController.completedCourseware);
@ -504,20 +506,20 @@ app.get('/sitemap.xml', resourcesController.sitemap);
* *
*/ */
app.post('/completed-challenge', function (req, res, done) { app.post('/completed-challenge', function (req, res, done) {
req.user.challengesHash[parseInt(req.body.challengeNumber)] = req.user.challengesHash[parseInt(req.body.challengeNumber)] =
Math.round(+new Date() / 1000); Math.round(+new Date() / 1000);
var timestamp = req.user.challengesHash; var timestamp = req.user.challengesHash;
var points = 0; var points = 0;
for (var key in timestamp) { for (var key in timestamp) {
if (timestamp[key] > 0 && req.body.challengeNumber < 54) { if (timestamp[key] > 0 && req.body.challengeNumber < 54) {
points += 1; points += 1;
}
} }
req.user.points = points; }
req.user.save(function(err) { req.user.points = points;
if (err) { return done(err); } req.user.save(function(err) {
res.status(200).send({ msg: 'progress saved' }); if (err) { return done(err); }
}); res.status(200).send({ msg: 'progress saved' });
});
}); });
/** /**
@ -525,60 +527,60 @@ app.post('/completed-challenge', function (req, res, done) {
*/ */
var passportOptions = { var passportOptions = {
successRedirect: '/', successRedirect: '/',
failureRedirect: '/login' failureRedirect: '/login'
}; };
app.get('/auth/twitter', passport.authenticate('twitter')); app.get('/auth/twitter', passport.authenticate('twitter'));
app.get( app.get(
'/auth/twitter/callback', '/auth/twitter/callback',
passport.authenticate('twitter', { passport.authenticate('twitter', {
successRedirect: '/', successRedirect: '/',
failureRedirect: '/login' failureRedirect: '/login'
}) })
); );
app.get( app.get(
'/auth/linkedin', '/auth/linkedin',
passport.authenticate('linkedin', { passport.authenticate('linkedin', {
state: 'SOME STATE' state: 'SOME STATE'
}) })
); );
app.get( app.get(
'/auth/linkedin/callback', '/auth/linkedin/callback',
passport.authenticate('linkedin', passportOptions) passport.authenticate('linkedin', passportOptions)
); );
app.get( app.get(
'/auth/facebook', '/auth/facebook',
passport.authenticate('facebook', {scope: ['email', 'user_location']}) passport.authenticate('facebook', {scope: ['email', 'user_location']})
); );
app.get( app.get(
'/auth/facebook/callback', '/auth/facebook/callback',
passport.authenticate('facebook', passportOptions), function (req, res) { passport.authenticate('facebook', passportOptions), function (req, res) {
res.redirect(req.session.returnTo || '/'); res.redirect(req.session.returnTo || '/');
} }
); );
app.get('/auth/github', passport.authenticate('github')); app.get('/auth/github', passport.authenticate('github'));
app.get( app.get(
'/auth/github/callback', '/auth/github/callback',
passport.authenticate('github', passportOptions), function (req, res) { passport.authenticate('github', passportOptions), function (req, res) {
res.redirect(req.session.returnTo || '/'); res.redirect(req.session.returnTo || '/');
} }
); );
app.get( app.get(
'/auth/google', '/auth/google',
passport.authenticate('google', {scope: 'profile email'}) passport.authenticate('google', {scope: 'profile email'})
); );
app.get( app.get(
'/auth/google/callback', '/auth/google/callback',
passport.authenticate('google', passportOptions), function (req, res) { passport.authenticate('google', passportOptions), function (req, res) {
res.redirect(req.session.returnTo || '/'); res.redirect(req.session.returnTo || '/');
} }
); );
app.get('/induce-vomiting', function(req, res, next) { app.get('/induce-vomiting', function(req, res, next) {
@ -587,8 +589,8 @@ app.get('/induce-vomiting', function(req, res, next) {
// put this route last // put this route last
app.get( app.get(
'/:username', '/:username',
userController.returnUser userController.returnUser
); );
/** /**
@ -614,15 +616,16 @@ if (process.env.NODE_ENV === 'development') {
var accept = accepts(req); var accept = accepts(req);
var type = accept.type('html', 'json', 'text'); var type = accept.type('html', 'json', 'text');
var message = 'opps! Something went wrong. Please try again later'; var message = 'oops! Something went wrong. Please try again later.';
debug('ERROR!!', err);
if (type === 'html') { if (type === 'html') {
req.flash('errors', { msg: message }); req.flash('errors', { msg: message });
return res.redirect('/'); return res.redirect('/');
// json // json
} else if (type === 'json') { } else if (type === 'json') {
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
return res.send({ message: message }); return res.send({ message: message });
// plain text // plain text
} else { } else {
res.setHeader('Content-Type', 'text/plain'); res.setHeader('Content-Type', 'text/plain');
return res.send(message); return res.send(message);
@ -634,11 +637,11 @@ if (process.env.NODE_ENV === 'development') {
* Start Express server. * Start Express server.
*/ */
app.listen(app.get('port'), function () { app.listen(app.get('port'), function () {
console.log( console.log(
'FreeCodeCamp server listening on port %d in %s mode', 'FreeCodeCamp server listening on port %d in %s mode',
app.get('port'), app.get('port'),
app.get('env') app.get('env')
); );
}); });
module.exports = app; module.exports = app;