2014-01-27 18:36:35 -05:00
|
|
|
express = require 'express'
|
|
|
|
path = require 'path'
|
2014-02-04 17:08:20 -05:00
|
|
|
authentication = require 'passport'
|
2014-01-27 18:36:35 -05:00
|
|
|
useragent = require 'express-useragent'
|
|
|
|
fs = require 'graceful-fs'
|
2014-04-17 13:12:23 -04:00
|
|
|
log = require 'winston'
|
|
|
|
compressible = require 'compressible'
|
2014-01-27 18:36:35 -05:00
|
|
|
|
2014-02-04 15:30:05 -05:00
|
|
|
database = require './server/commons/database'
|
2014-02-04 16:29:13 -05:00
|
|
|
baseRoute = require './server/routes/base'
|
2014-01-27 18:36:35 -05:00
|
|
|
user = require './server/users/user_handler'
|
|
|
|
logging = require './server/commons/logging'
|
|
|
|
config = require './server_config'
|
2014-04-02 16:12:24 -04:00
|
|
|
auth = require './server/routes/auth'
|
2014-04-17 13:12:23 -04:00
|
|
|
UserHandler = require './server/users/user_handler'
|
2014-01-27 18:36:35 -05:00
|
|
|
|
2014-03-15 10:08:22 -04:00
|
|
|
productionLogging = (tokens, req, res) ->
|
2014-03-01 15:18:21 -05:00
|
|
|
status = res.statusCode
|
2014-03-03 11:10:36 -05:00
|
|
|
color = 32
|
|
|
|
if status >= 500 then color = 31
|
|
|
|
else if status >= 400 then color = 33
|
|
|
|
else if status >= 300 then color = 36
|
|
|
|
elapsed = (new Date()) - req._startTime
|
|
|
|
elapsedColor = if elapsed < 500 then 90 else 31
|
2014-05-22 00:56:11 -04:00
|
|
|
if (status isnt 200 and status isnt 204 and status isnt 304 and status isnt 302) or elapsed > 500
|
2014-03-03 11:10:36 -05:00
|
|
|
return "\x1b[90m#{req.method} #{req.originalUrl} \x1b[#{color}m#{res.statusCode} \x1b[#{elapsedColor}m#{elapsed}ms\x1b[0m"
|
|
|
|
null
|
2014-03-01 15:18:21 -05:00
|
|
|
|
2014-01-27 18:36:35 -05:00
|
|
|
setupExpressMiddleware = (app) ->
|
2014-03-03 11:10:36 -05:00
|
|
|
if config.isProduction
|
|
|
|
express.logger.format('prod', productionLogging)
|
|
|
|
app.use(express.logger('prod'))
|
2014-04-17 13:12:23 -04:00
|
|
|
app.use express.compress filter: (req, res) ->
|
|
|
|
return false if req.headers.host is 'codecombat.com' # Cloudflare will gzip it for us on codecombat.com
|
|
|
|
compressible res.getHeader('Content-Type')
|
2014-03-03 11:10:36 -05:00
|
|
|
else
|
|
|
|
app.use(express.logger('dev'))
|
2014-01-27 18:36:35 -05:00
|
|
|
app.use(express.static(path.join(__dirname, 'public')))
|
|
|
|
app.use(useragent.express())
|
|
|
|
|
|
|
|
app.use(express.favicon())
|
|
|
|
app.use(express.cookieParser(config.cookie_secret))
|
|
|
|
app.use(express.bodyParser())
|
|
|
|
app.use(express.methodOverride())
|
|
|
|
app.use(express.cookieSession({secret:'defenestrate'}))
|
|
|
|
|
|
|
|
setupPassportMiddleware = (app) ->
|
2014-02-04 17:08:20 -05:00
|
|
|
app.use(authentication.initialize())
|
|
|
|
app.use(authentication.session())
|
2014-01-27 18:36:35 -05:00
|
|
|
|
2014-06-08 12:35:59 -04:00
|
|
|
setupOneSecondDelayMiddleware = (app) ->
|
2014-01-27 18:36:35 -05:00
|
|
|
if(config.slow_down)
|
|
|
|
app.use((req, res, next) -> setTimeout((-> next()), 1000))
|
|
|
|
|
|
|
|
setupMiddlewareToSendOldBrowserWarningWhenPlayersViewLevelDirectly = (app) ->
|
|
|
|
isOldBrowser = (req) ->
|
|
|
|
# https://github.com/biggora/express-useragent/blob/master/lib/express-useragent.js
|
|
|
|
return false unless ua = req.useragent
|
|
|
|
return true if ua.isiPad or ua.isiPod or ua.isiPhone or ua.isOpera
|
2014-06-30 22:16:26 -04:00
|
|
|
return false unless ua and ua.Browser in ['Chrome', 'Safari', 'Firefox', 'IE'] and ua.Version
|
2014-01-27 18:36:35 -05:00
|
|
|
b = ua.Browser
|
|
|
|
v = parseInt ua.Version.split('.')[0], 10
|
|
|
|
return true if b is 'Chrome' and v < 17
|
|
|
|
return true if b is 'Safari' and v < 6
|
|
|
|
return true if b is 'Firefox' and v < 21
|
|
|
|
return true if b is 'IE' and v < 10
|
|
|
|
false
|
|
|
|
|
|
|
|
app.use '/play/', (req, res, next) ->
|
|
|
|
return next() if req.query['try-old-browser-anyway'] or not isOldBrowser req
|
|
|
|
res.sendfile(path.join(__dirname, 'public', 'index_old_browser.html'))
|
|
|
|
|
2014-07-13 16:34:32 -04:00
|
|
|
setupRedirectMiddleware = (app) ->
|
|
|
|
app.all '/account/profile/*', (req, res, next) ->
|
|
|
|
nameOrID = req.path.split('/')[3]
|
|
|
|
res.redirect 301, "/user/#{nameOrID}/profile"
|
|
|
|
|
2014-01-27 18:36:35 -05:00
|
|
|
exports.setupMiddleware = (app) ->
|
|
|
|
setupMiddlewareToSendOldBrowserWarningWhenPlayersViewLevelDirectly app
|
|
|
|
setupExpressMiddleware app
|
|
|
|
setupPassportMiddleware app
|
2014-06-08 12:35:59 -04:00
|
|
|
setupOneSecondDelayMiddleware app
|
2014-07-13 16:34:32 -04:00
|
|
|
setupRedirectMiddleware app
|
2014-01-27 18:36:35 -05:00
|
|
|
|
|
|
|
###Routing function implementations###
|
|
|
|
|
|
|
|
setupFallbackRouteToIndex = (app) ->
|
2014-03-12 13:07:18 -04:00
|
|
|
app.all '*', (req, res) ->
|
2014-04-02 16:12:24 -04:00
|
|
|
if req.user
|
|
|
|
sendMain(req, res)
|
|
|
|
else
|
|
|
|
user = auth.makeNewUser(req)
|
|
|
|
makeNext = (req, res) -> -> sendMain(req, res)
|
|
|
|
next = makeNext(req, res)
|
|
|
|
auth.loginUser(req, res, user, false, next)
|
|
|
|
|
|
|
|
sendMain = (req, res) ->
|
2014-04-05 20:05:03 -04:00
|
|
|
fs.readFile path.join(__dirname, 'public', 'main.html'), 'utf8', (err, data) ->
|
|
|
|
log.error "Error modifying main.html: #{err}" if err
|
2014-05-19 18:13:09 -04:00
|
|
|
# insert the user object directly into the html so the application can have it immediately. Sanitize </script>
|
2014-05-21 14:12:46 -04:00
|
|
|
data = data.replace('"userObjectTag"', JSON.stringify(UserHandler.formatEntity(req, req.user)).replace(/\//g, '\\/'))
|
2014-06-30 22:16:26 -04:00
|
|
|
res.header 'Cache-Control', 'no-cache, no-store, must-revalidate'
|
|
|
|
res.header 'Pragma', 'no-cache'
|
|
|
|
res.header 'Expires', 0
|
2014-06-11 12:52:36 -04:00
|
|
|
res.send 200, data
|
2014-01-27 18:36:35 -05:00
|
|
|
|
|
|
|
setupFacebookCrossDomainCommunicationRoute = (app) ->
|
|
|
|
app.get '/channel.html', (req, res) ->
|
|
|
|
res.sendfile path.join(__dirname, 'public', 'channel.html')
|
|
|
|
|
|
|
|
exports.setupRoutes = (app) ->
|
|
|
|
app.use app.router
|
2014-02-05 12:42:25 -05:00
|
|
|
|
2014-02-04 16:29:13 -05:00
|
|
|
baseRoute.setup app
|
2014-01-27 18:36:35 -05:00
|
|
|
setupFacebookCrossDomainCommunicationRoute app
|
|
|
|
setupFallbackRouteToIndex app
|
|
|
|
|
|
|
|
###Miscellaneous configuration functions###
|
|
|
|
|
|
|
|
exports.setupLogging = ->
|
|
|
|
logging.setup()
|
|
|
|
|
|
|
|
exports.connectToDatabase = ->
|
2014-02-04 15:30:05 -05:00
|
|
|
database.connect()
|
2014-01-27 18:36:35 -05:00
|
|
|
|
|
|
|
exports.setupMailchimp = ->
|
|
|
|
mcapi = require 'mailchimp-api'
|
|
|
|
mc = new mcapi.Mailchimp(config.mail.mailchimpAPIKey)
|
|
|
|
GLOBAL.mc = mc
|
|
|
|
|
|
|
|
exports.setExpressConfigurationOptions = (app) ->
|
|
|
|
app.set('port', config.port)
|
|
|
|
app.set('views', __dirname + '/app/views')
|
|
|
|
app.set('view engine', 'jade')
|
|
|
|
app.set('view options', { layout: false })
|
2014-03-03 19:19:35 -05:00
|
|
|
app.set('env', if config.isProduction then 'production' else 'development')
|
|
|
|
app.set('json spaces', 0)
|