| 
									
										
										
										
											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 10:50:42 -05:00
										 |  |  | middleware.ensureSelfOrGlobalPrivilege = function (req, res, next) { | 
					
						
							|  |  |  | 	/* | 
					
						
							|  |  |  | 		The "self" part of this middleware hinges on you having used | 
					
						
							|  |  |  | 		middleware.exposeUid prior to invoking this middleware. | 
					
						
							|  |  |  | 	*/ | 
					
						
							| 
									
										
										
										
											2016-12-02 09:49:52 -05:00
										 |  |  | 	if (req.user) { | 
					
						
							| 
									
										
										
										
											2016-12-02 10:50:42 -05:00
										 |  |  | 		if (req.user.uid === res.locals.uid) { | 
					
						
							|  |  |  | 			return next(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-02 09:49:52 -05:00
										 |  |  | 		user.isAdminOrGlobalMod(req.uid, function (err, ok) { | 
					
						
							| 
									
										
										
										
											2016-12-02 10:07:33 -05:00
										 |  |  | 			if (err) { | 
					
						
							|  |  |  | 				return next(err); | 
					
						
							|  |  |  | 			} else if (ok) { | 
					
						
							| 
									
										
										
										
											2016-12-02 09:49:52 -05:00
										 |  |  | 				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; | 
					
						
							| 
									
										
										
										
											2017-01-07 22:48:57 -07:00
										 |  |  | 	var namespace = req.params[0]; | 
					
						
							| 
									
										
										
										
											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; |