codecombat/server_setup.js
2016-03-29 14:18:41 -04:00

371 lines
12 KiB
JavaScript

// Generated by CoffeeScript 1.10.0
(function() {
var Mandate, Promise, UserHandler, auth, authentication, baseRoute, compressible, config, database, developmentLogging, errors, express, fs, geoip, log, logging, path, perfmon, productionLogging, request, routes, setupCountryRedirectMiddleware, setupErrorMiddleware, setupExpressMiddleware, setupFacebookCrossDomainCommunicationRoute, setupFallbackRouteToIndex, setupJavascript404s, setupMiddlewareToSendOldBrowserWarningWhenPlayersViewLevelDirectly, setupOneSecondDelayMiddleware, setupPassportMiddleware, setupPerfMonMiddleware, setupRedirectMiddleware, slack, user, useragent;
express = require('express');
path = require('path');
authentication = require('passport');
useragent = require('express-useragent');
fs = require('graceful-fs');
log = require('winston');
compressible = require('compressible');
geoip = require('geoip-lite');
database = require('./server/commons/database');
perfmon = require('./server/commons/perfmon');
baseRoute = require('./server/routes/base');
user = require('./server/users/user_handler');
logging = require('./server/commons/logging');
config = require('./server_config');
auth = require('./server/routes/auth');
routes = require('./server/routes');
UserHandler = require('./server/users/user_handler');
slack = require('./server/slack');
Mandate = require('./server/models/Mandate');
global.tv4 = require('tv4');
global.jsondiffpatch = require('jsondiffpatch');
global.stripe = require('stripe')(config.stripe.secretKey);
errors = require('./server/commons/errors');
request = require('request');
Promise = require('bluebird');
Promise.promisifyAll(request, {
multiArgs: true
});
productionLogging = function(tokens, req, res) {
var color, elapsed, elapsedColor, status;
status = res.statusCode;
color = 32;
if (status >= 500) {
color = 31;
} else if (status >= 400) {
color = 33;
} else if (status >= 300) {
color = 36;
}
elapsed = (new Date()) - req._startTime;
elapsedColor = elapsed < 500 ? 90 : 31;
if (status === 404 && /\/feedback/.test(req.originalUrl)) {
return null;
}
if ((status !== 200 && status !== 201 && status !== 204 && status !== 304 && status !== 302) || elapsed > 500) {
return "\x1b[90m" + req.method + " " + req.originalUrl + " \x1b[" + color + "m" + res.statusCode + " \x1b[" + elapsedColor + "m" + elapsed + "ms\x1b[0m";
}
return null;
};
developmentLogging = function(tokens, req, res) {
var color, elapsed, elapsedColor, status;
status = res.statusCode;
color = 32;
if (status >= 500) {
color = 31;
} else if (status >= 400) {
color = 33;
} else if (status >= 300) {
color = 36;
}
elapsed = (new Date()) - req._startTime;
elapsedColor = elapsed < 500 ? 90 : 31;
return "\x1b[90m" + req.method + " " + req.originalUrl + " \x1b[" + color + "m" + res.statusCode + " \x1b[" + elapsedColor + "m" + elapsed + "ms\x1b[0m";
};
setupErrorMiddleware = function(app) {
return app.use(function(err, req, res, next) {
var message, ref, ref1;
if (err) {
if (err.name === 'MongoError' && err.code === 11000) {
err = new errors.Conflict('MongoDB conflict error.');
}
if (err.code === 422 && err.response) {
err = new errors.UnprocessableEntity(err.response);
}
if (err.code === 409 && err.response) {
err = new errors.Conflict(err.response);
}
if (err instanceof errors.NetworkError) {
return res.status(err.code).send(err.toJSON());
}
if (err.status && (400 <= (ref = err.status) && ref < 500)) {
res.status(err.status).send("Error " + err.status);
return;
}
res.status((ref1 = err.status) != null ? ref1 : 500).send({
error: "Something went wrong!"
});
message = "Express error: " + req.method + " " + req.path + ": " + err.message;
log.error(message + ", stack: " + err.stack);
return slack.sendSlackMessage(message, ['ops'], {
papertrail: true
});
} else {
return next(err);
}
});
};
setupExpressMiddleware = function(app) {
if (config.isProduction) {
express.logger.format('prod', productionLogging);
app.use(express.logger('prod'));
app.use(express.compress({
filter: function(req, res) {
if (req.headers.host === 'codecombat.com') {
return false;
}
return compressible(res.getHeader('Content-Type'));
}
}));
} else {
express.logger.format('dev', developmentLogging);
app.use(express.logger('dev'));
}
app.use(express["static"](path.join(__dirname, 'public'), {
maxAge: 0
}));
app.use(useragent.express());
app.use(express.favicon());
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.methodOverride());
return app.use(express.cookieSession({
key: 'codecombat.sess',
secret: config.cookie_secret
}));
};
setupPassportMiddleware = function(app) {
app.use(authentication.initialize());
if (config.picoCTF) {
app.use(authentication.authenticate('local', {
failureRedirect: config.picoCTF_login_URL
}));
return require('./server/lib/picoctf').init(app);
} else {
return app.use(authentication.session());
}
};
setupCountryRedirectMiddleware = function(app, country, countryCode, languageCode, serverID) {
var shouldRedirectToCountryServer;
if (country == null) {
country = "china";
}
if (countryCode == null) {
countryCode = "CN";
}
if (languageCode == null) {
languageCode = "zh";
}
if (serverID == null) {
serverID = "tokyo";
}
shouldRedirectToCountryServer = function(req) {
var geo, ip, speaksLanguage;
speaksLanguage = _.any(req.acceptedLanguages, function(language) {
return language.indexOf(languageCode !== -1);
});
if (!config[serverID]) {
ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
ip = ip != null ? ip.split(/,? /)[0] : void 0;
geo = geoip.lookup(ip);
return (geo != null ? geo.country : void 0) === countryCode && speaksLanguage;
} else {
if (speaksLanguage) {
req.country = country;
}
return false;
}
};
return app.use(function(req, res, next) {
if (shouldRedirectToCountryServer(req)) {
res.writeHead(302, {
"Location": config[country + 'Domain'] + req.url
});
return res.end();
} else {
return next();
}
});
};
setupOneSecondDelayMiddleware = function(app) {
if (config.slow_down) {
return app.use(function(req, res, next) {
return setTimeout((function() {
return next();
}), 1000);
});
}
};
setupMiddlewareToSendOldBrowserWarningWhenPlayersViewLevelDirectly = function(app) {
var isOldBrowser;
isOldBrowser = function(req) {
var b, ref, ua, v;
if (!(ua = req.useragent)) {
return false;
}
if (ua.isiPad || ua.isiPod || ua.isiPhone || ua.isOpera) {
return true;
}
if (!(ua && ((ref = ua.Browser) === 'Chrome' || ref === 'Safari' || ref === 'Firefox' || ref === 'IE') && ua.Version)) {
return false;
}
b = ua.Browser;
v = parseInt(ua.Version.split('.')[0], 10);
if (b === 'Chrome' && v < 17) {
return true;
}
if (b === 'Safari' && v < 6) {
return true;
}
if (b === 'Firefox' && v < 21) {
return true;
}
if (b === 'IE' && v < 10) {
return true;
}
return false;
};
return app.use('/play/', function(req, res, next) {
if (req.query['try-old-browser-anyway'] || !isOldBrowser(req)) {
return next();
}
return res.sendfile(path.join(__dirname, 'public', 'index_old_browser.html'));
});
};
setupRedirectMiddleware = function(app) {
return app.all('/account/profile/*', function(req, res, next) {
var nameOrID;
nameOrID = req.path.split('/')[3];
return res.redirect(301, "/user/" + nameOrID + "/profile");
});
};
setupPerfMonMiddleware = function(app) {
return app.use(perfmon.middleware);
};
exports.setupMiddleware = function(app) {
setupPerfMonMiddleware(app);
setupCountryRedirectMiddleware(app, "china", "CN", "zh", "tokyo");
setupCountryRedirectMiddleware(app, "brazil", "BR", "pt-BR", "saoPaulo");
setupMiddlewareToSendOldBrowserWarningWhenPlayersViewLevelDirectly(app);
setupExpressMiddleware(app);
setupPassportMiddleware(app);
setupOneSecondDelayMiddleware(app);
setupRedirectMiddleware(app);
setupErrorMiddleware(app);
return setupJavascript404s(app);
};
/*Routing function implementations */
setupJavascript404s = function(app) {
return app.get('/javascripts/*', function(req, res) {
return res.status(404).send('Not found');
});
};
setupFallbackRouteToIndex = function(app) {
return app.all('*', function(req, res) {
return fs.readFile(path.join(__dirname, 'public', 'main.html'), 'utf8', function(err, data) {
if (err) {
log.error("Error modifying main.html: " + err);
}
user = req.user ? JSON.stringify(UserHandler.formatEntity(req, req.user)).replace(/\//g, '\\/') : '{}';
return Mandate.findOne({}).cache(5 * 60 * 1000).exec(function(err, mandate) {
var configData;
if (err) {
log.error("Error getting mandate config: " + err);
configData = {};
} else {
configData = _.omit((mandate != null ? mandate.toObject() : void 0) || {}, '_id');
}
configData.picoCTF = config.picoCTF;
configData.production = config.isProduction;
data = data.replace('"serverConfigTag"', JSON.stringify(configData));
data = data.replace('"userObjectTag"', user);
data = data.replace('"amActuallyTag"', JSON.stringify(req.session.amActually));
res.header('Cache-Control', 'no-cache, no-store, must-revalidate');
res.header('Pragma', 'no-cache');
res.header('Expires', 0);
return res.send(200, data);
});
});
});
};
setupFacebookCrossDomainCommunicationRoute = function(app) {
return app.get('/channel.html', function(req, res) {
return res.sendfile(path.join(__dirname, 'public', 'channel.html'));
});
};
exports.setupRoutes = function(app) {
routes.setup(app);
app.use(app.router);
baseRoute.setup(app);
setupFacebookCrossDomainCommunicationRoute(app);
return setupFallbackRouteToIndex(app);
};
/*Miscellaneous configuration functions */
exports.setupLogging = function() {
return logging.setup();
};
exports.connectToDatabase = function() {
return database.connect();
};
exports.setupMailchimp = function() {
var mc, mcapi;
mcapi = require('mailchimp-api');
mc = new mcapi.Mailchimp(config.mail.mailchimpAPIKey);
return GLOBAL.mc = mc;
};
exports.setExpressConfigurationOptions = function(app) {
app.set('port', config.port);
app.set('views', __dirname + '/app/views');
app.set('view engine', 'jade');
app.set('view options', {
layout: false
});
app.set('env', config.isProduction ? 'production' : 'development');
if (config.isProduction) {
return app.set('json spaces', 0);
}
};
}).call(this);