2015-03-18 04:57:05 +00:00
if ( process . env . NODE _ENV !== 'development' ) {
require ( 'newrelic' ) ;
}
2014-12-23 00:16:10 +00:00
require ( 'dotenv' ) . load ( ) ;
2015-03-23 05:18:01 +00:00
// handle uncaught exceptions. Forever will restart process on shutdown
process . on ( 'uncaughtException' , function ( err ) {
console . error (
( new Date ( ) ) . toUTCString ( ) + ' uncaughtException:' ,
err . message
) ;
console . error ( err . stack ) ;
/* eslint-disable no-process-exit */
process . exit ( 1 ) ;
/* eslint-enable no-process-exit */
} ) ;
2014-01-12 03:53:31 +00:00
2014-12-23 16:48:28 +00:00
var express = require ( 'express' ) ,
2015-04-14 19:36:02 +00:00
accepts = require ( 'accepts' ) ,
cookieParser = require ( 'cookie-parser' ) ,
compress = require ( 'compression' ) ,
session = require ( 'express-session' ) ,
logger = require ( 'morgan' ) ,
errorHandler = require ( 'errorhandler' ) ,
methodOverride = require ( 'method-override' ) ,
bodyParser = require ( 'body-parser' ) ,
helmet = require ( 'helmet' ) ,
MongoStore = require ( 'connect-mongo' ) ( session ) ,
flash = require ( 'express-flash' ) ,
path = require ( 'path' ) ,
mongoose = require ( 'mongoose' ) ,
passport = require ( 'passport' ) ,
expressValidator = require ( 'express-validator' ) ,
connectAssets = require ( 'connect-assets' ) ,
request = require ( 'request' ) ,
/ * *
* 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
* /
storyController = require ( './controllers/story' ) ,
/ * *
* API keys and Passport configuration .
* /
secrets = require ( './config/secrets' ) ,
passportConf = require ( './config/passport' ) ;
2013-11-27 04:15:13 +00:00
2014-02-02 10:38:38 +00:00
/ * *
* Create Express server .
* /
var app = express ( ) ;
2014-01-12 03:53:31 +00:00
/ * *
2014-06-06 18:58:30 +00:00
* Connect to MongoDB .
2014-01-12 03:53:31 +00:00
* /
2014-02-26 03:39:28 +00:00
mongoose . connect ( secrets . db ) ;
2015-01-16 23:58:27 +00:00
mongoose . connection . on ( 'error' , function ( ) {
2015-04-14 19:36:02 +00:00
console . error (
'MongoDB Connection Error. Please make sure that MongoDB is running.'
) ;
2014-01-12 03:53:31 +00:00
} ) ;
2013-11-13 17:32:22 +00:00
2014-05-06 04:44:30 +00:00
/ * *
* Express configuration .
* /
2014-04-18 18:29:30 +00:00
2015-02-17 23:35:16 +00:00
2014-01-12 03:53:31 +00:00
app . set ( 'port' , process . env . PORT || 3000 ) ;
app . set ( 'views' , path . join ( _ _dirname , 'views' ) ) ;
app . set ( 'view engine' , 'jade' ) ;
2014-06-06 18:58:30 +00:00
app . use ( compress ( ) ) ;
2014-12-27 08:22:50 +00:00
var oneYear = 31557600000 ;
2015-01-16 23:58:27 +00:00
app . use ( express . static ( _ _dirname + '/public' , { maxAge : oneYear } ) ) ;
2014-02-21 22:29:06 +00:00
app . use ( connectAssets ( {
2015-04-14 19:36:02 +00:00
paths : [
path . join ( _ _dirname , 'public/css' ) ,
path . join ( _ _dirname , 'public/js' )
] ,
helperContext : app . locals
2014-02-03 13:34:12 +00:00
} ) ) ;
2014-04-12 16:43:07 +00:00
app . use ( logger ( 'dev' ) ) ;
app . use ( bodyParser . json ( ) ) ;
2015-01-16 23:58:27 +00:00
app . use ( bodyParser . urlencoded ( { extended : true } ) ) ;
2014-12-24 02:20:53 +00:00
app . use ( expressValidator ( {
2015-04-14 19:36:02 +00:00
customValidators : {
matchRegex : function ( param , regex ) {
return regex . test ( param ) ;
2014-12-24 02:20:53 +00:00
}
2015-04-14 19:36:02 +00:00
}
2014-12-24 02:20:53 +00:00
} ) ) ;
2014-04-12 16:43:07 +00:00
app . use ( methodOverride ( ) ) ;
app . use ( cookieParser ( ) ) ;
app . use ( session ( {
2015-04-14 19:36:02 +00:00
resave : true ,
saveUninitialized : true ,
secret : secrets . sessionSecret ,
store : new MongoStore ( {
url : secrets . db ,
'auto_reconnect' : true
} )
2014-01-29 05:49:09 +00:00
} ) ) ;
2014-01-12 03:53:31 +00:00
app . use ( passport . initialize ( ) ) ;
app . use ( passport . session ( ) ) ;
2014-06-01 15:52:28 +00:00
app . use ( flash ( ) ) ;
2014-12-11 04:44:33 +00:00
app . disable ( 'x-powered-by' ) ;
2014-12-23 16:48:28 +00:00
2014-12-11 04:44:33 +00:00
app . use ( helmet . xssFilter ( ) ) ;
2015-01-09 23:10:34 +00:00
app . use ( helmet . noSniff ( ) ) ;
2014-12-11 04:44:33 +00:00
app . use ( helmet . xframe ( ) ) ;
2015-02-17 23:35:16 +00:00
app . use ( function ( req , res , next ) {
2015-04-14 19:36:02 +00:00
res . header ( "Access-Control-Allow-Origin" , "*" ) ;
res . header ( "Access-Control-Allow-Headers" , "Origin, X-Requested-With, Content-Type, Accept" ) ;
next ( ) ;
2015-02-17 23:35:16 +00:00
} ) ;
2014-12-23 16:48:28 +00:00
2014-12-22 20:36:45 +00:00
var trusted = [
2015-04-14 19:36:02 +00:00
"'self'" ,
'*.freecodecamp.com' ,
'*.gstatic.com' ,
'*.google-analytics.com' ,
'*.googleapis.com' ,
'*.google.com' ,
'*.gstatic.com' ,
'*.doubleclick.net' ,
'*.twitter.com' ,
'*.twitch.tv' ,
'*.twimg.com' ,
"'unsafe-eval'" ,
"'unsafe-inline'" ,
'*.rafflecopter.com' ,
'*.bootstrapcdn.com' ,
'*.cloudflare.com' ,
'https://*.cloudflare.com' ,
'localhost:3001' ,
'ws://localhost:3001/' ,
'http://localhost:3001' ,
'localhost:3000' ,
'ws://localhost:3000/' ,
'http://localhost:3000' ,
'*.ionicframework.com' ,
'https://syndication.twitter.com' ,
'*.youtube.com' ,
'*.jsdelivr.net' ,
'https://*.jsdelivr.net' ,
'*.togetherjs.com' ,
'https://*.togetherjs.com' ,
'wss://hub.togetherjs.com' ,
'*.ytimg.com' ,
'wss://fcctogether.herokuapp.com' ,
'*.bitly.com'
2014-12-22 20:36:45 +00:00
] ;
2014-12-22 21:38:48 +00:00
2014-12-11 04:44:33 +00:00
app . use ( helmet . contentSecurityPolicy ( {
2015-04-14 19:36:02 +00:00
defaultSrc : trusted ,
scriptSrc : [ '*.optimizely.com' , '*.aspnetcdn.com' ] . concat ( trusted ) ,
'connect-src' : [
'ws://*.rafflecopter.com' ,
'wss://*.rafflecopter.com' ,
'https://*.rafflecopter.com' ,
'ws://www.freecodecamp.com' ,
'http://www.freecodecamp.com'
] . concat ( trusted ) ,
styleSrc : trusted ,
imgSrc : [
'*.evernote.com' ,
'*.amazonaws.com' ,
'data:' ,
'*.licdn.com' ,
'*.gravatar.com' ,
'*.akamaihd.net' ,
'graph.facebook.com' ,
'*.githubusercontent.com' ,
'*.googleusercontent.com' ,
'*' /* allow all input since we have user submitted images for public profile*/
] . concat ( trusted ) ,
fontSrc : [ '*.googleapis.com' ] . concat ( trusted ) ,
mediaSrc : [
'*.amazonaws.com' ,
'*.twitter.com'
] . concat ( trusted ) ,
frameSrc : [
'*.gitter.im' ,
'*.gitter.im https:' ,
'*.vimeo.com' ,
'*.twitter.com' ,
'*.rafflecopter.com' ,
'*.ghbtns.com'
] . concat ( trusted ) ,
reportOnly : false , // set to true if you only want to report errors
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
2014-12-11 04:44:33 +00:00
} ) ) ;
2014-11-19 23:30:36 +00:00
2015-01-16 23:58:27 +00:00
app . use ( function ( req , res , next ) {
2015-04-14 19:36:02 +00:00
// Make user object available in templates.
res . locals . user = req . user ;
next ( ) ;
2014-01-12 03:53:31 +00:00
} ) ;
2014-11-19 23:30:36 +00:00
2015-01-16 23:58:27 +00:00
app . use ( function ( req , res , next ) {
2015-04-14 19:36:02 +00:00
// Remember original destination before login.
var path = req . path . split ( '/' ) [ 1 ] ;
if ( /auth|login|logout|signup|fonts|favicon/i . test ( path ) ) {
return next ( ) ;
}
req . session . returnTo = req . path ;
next ( ) ;
2014-03-08 19:58:27 +00:00
} ) ;
2014-11-19 23:30:36 +00:00
2014-12-23 16:48:28 +00:00
app . use (
2015-04-14 19:36:02 +00:00
express . static ( path . join ( _ _dirname , 'public' ) , { maxAge : 31557600000 } )
2014-12-23 16:48:28 +00:00
) ;
2014-01-08 06:37:40 +00:00
2015-03-07 10:00:21 +00:00
app . use ( express . static ( _ _dirname + '/public' , { maxAge : 86400000 } ) ) ;
2014-01-12 03:53:31 +00:00
/ * *
2014-06-06 19:23:28 +00:00
* Main routes .
2014-01-12 03:53:31 +00:00
* /
2014-11-19 23:30:36 +00:00
2015-01-14 21:28:20 +00:00
app . get ( '/' , homeController . index ) ;
2014-11-30 07:01:49 +00:00
app . get ( '/privacy' , resourcesController . privacy ) ;
2014-11-29 23:16:47 +00:00
app . get ( '/jquery-exercises' , resourcesController . jqueryExercises ) ;
2015-02-20 00:33:08 +00:00
app . get ( '/chat' , resourcesController . chat ) ;
2014-12-15 06:24:54 +00:00
app . get ( '/live-pair-programming' , resourcesController . livePairProgramming ) ;
2015-02-17 22:10:15 +00:00
app . get ( '/install-screenhero' , resourcesController . installScreenHero ) ;
2014-12-15 06:24:54 +00:00
app . get ( '/javascript-in-your-inbox' , resourcesController . javaScriptInYourInbox ) ;
2015-03-08 09:36:09 +00:00
app . get ( '/guide-to-our-nonprofit-projects' , resourcesController . guideToOurNonprofitProjects ) ;
2014-12-12 05:24:44 +00:00
app . get ( '/chromebook' , resourcesController . chromebook ) ;
2015-03-30 00:28:25 +00:00
app . get ( '/styleguide' , resourcesController . styleguide ) ;
2014-12-26 08:05:00 +00:00
app . get ( '/deploy-a-website' , resourcesController . deployAWebsite ) ;
app . get ( '/gmail-shortcuts' , resourcesController . gmailShortcuts ) ;
app . get ( '/control-shortcuts' , resourcesController . controlShortcuts ) ;
app . get ( '/control-shortcuts' , resourcesController . deployAWebsite ) ;
2015-03-20 05:34:36 +00:00
app . get ( '/nodeschool-challenges' , resourcesController . nodeSchoolChallenges ) ;
2015-01-26 19:38:19 +00:00
app . get ( '/stats' , function ( req , res ) {
2015-04-14 19:36:02 +00:00
res . redirect ( 301 , '/learn-to-code' ) ;
2015-01-26 19:38:19 +00:00
} ) ;
2015-03-09 15:54:45 +00:00
app . get ( '/news' , function ( req , res ) {
2015-04-14 19:36:02 +00:00
res . redirect ( 301 , '/stories/hot' ) ;
2015-03-09 15:54:45 +00:00
} ) ;
2015-01-17 19:27:27 +00:00
app . get ( '/learn-to-code' , resourcesController . about ) ;
2015-01-26 19:38:19 +00:00
app . get ( '/about' , function ( req , res ) {
2015-04-14 19:36:02 +00:00
res . redirect ( 301 , '/learn-to-code' ) ;
2015-01-26 19:38:19 +00:00
} ) ;
app . get ( '/signin' , userController . getSignin ) ;
app . get ( '/login' , function ( req , res ) {
2015-04-14 19:36:02 +00:00
res . redirect ( 301 , '/signin' ) ;
2015-01-26 19:38:19 +00:00
} ) ;
app . post ( '/signin' , userController . postSignin ) ;
app . get ( '/signout' , userController . signout ) ;
app . get ( '/logout' , function ( req , res ) {
2015-04-14 19:36:02 +00:00
res . redirect ( 301 , '/signout' ) ;
2015-01-26 19:38:19 +00:00
} ) ;
2014-06-06 19:23:28 +00:00
app . get ( '/forgot' , userController . getForgot ) ;
app . post ( '/forgot' , userController . postForgot ) ;
app . get ( '/reset/:token' , userController . getReset ) ;
app . post ( '/reset/:token' , userController . postReset ) ;
2014-12-08 00:25:43 +00:00
app . get ( '/email-signup' , userController . getEmailSignup ) ;
app . get ( '/email-signin' , userController . getEmailSignin ) ;
app . post ( '/email-signup' , userController . postEmailSignup ) ;
2015-01-26 19:38:19 +00:00
app . post ( '/email-signin' , userController . postSignin ) ;
2015-01-14 21:28:20 +00:00
app . get ( '/nonprofits' , contactController . getNonprofitsForm ) ;
app . post ( '/nonprofits' , contactController . postNonprofitsForm ) ;
2015-01-23 23:13:36 +00:00
2015-01-14 21:28:20 +00:00
app . get (
'/done-with-first-100-hours' ,
2015-01-23 23:13:36 +00:00
passportConf . isAuthenticated ,
2015-01-14 21:28:20 +00:00
contactController . getDoneWithFirst100Hours
) ;
app . post (
'/done-with-first-100-hours' ,
2015-01-23 23:13:36 +00:00
passportConf . isAuthenticated ,
2015-01-14 21:28:20 +00:00
contactController . postDoneWithFirst100Hours
) ;
2015-01-23 23:13:36 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/nonprofit-project-instructions' ,
passportConf . isAuthenticated ,
resourcesController . nonprofitProjectInstructions
2015-01-23 23:13:36 +00:00
) ;
2014-11-19 23:50:57 +00:00
app . post (
2015-04-14 19:36:02 +00:00
'/update-progress' ,
passportConf . isAuthenticated ,
userController . updateProgress
2014-12-23 16:48:28 +00:00
) ;
2015-02-16 07:59:03 +00:00
2015-04-09 05:42:40 +00:00
app . get ( '/api/slack' , function ( req , res ) {
if ( req . user ) {
if ( req . user . email ) {
var invite = {
'email' : req . user . email ,
'token' : process . env . SLACK _KEY ,
'set_active' : true
} ;
var headers = {
'User-Agent' : 'Node Browser/0.0.1' ,
'Content-Type' : 'application/x-www-form-urlencoded'
} ;
var options = {
url : 'https://freecode.slack.com/api/users.admin.invite' ,
method : 'POST' ,
headers : headers ,
form : invite
} ;
request ( options , function ( error , response , body ) {
if ( ! error && response . statusCode === 200 ) {
req . flash ( 'success' , {
msg : "We've successfully requested an invite for you. Please check your email and follow the instructions from Slack."
} ) ;
req . user . sentSlackInvite = true ;
req . user . save ( function ( err , user ) {
if ( err ) {
next ( err ) ;
}
return res . redirect ( 'back' ) ;
} ) ;
} else {
req . flash ( 'errors' , {
msg : "The invitation email did not go through for some reason. Please try again or <a href='mailto:team@freecodecamp.com?subject=slack%20invite%20failed%20to%20send>email us</a>."
} ) ;
return res . redirect ( 'back' ) ;
}
} )
} else {
req . flash ( 'notice' , {
msg : "Before we can send your Slack invite, we need your email address. Please update your profile information here."
} ) ;
return res . redirect ( '/account' ) ;
}
} else {
req . flash ( 'notice' , {
msg : "You need to sign in to Free Code Camp before we can send you a Slack invite."
} ) ;
return res . redirect ( '/account' ) ;
}
} ) ;
2015-03-03 10:23:56 +00:00
/ * *
* Main routes .
* /
2015-03-05 23:11:18 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/stories/hotStories' ,
storyController . hotJSON
2015-03-05 23:11:18 +00:00
) ;
app . get (
2015-04-14 19:36:02 +00:00
'/stories/recentStories' ,
storyController . recentJSON
2015-03-05 23:11:18 +00:00
) ;
2015-03-03 10:23:56 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/stories/' ,
function ( req , res ) {
res . redirect ( 302 , '/stories/hot' ) ;
}
2015-03-03 10:23:56 +00:00
) ;
2015-03-05 23:11:18 +00:00
2015-03-03 10:23:56 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/stories/comments/:id' ,
storyController . comments
2015-03-03 10:23:56 +00:00
) ;
2015-03-03 22:15:00 +00:00
2015-03-05 21:08:40 +00:00
app . post (
2015-04-14 19:36:02 +00:00
'/stories/comment/' ,
storyController . commentSubmit
2015-03-05 21:08:40 +00:00
) ;
2015-03-06 16:57:09 +00:00
app . post (
2015-04-14 19:36:02 +00:00
'/stories/comment/:id/comment' ,
storyController . commentOnCommentSubmit
2015-03-06 16:57:09 +00:00
) ;
2015-03-03 22:15:00 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/stories/submit' ,
storyController . submitNew
2015-03-03 22:15:00 +00:00
) ;
2015-03-07 08:42:22 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/stories/submit/new-story' ,
storyController . preSubmit
2015-03-05 10:21:26 +00:00
) ;
2015-03-07 08:42:22 +00:00
app . post (
2015-04-14 19:36:02 +00:00
'/stories/preliminary' ,
storyController . newStory
2015-03-07 08:42:22 +00:00
) ;
2015-03-05 23:11:18 +00:00
2015-03-07 09:26:49 +00:00
app . post (
2015-04-14 19:36:02 +00:00
'/stories/' ,
storyController . storySubmission
2015-03-07 09:26:49 +00:00
) ;
2015-03-05 23:11:18 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/stories/hot' ,
storyController . hot
2015-03-05 23:11:18 +00:00
) ;
app . get (
2015-04-14 19:36:02 +00:00
'/stories/recent' ,
storyController . recent
2015-03-05 23:11:18 +00:00
) ;
app . get (
2015-04-14 19:36:02 +00:00
'/stories/search' ,
storyController . search
2015-03-05 23:11:18 +00:00
) ;
2015-03-06 00:20:30 +00:00
app . post (
2015-04-14 19:36:02 +00:00
'/stories/search' ,
storyController . getStories
2015-03-06 00:20:30 +00:00
) ;
2015-03-03 10:50:16 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/stories/:storyName' ,
storyController . returnIndividualStory
2015-03-03 10:50:16 +00:00
) ;
2015-03-05 23:11:18 +00:00
2015-03-03 13:03:33 +00:00
app . post (
2015-04-14 19:36:02 +00:00
'/stories/upvote/' ,
storyController . upvote
2015-03-03 13:03:33 +00:00
) ;
2015-03-03 10:23:56 +00:00
2015-02-16 07:59:03 +00:00
/ * *
* Challenge related routes
* /
app . get (
2015-04-14 19:36:02 +00:00
'/challenges/' ,
challengesController . returnNextChallenge
2015-02-16 07:59:03 +00:00
) ;
2014-11-19 23:50:57 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/challenges/:challengeNumber' ,
challengesController . returnChallenge
2014-12-23 16:48:28 +00:00
) ;
2015-02-16 07:59:03 +00:00
2014-11-19 23:30:36 +00:00
app . all ( '/account' , passportConf . isAuthenticated ) ;
2015-01-06 05:52:30 +00:00
app . get ( '/account/api' , userController . getAccountAngular ) ;
2015-01-28 01:12:51 +00:00
2015-02-17 07:35:02 +00:00
/ * *
* API routes
* /
app . get ( '/api/github' , resourcesController . githubCalls ) ;
2015-03-28 06:30:06 +00:00
app . get ( '/api/blogger' , resourcesController . bloggerCalls ) ;
app . get ( '/api/trello' , resourcesController . trelloCalls ) ;
2015-02-17 07:35:02 +00:00
2015-01-28 01:12:51 +00:00
/ * *
* Bonfire related routes
* /
2015-01-24 22:42:34 +00:00
app . get ( '/playground' , bonfireController . index ) ;
2015-01-28 01:12:51 +00:00
app . get ( '/bonfires' , bonfireController . returnNextBonfire ) ;
app . get ( '/bonfire-json-generator' , bonfireController . returnGenerator ) ;
app . post ( '/bonfire-json-generator' , bonfireController . generateChallenge ) ;
app . get ( '/bonfire-challenge-generator' , bonfireController . publicGenerator ) ;
app . post ( '/bonfire-challenge-generator' , bonfireController . testBonfire )
2015-01-22 18:20:46 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/bonfires/:bonfireName' ,
bonfireController . returnIndividualBonfire
2015-01-22 18:20:46 +00:00
) ;
2015-01-26 17:30:04 +00:00
app . get ( '/bonfire' , function ( req , res ) {
2015-04-14 19:36:02 +00:00
res . redirect ( 301 , '/playground' ) ;
2015-01-26 17:30:04 +00:00
} ) ;
2014-02-01 08:30:14 +00:00
2015-02-02 06:39:59 +00:00
app . post ( '/completed-bonfire/' , bonfireController . completedBonfire ) ;
2015-01-24 05:44:08 +00:00
2015-02-02 07:35:27 +00:00
/ * *
* Courseware related routes
* /
2015-02-06 17:36:55 +00:00
app . get ( '/coursewares/' , coursewareController . returnNextCourseware ) ;
2015-02-02 07:35:27 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/coursewares/:coursewareName' ,
coursewareController . returnIndividualCourseware
2015-02-02 07:35:27 +00:00
) ;
app . post ( '/completed-courseware/' , coursewareController . completedCourseware ) ;
2015-01-28 01:12:51 +00:00
// Unique Check API route
app . get ( '/api/checkUniqueUsername/:username' , userController . checkUniqueUsername ) ;
app . get ( '/api/checkExistingUsername/:username' , userController . checkExistingUsername ) ;
app . get ( '/api/checkUniqueEmail/:email' , userController . checkUniqueEmail ) ;
app . get ( '/account' , userController . getAccount ) ;
app . post ( '/account/profile' , userController . postUpdateProfile ) ;
app . post ( '/account/password' , userController . postUpdatePassword ) ;
app . post ( '/account/delete' , userController . postDeleteAccount ) ;
app . get ( '/account/unlink/:provider' , userController . getOauthUnlink ) ;
2015-03-06 08:20:39 +00:00
app . get ( '/sitemap.xml' , resourcesController . sitemap ) ;
2015-01-28 01:12:51 +00:00
/ * *
* API examples routes .
* accepts a post request . the challenge id req . body . challengeNumber
* and updates user . challengesHash & user . challengesCompleted
*
* /
2015-03-24 00:17:39 +00:00
app . post ( '/completed-challenge' , function ( req , res , done ) {
2015-04-14 19:36:02 +00:00
req . user . challengesHash [ parseInt ( req . body . challengeNumber ) ] =
Math . round ( + new Date ( ) / 1000 ) ;
var timestamp = req . user . challengesHash ;
var points = 0 ;
for ( var key in timestamp ) {
if ( timestamp [ key ] > 0 && req . body . challengeNumber < 54 ) {
points += 1 ;
2015-01-28 01:12:51 +00:00
}
2015-04-14 19:36:02 +00:00
}
req . user . points = points ;
req . user . save ( function ( err ) {
if ( err ) { return done ( err ) ; }
res . status ( 200 ) . send ( { msg : 'progress saved' } ) ;
} ) ;
2015-01-28 01:12:51 +00:00
} ) ;
2014-02-01 08:30:14 +00:00
/ * *
2014-06-06 18:58:30 +00:00
* OAuth sign - in routes .
2014-02-01 08:30:14 +00:00
* /
2014-12-23 21:50:14 +00:00
var passportOptions = {
2015-04-14 19:36:02 +00:00
successRedirect : '/' ,
failureRedirect : '/login'
2014-12-23 21:50:14 +00:00
} ;
2015-01-18 02:52:58 +00:00
app . get ( '/auth/twitter' , passport . authenticate ( 'twitter' ) ) ;
2014-11-19 23:30:36 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/auth/twitter/callback' ,
passport . authenticate ( 'twitter' , {
successRedirect : '/' ,
failureRedirect : '/login'
} )
2014-12-23 21:50:14 +00:00
) ;
2014-11-19 23:30:36 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/auth/linkedin' ,
passport . authenticate ( 'linkedin' , {
state : 'SOME STATE'
} )
2014-12-23 21:50:14 +00:00
) ;
2014-11-19 23:30:36 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/auth/linkedin/callback' ,
passport . authenticate ( 'linkedin' , passportOptions )
2014-12-23 21:50:14 +00:00
) ;
2014-11-19 23:30:36 +00:00
2014-12-23 16:48:28 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/auth/facebook' ,
passport . authenticate ( 'facebook' , { scope : [ 'email' , 'user_location' ] } )
2014-12-23 16:48:28 +00:00
) ;
app . get (
2015-04-14 19:36:02 +00:00
'/auth/facebook/callback' ,
passport . authenticate ( 'facebook' , passportOptions ) , function ( req , res ) {
res . redirect ( req . session . returnTo || '/' ) ;
}
2014-12-23 16:48:28 +00:00
) ;
2014-11-30 06:22:27 +00:00
app . get ( '/auth/github' , passport . authenticate ( 'github' ) ) ;
2014-12-23 16:48:28 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/auth/github/callback' ,
passport . authenticate ( 'github' , passportOptions ) , function ( req , res ) {
res . redirect ( req . session . returnTo || '/' ) ;
}
2014-12-23 16:48:28 +00:00
) ;
2014-11-30 06:22:27 +00:00
2014-12-23 16:48:28 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/auth/google' ,
passport . authenticate ( 'google' , { scope : 'profile email' } )
2014-12-23 16:48:28 +00:00
) ;
app . get (
2015-04-14 19:36:02 +00:00
'/auth/google/callback' ,
passport . authenticate ( 'google' , passportOptions ) , function ( req , res ) {
res . redirect ( req . session . returnTo || '/' ) ;
}
2014-12-23 16:48:28 +00:00
) ;
2014-11-30 06:22:27 +00:00
2015-03-24 15:03:59 +00:00
app . get ( '/induce-vomiting' , function ( req , res , next ) {
next ( new Error ( 'vomiting induced' ) ) ;
} ) ;
// put this route last
2015-01-18 02:52:58 +00:00
app . get (
2015-04-14 19:36:02 +00:00
'/:username' ,
userController . returnUser
2015-01-18 02:52:58 +00:00
) ;
2015-01-11 05:45:22 +00:00
2014-11-19 23:30:36 +00:00
/ * *
* 500 Error Handler .
* /
2015-03-24 15:03:59 +00:00
if ( process . env . NODE _ENV === 'development' ) {
app . use ( errorHandler ( { log : true } ) ) ;
} else {
// error handling in production
app . use ( function ( err , req , res , next ) {
// respect err.status
if ( err . status ) {
res . statusCode = err . status ;
}
// default status code to 500
if ( res . statusCode < 400 ) {
res . statusCode = 500 ;
}
// parse res type
var accept = accepts ( req ) ;
var type = accept . type ( 'html' , 'json' , 'text' ) ;
2015-04-14 20:17:58 +00:00
var message = 'oops! Something went wrong. Please try again later.' +
' Twitter authentication is currently unavailable for FreeCodeCamp.' +
' We are working with Twitter to restore functionality' +
' as soon as possible.' ;
2015-04-14 19:42:46 +00:00
console . log ( 'ERROR!!' , err ) ;
2015-03-24 15:03:59 +00:00
if ( type === 'html' ) {
req . flash ( 'errors' , { msg : message } ) ;
return res . redirect ( '/' ) ;
2015-04-14 19:36:02 +00:00
// json
2015-03-24 15:03:59 +00:00
} else if ( type === 'json' ) {
res . setHeader ( 'Content-Type' , 'application/json' ) ;
return res . send ( { message : message } ) ;
2015-04-14 19:36:02 +00:00
// plain text
2015-03-24 15:03:59 +00:00
} else {
res . setHeader ( 'Content-Type' , 'text/plain' ) ;
return res . send ( message ) ;
}
} ) ;
}
2014-11-19 23:30:36 +00:00
/ * *
* Start Express server .
* /
2015-01-16 23:58:27 +00:00
app . listen ( app . get ( 'port' ) , function ( ) {
2015-04-14 19:36:02 +00:00
console . log (
'FreeCodeCamp server listening on port %d in %s mode' ,
app . get ( 'port' ) ,
app . get ( 'env' )
) ;
2014-11-19 23:30:36 +00:00
} ) ;
module . exports = app ;