2014-03-02 14:45:57 -05:00
|
|
|
"use strict";
|
|
|
|
|
|
2016-08-26 18:50:37 +03:00
|
|
|
var async = require('async');
|
|
|
|
|
var fs = require('fs');
|
|
|
|
|
var path = require('path');
|
|
|
|
|
var csrf = require('csurf');
|
|
|
|
|
var validator = require('validator');
|
|
|
|
|
var nconf = require('nconf');
|
|
|
|
|
var ensureLoggedIn = require('connect-ensure-login');
|
|
|
|
|
var toobusy = require('toobusy-js');
|
|
|
|
|
|
|
|
|
|
var plugins = require('../plugins');
|
|
|
|
|
var languages = require('../languages');
|
|
|
|
|
var meta = require('../meta');
|
|
|
|
|
var user = require('../user');
|
|
|
|
|
var groups = require('../groups');
|
|
|
|
|
|
|
|
|
|
var analytics = require('../analytics');
|
|
|
|
|
|
|
|
|
|
var controllers = {
|
|
|
|
|
api: require('./../controllers/api'),
|
|
|
|
|
helpers: require('../controllers/helpers')
|
|
|
|
|
};
|
2014-03-01 17:26:26 -05:00
|
|
|
|
2014-04-15 02:16:03 -04:00
|
|
|
var middleware = {};
|
2014-03-05 17:06:24 -05:00
|
|
|
|
2016-08-26 18:50:37 +03:00
|
|
|
middleware.applyCSRF = csrf();
|
|
|
|
|
|
|
|
|
|
middleware.ensureLoggedIn = ensureLoggedIn.ensureLoggedIn(nconf.get('relative_path') + '/login');
|
|
|
|
|
|
|
|
|
|
require('./admin')(middleware);
|
|
|
|
|
require('./header')(middleware);
|
|
|
|
|
require('./render')(middleware);
|
|
|
|
|
require('./maintenance')(middleware);
|
|
|
|
|
require('./user')(middleware);
|
|
|
|
|
require('./headers')(middleware);
|
|
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
middleware.authenticate = function (req, res, next) {
|
2016-08-26 18:50:37 +03:00
|
|
|
if (req.user) {
|
|
|
|
|
return next();
|
|
|
|
|
} else if (plugins.hasListeners('action:middleware.authenticate')) {
|
|
|
|
|
return plugins.fireHook('action:middleware.authenticate', {
|
|
|
|
|
req: req,
|
|
|
|
|
res: res,
|
|
|
|
|
next: next
|
|
|
|
|
});
|
2014-10-17 19:37:09 -04:00
|
|
|
}
|
|
|
|
|
|
2016-08-26 18:50:37 +03:00
|
|
|
controllers.helpers.notAllowed(req, res);
|
|
|
|
|
};
|
2014-11-19 17:48:43 -05:00
|
|
|
|
2016-12-02 09:49:52 -05:00
|
|
|
middleware.ensureGlobalPrivilege = function (req, res, next) {
|
|
|
|
|
if (req.user) {
|
|
|
|
|
user.isAdminOrGlobalMod(req.uid, function (err, ok) {
|
|
|
|
|
if (ok) {
|
|
|
|
|
return next();
|
|
|
|
|
} else {
|
|
|
|
|
controllers.helpers.notAllowed(req, res);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
controllers.helpers.notAllowed(req, res);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
middleware.pageView = function (req, res, next) {
|
2016-08-26 18:50:37 +03:00
|
|
|
analytics.pageView({
|
|
|
|
|
ip: req.ip,
|
|
|
|
|
path: req.path,
|
2016-08-26 18:55:44 +03:00
|
|
|
uid: req.uid
|
2016-08-26 18:50:37 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
plugins.fireHook('action:middleware.pageView', {req: req});
|
|
|
|
|
|
|
|
|
|
if (req.user) {
|
|
|
|
|
user.updateLastOnlineTime(req.user.uid);
|
|
|
|
|
if (req.path.startsWith('/api/users') || req.path.startsWith('/users')) {
|
|
|
|
|
user.updateOnlineUsers(req.user.uid, next);
|
|
|
|
|
} else {
|
|
|
|
|
user.updateOnlineUsers(req.user.uid);
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
};
|
2014-03-02 14:16:16 -05:00
|
|
|
|
2014-05-05 16:56:01 -04:00
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
middleware.pluginHooks = function (req, res, next) {
|
|
|
|
|
async.each(plugins.loadedHooks['filter:router.page'] || [], function (hookObj, next) {
|
2016-08-26 18:50:37 +03:00
|
|
|
hookObj.method(req, res, next);
|
2016-10-13 11:43:39 +02:00
|
|
|
}, function () {
|
2016-08-26 18:50:37 +03:00
|
|
|
// If it got here, then none of the subscribed hooks did anything, or there were no hooks
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
};
|
2014-03-01 17:26:26 -05:00
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
middleware.validateFiles = function (req, res, next) {
|
2016-08-26 18:50:37 +03:00
|
|
|
if (!Array.isArray(req.files.files) || !req.files.files.length) {
|
|
|
|
|
return next(new Error(['[[error:invalid-files]]']));
|
|
|
|
|
}
|
2014-03-01 17:26:26 -05:00
|
|
|
|
2016-08-26 18:50:37 +03:00
|
|
|
next();
|
|
|
|
|
};
|
2014-10-22 18:25:57 -04:00
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
middleware.prepareAPI = function (req, res, next) {
|
2016-08-26 18:50:37 +03:00
|
|
|
res.locals.isAPI = true;
|
|
|
|
|
next();
|
|
|
|
|
};
|
|
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
middleware.routeTouchIcon = function (req, res) {
|
2016-08-26 18:50:37 +03:00
|
|
|
if (meta.config['brand:touchIcon'] && validator.isURL(meta.config['brand:touchIcon'])) {
|
|
|
|
|
return res.redirect(meta.config['brand:touchIcon']);
|
|
|
|
|
} else {
|
|
|
|
|
return res.sendFile(path.join(__dirname, '../../public', meta.config['brand:touchIcon'] || '/logo.png'), {
|
|
|
|
|
maxAge: req.app.enabled('cache') ? 5184000000 : 0
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
2014-03-01 17:26:26 -05:00
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
middleware.privateTagListing = function (req, res, next) {
|
2016-08-26 18:50:37 +03:00
|
|
|
if (!req.user && parseInt(meta.config.privateTagListing, 10) === 1) {
|
|
|
|
|
controllers.helpers.notAllowed(req, res);
|
|
|
|
|
} else {
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
};
|
2014-03-01 17:26:26 -05:00
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
middleware.exposeGroupName = function (req, res, next) {
|
2016-09-14 21:21:32 +03:00
|
|
|
expose('groupName', groups.getGroupNameByGroupSlug, 'slug', req, res, next);
|
|
|
|
|
};
|
|
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
middleware.exposeUid = function (req, res, next) {
|
2016-09-14 21:21:32 +03:00
|
|
|
expose('uid', user.getUidByUserslug, 'userslug', req, res, next);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function expose(exposedField, method, field, req, res, next) {
|
|
|
|
|
if (!req.params.hasOwnProperty(field)) {
|
|
|
|
|
return next();
|
|
|
|
|
}
|
2016-10-13 11:43:39 +02:00
|
|
|
method(req.params[field], function (err, id) {
|
2016-09-14 21:21:32 +03:00
|
|
|
if (err) {
|
|
|
|
|
return next(err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res.locals[exposedField] = id;
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
middleware.privateUploads = function (req, res, next) {
|
2016-08-26 18:50:37 +03:00
|
|
|
if (req.user || parseInt(meta.config.privateUploads, 10) !== 1) {
|
|
|
|
|
return next();
|
2014-07-24 22:26:19 +02:00
|
|
|
}
|
2016-08-26 18:50:37 +03:00
|
|
|
if (req.path.startsWith('/uploads/files')) {
|
|
|
|
|
return res.status(403).json('not-allowed');
|
|
|
|
|
}
|
|
|
|
|
next();
|
|
|
|
|
};
|
2014-08-13 16:03:33 -04:00
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
middleware.busyCheck = function (req, res, next) {
|
2016-08-26 18:50:37 +03:00
|
|
|
if (global.env === 'production' && (!meta.config.hasOwnProperty('eventLoopCheckEnabled') || parseInt(meta.config.eventLoopCheckEnabled, 10) === 1) && toobusy()) {
|
|
|
|
|
analytics.increment('errors:503');
|
|
|
|
|
res.status(503).type('text/html').sendFile(path.join(__dirname, '../../public/503.html'));
|
|
|
|
|
} else {
|
|
|
|
|
next();
|
2015-08-17 14:53:37 -04:00
|
|
|
}
|
2016-08-26 18:50:37 +03:00
|
|
|
};
|
|
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
middleware.applyBlacklist = function (req, res, next) {
|
|
|
|
|
meta.blacklist.test(req.ip, function (err) {
|
2016-08-26 18:50:37 +03:00
|
|
|
next(err);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2016-11-23 09:50:49 -07:00
|
|
|
middleware.getTranslation = function (req, res, next) {
|
|
|
|
|
var language = req.params.language;
|
|
|
|
|
var namespace = req.params.namespace;
|
2016-06-24 16:57:58 -04:00
|
|
|
|
2016-11-23 09:50:49 -07:00
|
|
|
if (language && namespace) {
|
|
|
|
|
languages.get(language, namespace, function (err, translations) {
|
2016-08-26 18:50:37 +03:00
|
|
|
if (err) {
|
|
|
|
|
return next(err);
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-23 09:50:49 -07:00
|
|
|
res.status(200).json(translations);
|
2016-08-26 18:50:37 +03:00
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
res.status(404).json('{}');
|
2016-05-18 18:43:46 +02:00
|
|
|
}
|
2016-08-26 18:50:37 +03:00
|
|
|
};
|
2015-08-17 14:53:37 -04:00
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
middleware.processTimeagoLocales = function (req, res, next) {
|
2016-08-26 18:50:37 +03:00
|
|
|
var fallback = req.path.indexOf('-short') === -1 ? 'jquery.timeago.en.js' : 'jquery.timeago.en-short.js',
|
|
|
|
|
localPath = path.join(__dirname, '../../public/vendor/jquery/timeago/locales', req.path),
|
|
|
|
|
exists;
|
2014-03-01 17:26:26 -05:00
|
|
|
|
2016-08-26 18:50:37 +03:00
|
|
|
try {
|
|
|
|
|
exists = fs.accessSync(localPath, fs.F_OK | fs.R_OK);
|
|
|
|
|
} catch(e) {
|
|
|
|
|
exists = false;
|
|
|
|
|
}
|
2014-03-02 14:16:16 -05:00
|
|
|
|
2016-08-26 18:50:37 +03:00
|
|
|
if (exists) {
|
|
|
|
|
res.status(200).sendFile(localPath, {
|
|
|
|
|
maxAge: req.app.enabled('cache') ? 5184000000 : 0
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
res.status(200).sendFile(path.join(__dirname, '../../public/vendor/jquery/timeago/locales', fallback), {
|
|
|
|
|
maxAge: req.app.enabled('cache') ? 5184000000 : 0
|
|
|
|
|
});
|
|
|
|
|
}
|
2014-04-10 20:31:57 +01:00
|
|
|
};
|
2016-08-26 18:50:37 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = middleware;
|