mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-27 17:45:40 -05:00
371 lines
12 KiB
JavaScript
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);
|