From 4b005a4037d1356bd04aba72ac1183f7faa0b48d Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 2 Jul 2014 15:01:14 -0400 Subject: [PATCH 01/10] crash fix --- src/postTools.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/postTools.js b/src/postTools.js index b7361f14ee..97d3e71928 100644 --- a/src/postTools.js +++ b/src/postTools.js @@ -54,7 +54,7 @@ var winston = require('winston'), if (err) { return next(err); } - + options.tags = options.tags || []; if (isMainPost) { title = title.trim(); From 24ebf20d7eb8ac8be32effafcb071bf40fa6f7d2 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 2 Jul 2014 14:07:08 -0400 Subject: [PATCH 02/10] first commit --- package.json | 14 ++++- public/src/templates.js | 15 +++--- src/database/mongo.js | 4 +- src/database/redis.js | 4 +- src/install.js | 2 +- src/logger.js | 5 +- src/middleware/index.js | 90 ++++++++++++++++--------------- src/routes/api.js | 23 ++++---- src/routes/debug.js | 87 +++++++++++++++--------------- src/routes/index.js | 116 +++++++++++++++++++++++++++++----------- src/socket.io/index.js | 5 +- src/webserver.js | 1 - 12 files changed, 219 insertions(+), 147 deletions(-) diff --git a/package.json b/package.json index 761b21a0fe..c503019f29 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,7 @@ "connect-flash": "^0.1.1", "cron": "~1.0.4", "daemon": "~1.1.0", - "express": "3.2.0", - "express-namespace": "~0.1.1", + "express": "4.4.5", "gm": "1.14.2", "gravatar": "1.0.6", "less": "~1.6.3", @@ -41,6 +40,17 @@ "prompt": "~0.2.11", "request": "~2.34.0", "rimraf": "~2.2.6", + + + "cookie-parser": "^1.0.1", + "body-parser": "^1.0.1", + "serve-favicon": "^2.0.1", + "express-session": "^1.0.2", + "csurf": "^1.1.0", + "compression": "^1.0.1", + + "morgan": "^1.0.0", + "rss": "~0.2.0", "semver": "~2.2.1", "sitemap": "~0.7.3", diff --git a/public/src/templates.js b/public/src/templates.js index 3d02dfcc87..5cf10aeb4b 100644 --- a/public/src/templates.js +++ b/public/src/templates.js @@ -36,7 +36,7 @@ Please use the npm module instead - require('templates.js') } callback(parse(loaded, obj, bind)); - }); + }); } else { callback(parse(templates.cache[template], obj, bind)); } @@ -62,6 +62,7 @@ Please use the npm module instead - require('templates.js') }; function express(filename, options, fn) { + console.log(filename, options, fn); var fs = require('fs'), tpl = filename.replace(options.settings.views + '/', ''); @@ -185,7 +186,7 @@ Please use the npm module instead - require('templates.js') while (block = template.match(regex)) { block = block[0].replace(makeBlockRegex(key), ''); - + var numblocks = array[key].length - 1, iterator = 0, result = '', @@ -193,7 +194,7 @@ Please use the npm module instead - require('templates.js') do { parsedBlock = parse(block, array[key][iterator], bind, namespace, {iterator: iterator, total: numblocks}) + ((iterator < numblocks) ? '\r\n':''); - + result += (!bind) ? parsedBlock : setBindContainer(parsedBlock, bind + namespace + iterator); result = parseFunctions(block, result, { data: array[key][iterator], @@ -213,7 +214,7 @@ Please use the npm module instead - require('templates.js') template = template.replace(regex, result); } - + return template; } @@ -247,14 +248,14 @@ Please use the npm module instead - require('templates.js') this['__' + key] = value; var els = document.querySelectorAll('[data-binding="' + (this.__iterator !== false ? (bind + this.__namespace + this.__iterator) : bind) + '"]'); - + for (var el in els) { if (els.hasOwnProperty(el)) { if (this.__parent) { var parent = this.__parent(); els[el].innerHTML = parse(parent.template, parent.data, false); } else { - els[el].innerHTML = parse(this.__template, obj, false, this.__namespace); + els[el].innerHTML = parse(this.__template, obj, false, this.__namespace); } } } @@ -294,7 +295,7 @@ Please use the npm module instead - require('templates.js') template = parse(template, obj[key], bind, namespace + key + '.'); } else { template = parseValue(template, namespace + key, obj[key]); - + if (bind && obj[key]) { setupBindings({ obj: obj, diff --git a/src/database/mongo.js b/src/database/mongo.js index 5b25ae9284..a9f765e1dd 100644 --- a/src/database/mongo.js +++ b/src/database/mongo.js @@ -6,7 +6,7 @@ var winston = require('winston'), async = require('async'), nconf = require('nconf'), - express = require('express'), + session = require('express-session'), db, mongoClient, mongoStore; @@ -41,7 +41,7 @@ module.init = function(callback) { try { mongoClient = require('mongodb').MongoClient; - mongoStore = require('connect-mongo')(express); + mongoStore = require('connect-mongo')({session: session}); } catch (err) { winston.error('Unable to initialize MongoDB! Is MongoDB installed? Error :' + err.message); process.exit(); diff --git a/src/database/redis.js b/src/database/redis.js index 2c0e9bd1cc..078f0a54d6 100644 --- a/src/database/redis.js +++ b/src/database/redis.js @@ -5,7 +5,7 @@ var winston = require('winston'), nconf = require('nconf'), path = require('path'), - express = require('express'), + session = require('express-session'), utils = require('./../../public/src/utils.js'), redis, connectRedis, @@ -40,7 +40,7 @@ module.init = function(callback) { try { redis = require('redis'); - connectRedis = require('connect-redis')(express); + connectRedis = require('connect-redis')({session: session}); reds = require('reds'); } catch (err) { winston.error('Unable to initialize Redis! Is Redis installed? Error :' + err.message); diff --git a/src/install.js b/src/install.js index b6d062cbb0..15005e8999 100644 --- a/src/install.js +++ b/src/install.js @@ -11,7 +11,7 @@ var async = require('async'), DATABASES = { "redis": { - "dependencies": ["redis@~0.10.1", "connect-redis@~1.4"] + "dependencies": ["redis@~0.10.1", "connect-redis@~2.0.0"] }, "mongo": { "dependencies": ["mongodb", "connect-mongo"] diff --git a/src/logger.js b/src/logger.js index 90926dd5fd..f1da65555e 100644 --- a/src/logger.js +++ b/src/logger.js @@ -10,7 +10,8 @@ var fs = require('fs'), winston = require('winston'), util = require('util'), socketio = require('socket.io'), - meta = require('./meta'); + meta = require('./meta'), + morgan = require('morgan'); var opts = { /* @@ -124,7 +125,7 @@ var opts = { /* * Always initialize "ofn" (original function) with the original logger function */ - opts.express.ofn = express.logger({stream : opts.streams.log.f}); + opts.express.ofn = morgan({stream : opts.streams.log.f}); }; Logger.expressLogger = function(req,res,next) { diff --git a/src/middleware/index.js b/src/middleware/index.js index 844e46cdd8..5131d0e449 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -15,6 +15,12 @@ var utils = require('./../../public/src/utils'), winston = require('winston'), flash = require('connect-flash'), templates = require('templates.js'), + bodyParser = require('body-parser'), + cookieParser = require('cookie-parser'), + compression = require('compression'), + favicon = require('serve-favicon'), + csrf = require('csurf'), + session = require('express-session'), relativePath, viewsPath, @@ -188,65 +194,63 @@ module.exports = function(app, data) { themesPath = nconf.get('themes_path'); baseTemplatesPath = nconf.get('base_templates_path'); - app.configure(function() { - app.engine('tpl', templates.__express); - app.set('view engine', 'tpl'); - app.set('views', viewsPath); - app.use(flash()); - app.enable('view cache'); + app.engine('tpl', templates.__express); + app.set('view engine', 'tpl'); + app.set('views', viewsPath); + app.use(flash()); - app.use(express.compress()); + app.enable('view cache'); - app.use(express.favicon(path.join(__dirname, '../../', 'public', meta.config['brand:favicon'] ? meta.config['brand:favicon'] : 'favicon.ico'))); - app.use(relativePath + '/apple-touch-icon', middleware.routeTouchIcon); + app.use(compression()); - app.use(express.bodyParser()); - app.use(express.cookieParser()); + app.use(favicon(path.join(__dirname, '../../', 'public', meta.config['brand:favicon'] ? meta.config['brand:favicon'] : 'favicon.ico'))); + app.use(relativePath + '/apple-touch-icon', middleware.routeTouchIcon); - app.use(express.session({ - store: db.sessionStore, - secret: nconf.get('secret'), - key: 'express.sid', - cookie: { - maxAge: 1000 * 60 * 60 * 24 * parseInt(meta.configs.loginDays || 14, 10) - } - })); + app.use(bodyParser()); + app.use(cookieParser()); - app.use(express.csrf()); // todo, make this a conditional middleware + app.use(session({ + store: db.sessionStore, + secret: nconf.get('secret'), + key: 'express.sid', + cookie: { + maxAge: 1000 * 60 * 60 * 24 * parseInt(meta.configs.loginDays || 14, 10) + } + })); - app.use(function (req, res, next) { - res.locals.csrf_token = req.session._csrf; - res.setHeader('X-Powered-By', 'NodeBB'); + app.use(csrf()); - res.setHeader('X-Frame-Options', 'SAMEORIGIN'); - if (meta.config['allow-from-uri']) { - res.setHeader('ALLOW-FROM', meta.config['allow-from-uri']); - } + app.use(function (req, res, next) { + res.locals.csrf_token = req.session._csrf; + res.setHeader('X-Powered-By', 'NodeBB'); - next(); - }); + res.setHeader('X-Frame-Options', 'SAMEORIGIN'); + if (meta.config['allow-from-uri']) { + res.setHeader('ALLOW-FROM', meta.config['allow-from-uri']); + } - app.use(middleware.processRender); + next(); + }); - auth.initialize(app); + app.use(middleware.processRender); - routeCurrentTheme(app, data.currentThemeId, data.themesData); - routeThemeScreenshots(app, data.themesData); + auth.initialize(app); - plugins.getTemplates(function(err, pluginTemplates) { - compileTemplates(pluginTemplates); - }); + routeCurrentTheme(app, data.currentThemeId, data.themesData); + routeThemeScreenshots(app, data.themesData); - app.use(relativePath, app.router); + plugins.getTemplates(function(err, pluginTemplates) { + compileTemplates(pluginTemplates); + }); - app.use(relativePath, express.static(path.join(__dirname, '../../', 'public'), { - maxAge: app.enabled('cache') ? 5184000000 : 0 - })); + app.use(relativePath, express.static(path.join(__dirname, '../../', 'public'), { + maxAge: app.enabled('cache') ? 5184000000 : 0 + })); + + //app.use(catch404); + //app.use(handleErrors); - app.use(catch404); - app.use(handleErrors); - }); return middleware; }; diff --git a/src/routes/api.js b/src/routes/api.js index 001cb5a01b..47e7b5f045 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -4,6 +4,7 @@ var path = require('path'), async = require('async'), fs = require('fs'), nconf = require('nconf'), + express = require('express'), user = require('../user'), topics = require('../topics'), @@ -178,17 +179,19 @@ function getRecentPosts(req, res, next) { } module.exports = function(app, middleware, controllers) { - app.namespace('/api', function () { - app.get('/config', controllers.api.getConfig); - app.get('/user/uid/:uid', middleware.checkGlobalPrivacySettings, controllers.accounts.getUserByUID); - app.get('/get_templates_listing', getTemplatesListing); - app.get('/categories/:cid/moderators', getModerators); - app.get('/recent/posts/:term?', getRecentPosts); + var router = express.Router(); - app.post('/post/upload', uploadPost); - app.post('/topic/thumb/upload', uploadThumb); - app.post('/user/:userslug/uploadpicture', middleware.authenticate, middleware.checkGlobalPrivacySettings, middleware.checkAccountPermissions, controllers.accounts.uploadPicture); - }); + router.get('/config', controllers.api.getConfig); + + router.get('/user/uid/:uid', middleware.checkGlobalPrivacySettings, controllers.accounts.getUserByUID); + router.get('/get_templates_listing', getTemplatesListing); + router.get('/categories/:cid/moderators', getModerators); + router.get('/recent/posts/:term?', getRecentPosts); + + router.post('/post/upload', uploadPost); + router.post('/topic/thumb/upload', uploadThumb); + router.post('/user/:userslug/uploadpicture', middleware.authenticate, middleware.checkGlobalPrivacySettings, middleware.checkAccountPermissions, controllers.accounts.uploadPicture); + app.use('/api', router); }; diff --git a/src/routes/debug.js b/src/routes/debug.js index ccaa4209a6..d0e24c5494 100644 --- a/src/routes/debug.js +++ b/src/routes/debug.js @@ -1,60 +1,63 @@ "use strict"; -var user = require('./../user'), +var express = require('express'), + user = require('./../user'), categories = require('./../categories'), topics = require('./../topics'), posts = require('./../posts'); module.exports = function(app, middleware, controllers) { - app.namespace('/debug', function() { - app.get('/uid/:uid', function (req, res) { - if (!req.params.uid) { - return res.redirect('/404'); - } + var router = express.Router(); - user.getUserData(req.params.uid, function (err, data) { - if (data) { - res.send(data); - } else { - res.json(404, { - error: "User doesn't exist!" - }); - } - }); - }); + router.get('/uid/:uid', function (req, res) { + if (!req.params.uid) { + return res.redirect('/404'); + } - app.get('/cid/:cid', function (req, res) { - categories.getCategoryData(req.params.cid, function (err, data) { - if (data) { - res.send(data); - } else { - res.send(404, "Category doesn't exist!"); - } - }); + user.getUserData(req.params.uid, function (err, data) { + if (data) { + res.send(data); + } else { + res.json(404, { + error: "User doesn't exist!" + }); + } }); + }); - app.get('/tid/:tid', function (req, res) { - topics.getTopicData(req.params.tid, function (err, data) { - if (data) { - res.send(data); - } else { - res.send(404, "Topic doesn't exist!"); - } - }); + router.get('/cid/:cid', function (req, res) { + categories.getCategoryData(req.params.cid, function (err, data) { + if (data) { + res.send(data); + } else { + res.send(404, "Category doesn't exist!"); + } }); + }); - app.get('/pid/:pid', function (req, res) { - posts.getPostData(req.params.pid, function (err, data) { - if (data) { - res.send(data); - } else { - res.send(404, "Post doesn't exist!"); - } - }); + router.get('/tid/:tid', function (req, res) { + topics.getTopicData(req.params.tid, function (err, data) { + if (data) { + res.send(data); + } else { + res.send(404, "Topic doesn't exist!"); + } }); + }); - app.get('/test', function(req, res) { - res.redirect('404'); + router.get('/pid/:pid', function (req, res) { + posts.getPostData(req.params.pid, function (err, data) { + if (data) { + res.send(data); + } else { + res.send(404, "Post doesn't exist!"); + } }); }); + + router.get('/test', function(req, res) { + res.redirect('404'); + }); + + return router; }; diff --git a/src/routes/index.js b/src/routes/index.js index 9166d340c1..9c94e74054 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -4,6 +4,7 @@ var nconf = require('nconf'), controllers = require('./../controllers'), meta = require('./../meta'), plugins = require('./../plugins'), + express = require('express'), metaRoutes = require('./meta'), apiRoutes = require('./api'), @@ -151,38 +152,89 @@ function groupRoutes(app, middleware, controllers) { module.exports = function(app, middleware) { - app.namespace(nconf.get('relative_path'), function() { - plugins.ready(function() { - app.all('/api/*', middleware.updateLastOnlineTime, middleware.prepareAPI); - app.all('/api/admin/*', middleware.admin.isAdmin, middleware.prepareAPI); - app.all('/admin/*', middleware.admin.isAdmin); - app.get('/admin', middleware.admin.isAdmin); - - plugins.fireHook('action:app.load', app, middleware, controllers); - - adminRoutes(app, middleware, controllers); - metaRoutes(app, middleware, controllers); - apiRoutes(app, middleware, controllers); - feedRoutes(app, middleware, controllers); - pluginRoutes(app, middleware, controllers); - authRoutes.createRoutes(app, middleware, controllers); - - /** - * Every view has an associated API route. - * - */ - mainRoutes(app, middleware, controllers); - staticRoutes(app, middleware, controllers); - topicRoutes(app, middleware, controllers); - tagRoutes(app, middleware, controllers); - categoryRoutes(app, middleware, controllers); - accountRoutes(app, middleware, controllers); - userRoutes(app, middleware, controllers); - groupRoutes(app, middleware, controllers); - }); - if (process.env.NODE_ENV === 'development') { - require('./debug')(app, middleware, controllers); - } + var router = express.Router(); + + plugins.ready(function() { + + app.all('/api/*', middleware.updateLastOnlineTime, middleware.prepareAPI); + app.all('/api/admin/*', middleware.admin.isAdmin, middleware.prepareAPI); + app.all('/admin/*', middleware.admin.isAdmin); + app.get('/admin', middleware.admin.isAdmin); + + plugins.fireHook('action:app.load', app, middleware, controllers); + + adminRoutes(app, middleware, controllers); + metaRoutes(app, middleware, controllers); + apiRoutes(app, middleware, controllers); + feedRoutes(app, middleware, controllers); + pluginRoutes(app, middleware, controllers); + authRoutes.createRoutes(app, middleware, controllers); + + /** + * Every view has an associated API route. + * + */ + mainRoutes(app, middleware, controllers); + staticRoutes(app, middleware, controllers); + topicRoutes(app, middleware, controllers); + tagRoutes(app, middleware, controllers); + categoryRoutes(app, middleware, controllers); + accountRoutes(app, middleware, controllers); + userRoutes(app, middleware, controllers); + groupRoutes(app, middleware, controllers); + + app.use(catch404); + app.use(handleErrors); + + app.use(nconf.get('relative_path'), router); }); + + if (process.env.NODE_ENV === 'development') { + app.use('/debug', require('./debug')(middleware, controllers)); + } + }; + +function handleErrors(err, req, res, next) { + // we may use properties of the error object + // here and next(err) appropriately, or if + // we possibly recovered from the error, simply next(). + console.error(err.stack); + + var status = err.status || 500; + res.status(status); + + req.flash('errorMessage', err.message); + + res.redirect('500'); +} + +function catch404(req, res, next) { + var isLanguage = new RegExp('^' + relativePath + '/language/[\\w]{2,}/.*.json'), + isClientScript = new RegExp('^' + relativePath + '\\/src\\/forum(\\/admin)?\\/.+\\.js'); + + res.status(404); + + if (isClientScript.test(req.url)) { + res.type('text/javascript').send(200, ''); + } else if (isLanguage.test(req.url)) { + res.json(200, {}); + } else if (req.accepts('html')) { + if (process.env.NODE_ENV === 'development') { + winston.warn('Route requested but not found: ' + req.url); + } + + res.redirect(relativePath + '/404'); + } else if (req.accepts('json')) { + if (process.env.NODE_ENV === 'development') { + winston.warn('Route requested but not found: ' + req.url); + } + + res.json({ + error: 'Not found' + }); + } else { + res.type('txt').send('Not found'); + } +} \ No newline at end of file diff --git a/src/socket.io/index.js b/src/socket.io/index.js index 3b872c2cac..750b8eeb11 100644 --- a/src/socket.io/index.js +++ b/src/socket.io/index.js @@ -7,8 +7,7 @@ var SocketIO = require('socket.io'), path = require('path'), fs = require('fs'), nconf = require('nconf'), - express = require('express'), - socketCookieParser = express.cookieParser(nconf.get('secret')), + socketCookieParser = require('cookie-parser')(nconf.get('secret')), winston = require('winston'), db = require('../database'), @@ -60,7 +59,7 @@ Sockets.init = function(server) { winston.error(err.message); } - sessionID = socket.handshake.signedCookies["express.sid"]; + sessionID = socket.handshake.signedCookies['express.sid']; db.sessionStore.get(sessionID, function(err, sessionData) { if (!err && sessionData && sessionData.passport && sessionData.passport.user) { uid = parseInt(sessionData.passport.user, 10); diff --git a/src/webserver.js b/src/webserver.js index e7c19359f0..9b50f0b553 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -2,7 +2,6 @@ var path = require('path'), fs = require('fs'), nconf = require('nconf'), express = require('express'), - express_namespace = require('express-namespace'), WebServer = express(), server, winston = require('winston'), From 9e8584eee7ce11ed25e0716e0ea705119e33194f Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 2 Jul 2014 14:59:48 -0400 Subject: [PATCH 03/10] uploads --- package.json | 3 +- src/controllers/accounts.js | 2 ++ src/middleware/index.js | 61 ++++++------------------------------- src/routes/admin.js | 2 +- src/routes/index.js | 6 ++-- 5 files changed, 18 insertions(+), 56 deletions(-) diff --git a/package.json b/package.json index c503019f29..e497692037 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "express-session": "^1.0.2", "csurf": "^1.1.0", "compression": "^1.0.1", + "connect-multiparty": "^1.0.1", "morgan": "^1.0.0", @@ -62,7 +63,7 @@ "validator": "~3.4.0", "winston": "~0.7.2", "xregexp": "~2.0.0", - "templates.js": "0.0.6" + "templates.js": "0.0.7" }, "devDependencies": { "mocha": "~1.13.0" diff --git a/src/controllers/accounts.js b/src/controllers/accounts.js index 312c6fc038..ca2c6286d4 100644 --- a/src/controllers/accounts.js +++ b/src/controllers/accounts.js @@ -373,6 +373,8 @@ accountsController.accountSettings = function(req, res, next) { }; accountsController.uploadPicture = function (req, res, next) { +console.log(req.body, req.files); + var uploadSize = parseInt(meta.config.maximumProfileImageSize, 10) || 256; if (req.files.userPhoto.size > uploadSize * 1024) { fs.unlink(req.files.userPhoto.path); diff --git a/src/middleware/index.js b/src/middleware/index.js index 5131d0e449..fb7bfc24fb 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -19,6 +19,7 @@ var utils = require('./../../public/src/utils'), cookieParser = require('cookie-parser'), compression = require('compression'), favicon = require('serve-favicon'), + multipart = require('connect-multiparty'), csrf = require('csurf'), session = require('express-session'), @@ -140,52 +141,6 @@ function compileTemplates(pluginTemplates) { }); } -function handleErrors(err, req, res, next) { - // we may use properties of the error object - // here and next(err) appropriately, or if - // we possibly recovered from the error, simply next(). - console.error(err.stack); - - var status = err.status || 500; - res.status(status); - - req.flash('errorMessage', err.message); - - res.redirect('500'); -} - -function catch404(req, res, next) { - var isLanguage = new RegExp('^' + relativePath + '/language/[\\w]{2,}/.*.json'), - isClientScript = new RegExp('^' + relativePath + '\\/src\\/forum(\\/admin)?\\/.+\\.js'); - - res.status(404); - - if (isClientScript.test(req.url)) { - res.type('text/javascript').send(200, ''); - } else if (isLanguage.test(req.url)) { - res.json(200, {}); - } else if (req.accepts('html')) { - if (process.env.NODE_ENV === 'development') { - winston.warn('Route requested but not found: ' + req.url); - } - - res.redirect(relativePath + '/404'); - } else if (req.accepts('json')) { - if (process.env.NODE_ENV === 'development') { - winston.warn('Route requested but not found: ' + req.url); - } - - res.json({ - error: 'Not found' - }); - } else { - res.type('txt').send('Not found'); - } -} - - - - module.exports = function(app, data) { middleware = require('./middleware')(app); @@ -198,6 +153,7 @@ module.exports = function(app, data) { app.engine('tpl', templates.__express); app.set('view engine', 'tpl'); app.set('views', viewsPath); + app.set('json spaces', process.env.NODE_ENV === 'development' ? 4 : 0); app.use(flash()); app.enable('view cache'); @@ -207,7 +163,8 @@ module.exports = function(app, data) { app.use(favicon(path.join(__dirname, '../../', 'public', meta.config['brand:favicon'] ? meta.config['brand:favicon'] : 'favicon.ico'))); app.use(relativePath + '/apple-touch-icon', middleware.routeTouchIcon); - app.use(bodyParser()); + app.use(bodyParser.urlencoded({extended: true})); + app.use(bodyParser.json()); app.use(cookieParser()); app.use(session({ @@ -216,13 +173,16 @@ module.exports = function(app, data) { key: 'express.sid', cookie: { maxAge: 1000 * 60 * 60 * 24 * parseInt(meta.configs.loginDays || 14, 10) - } + }, + resave: true, + saveUninitialized: true })); + app.use(multipart()); app.use(csrf()); app.use(function (req, res, next) { - res.locals.csrf_token = req.session._csrf; + res.locals.csrf_token = req.csrfToken(); res.setHeader('X-Powered-By', 'NodeBB'); res.setHeader('X-Frame-Options', 'SAMEORIGIN'); @@ -248,9 +208,6 @@ module.exports = function(app, data) { maxAge: app.enabled('cache') ? 5184000000 : 0 })); - //app.use(catch404); - //app.use(handleErrors); - return middleware; }; diff --git a/src/routes/admin.js b/src/routes/admin.js index 3928298ada..8b6b06468c 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -2,7 +2,7 @@ function mainRoutes(app, middleware, controllers) { - app.get('/admin/', middleware.admin.buildHeader, controllers.admin.home); + app.get('/admin', middleware.admin.buildHeader, controllers.admin.home); app.get('/admin/index', middleware.admin.buildHeader, controllers.admin.home); app.get('/api/admin/index', controllers.admin.home); diff --git a/src/routes/index.js b/src/routes/index.js index 9c94e74054..4ecaa0859e 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -1,6 +1,7 @@ "use strict"; var nconf = require('nconf'), + winston = require('winston'), controllers = require('./../controllers'), meta = require('./../meta'), plugins = require('./../plugins'), @@ -184,10 +185,10 @@ module.exports = function(app, middleware) { userRoutes(app, middleware, controllers); groupRoutes(app, middleware, controllers); + app.use(nconf.get('relative_path'), router); + app.use(catch404); app.use(handleErrors); - - app.use(nconf.get('relative_path'), router); }); if (process.env.NODE_ENV === 'development') { @@ -211,6 +212,7 @@ function handleErrors(err, req, res, next) { } function catch404(req, res, next) { + var relativePath = nconf.get('relative_path'); var isLanguage = new RegExp('^' + relativePath + '/language/[\\w]{2,}/.*.json'), isClientScript = new RegExp('^' + relativePath + '\\/src\\/forum(\\/admin)?\\/.+\\.js'); From 78c977e8f6f00c5497056663de23f3247bdd50ac Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 2 Jul 2014 15:09:59 -0400 Subject: [PATCH 04/10] removed trailing slash --- src/routes/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/index.js b/src/routes/index.js index 4ecaa0859e..06960b3ca9 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -76,8 +76,8 @@ function categoryRoutes(app, middleware, controllers) { app.get('/recent/:term?', middleware.buildHeader, controllers.categories.recent); app.get('/api/recent/:term?', controllers.categories.recent); - app.get('/unread/', middleware.buildHeader, middleware.authenticate, controllers.categories.unread); - app.get('/api/unread/', middleware.authenticate, controllers.categories.unread); + app.get('/unread', middleware.buildHeader, middleware.authenticate, controllers.categories.unread); + app.get('/api/unread', middleware.authenticate, controllers.categories.unread); app.get('/api/unread/total', middleware.authenticate, controllers.categories.unreadTotal); From 38494a2af07bfbd562ee62c7686760a9facef1fd Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 2 Jul 2014 15:15:06 -0400 Subject: [PATCH 05/10] pass in session directly --- src/database/redis.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/database/redis.js b/src/database/redis.js index 078f0a54d6..0becf2ba9e 100644 --- a/src/database/redis.js +++ b/src/database/redis.js @@ -40,7 +40,7 @@ module.init = function(callback) { try { redis = require('redis'); - connectRedis = require('connect-redis')({session: session}); + connectRedis = require('connect-redis')(session); reds = require('reds'); } catch (err) { winston.error('Unable to initialize Redis! Is Redis installed? Error :' + err.message); From ec1196d288fcc0469094c594ad7d87cd17cf90f8 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 2 Jul 2014 15:44:09 -0400 Subject: [PATCH 06/10] use router for relative path --- src/controllers/accounts.js | 2 -- src/routes/api.js | 2 +- src/routes/debug.js | 4 +--- src/routes/index.js | 43 +++++++++++++++++++------------------ 4 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/controllers/accounts.js b/src/controllers/accounts.js index ca2c6286d4..312c6fc038 100644 --- a/src/controllers/accounts.js +++ b/src/controllers/accounts.js @@ -373,8 +373,6 @@ accountsController.accountSettings = function(req, res, next) { }; accountsController.uploadPicture = function (req, res, next) { -console.log(req.body, req.files); - var uploadSize = parseInt(meta.config.maximumProfileImageSize, 10) || 256; if (req.files.userPhoto.size > uploadSize * 1024) { fs.unlink(req.files.userPhoto.path); diff --git a/src/routes/api.js b/src/routes/api.js index 47e7b5f045..9af798e95b 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -181,6 +181,7 @@ function getRecentPosts(req, res, next) { module.exports = function(app, middleware, controllers) { var router = express.Router(); + app.use('/api', router); router.get('/config', controllers.api.getConfig); @@ -193,5 +194,4 @@ module.exports = function(app, middleware, controllers) { router.post('/topic/thumb/upload', uploadThumb); router.post('/user/:userslug/uploadpicture', middleware.authenticate, middleware.checkGlobalPrivacySettings, middleware.checkAccountPermissions, controllers.accounts.uploadPicture); - app.use('/api', router); }; diff --git a/src/routes/debug.js b/src/routes/debug.js index d0e24c5494..a03c5b2649 100644 --- a/src/routes/debug.js +++ b/src/routes/debug.js @@ -8,7 +8,7 @@ var express = require('express'), module.exports = function(app, middleware, controllers) { var router = express.Router(); - + app.use('/debug', router); router.get('/uid/:uid', function (req, res) { if (!req.params.uid) { return res.redirect('/404'); @@ -58,6 +58,4 @@ module.exports = function(app, middleware, controllers) { router.get('/test', function(req, res) { res.redirect('404'); }); - - return router; }; diff --git a/src/routes/index.js b/src/routes/index.js index 06960b3ca9..cfba34a1f6 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -155,44 +155,45 @@ function groupRoutes(app, middleware, controllers) { module.exports = function(app, middleware) { var router = express.Router(); + app.use(nconf.get('relative_path'), router); plugins.ready(function() { - app.all('/api/*', middleware.updateLastOnlineTime, middleware.prepareAPI); - app.all('/api/admin/*', middleware.admin.isAdmin, middleware.prepareAPI); - app.all('/admin/*', middleware.admin.isAdmin); - app.get('/admin', middleware.admin.isAdmin); + router.all('/api/*', middleware.updateLastOnlineTime, middleware.prepareAPI); + router.all('/api/admin/*', middleware.admin.isAdmin, middleware.prepareAPI); + router.all('/admin/*', middleware.admin.isAdmin); + router.get('/admin', middleware.admin.isAdmin); - plugins.fireHook('action:app.load', app, middleware, controllers); + plugins.fireHook('action:app.load', router, middleware, controllers); - adminRoutes(app, middleware, controllers); - metaRoutes(app, middleware, controllers); - apiRoutes(app, middleware, controllers); - feedRoutes(app, middleware, controllers); - pluginRoutes(app, middleware, controllers); - authRoutes.createRoutes(app, middleware, controllers); + adminRoutes(router, middleware, controllers); + metaRoutes(router, middleware, controllers); + apiRoutes(router, middleware, controllers); + feedRoutes(router, middleware, controllers); + pluginRoutes(router, middleware, controllers); + authRoutes.createRoutes(router, middleware, controllers); /** * Every view has an associated API route. * */ - mainRoutes(app, middleware, controllers); - staticRoutes(app, middleware, controllers); - topicRoutes(app, middleware, controllers); - tagRoutes(app, middleware, controllers); - categoryRoutes(app, middleware, controllers); - accountRoutes(app, middleware, controllers); - userRoutes(app, middleware, controllers); - groupRoutes(app, middleware, controllers); + mainRoutes(router, middleware, controllers); + staticRoutes(router, middleware, controllers); + topicRoutes(router, middleware, controllers); + tagRoutes(router, middleware, controllers); + categoryRoutes(router, middleware, controllers); + accountRoutes(router, middleware, controllers); + userRoutes(router, middleware, controllers); + groupRoutes(router, middleware, controllers); + - app.use(nconf.get('relative_path'), router); app.use(catch404); app.use(handleErrors); }); if (process.env.NODE_ENV === 'development') { - app.use('/debug', require('./debug')(middleware, controllers)); + require('./debug')(app, middleware, controllers); } }; From 119d13053d511b7e98c659c08b4869dcd2f551f8 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 2 Jul 2014 16:08:21 -0400 Subject: [PATCH 07/10] move static to end --- src/middleware/index.js | 4 ---- src/routes/index.js | 5 ++++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/middleware/index.js b/src/middleware/index.js index fb7bfc24fb..6c59c1709a 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -204,10 +204,6 @@ module.exports = function(app, data) { compileTemplates(pluginTemplates); }); - app.use(relativePath, express.static(path.join(__dirname, '../../', 'public'), { - maxAge: app.enabled('cache') ? 5184000000 : 0 - })); - return middleware; }; diff --git a/src/routes/index.js b/src/routes/index.js index cfba34a1f6..bea9e769dd 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -1,6 +1,7 @@ "use strict"; var nconf = require('nconf'), + path = require('path'), winston = require('winston'), controllers = require('./../controllers'), meta = require('./../meta'), @@ -187,7 +188,9 @@ module.exports = function(app, middleware) { groupRoutes(router, middleware, controllers); - + app.use(nconf.get('relative_path'), express.static(path.join(__dirname, '../../', 'public'), { + maxAge: app.enabled('cache') ? 5184000000 : 0 + })); app.use(catch404); app.use(handleErrors); }); From 5d0755c4a8f8fbfe17b998339a61aa9e4d5698ee Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 2 Jul 2014 16:09:57 -0400 Subject: [PATCH 08/10] package.json --- package.json | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index e497692037..0065c662fa 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,14 @@ "cron": "~1.0.4", "daemon": "~1.1.0", "express": "4.4.5", + "cookie-parser": "^1.0.1", + "body-parser": "^1.0.1", + "serve-favicon": "^2.0.1", + "express-session": "^1.0.2", + "csurf": "^1.1.0", + "compression": "^1.0.1", + "connect-multiparty": "^1.0.1", + "morgan": "^1.0.0", "gm": "1.14.2", "gravatar": "1.0.6", "less": "~1.6.3", @@ -40,18 +48,6 @@ "prompt": "~0.2.11", "request": "~2.34.0", "rimraf": "~2.2.6", - - - "cookie-parser": "^1.0.1", - "body-parser": "^1.0.1", - "serve-favicon": "^2.0.1", - "express-session": "^1.0.2", - "csurf": "^1.1.0", - "compression": "^1.0.1", - "connect-multiparty": "^1.0.1", - - "morgan": "^1.0.0", - "rss": "~0.2.0", "semver": "~2.2.1", "sitemap": "~0.7.3", From 5ea74ae9e928104778fe037a1af90343adc2c0f3 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 2 Jul 2014 16:19:55 -0400 Subject: [PATCH 09/10] closes #1776 --- src/plugins.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins.js b/src/plugins.js index 689ea1e026..f35cc2e2a9 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -73,7 +73,7 @@ var fs = require('fs'), }, function(plugins, next) { if (!plugins || !Array.isArray(plugins)) { - next(); + return next(); } plugins.push(meta.config['theme:id']); From 586aeaf53f6c79238d4f59e426002c76523fef97 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 2 Jul 2014 21:55:05 -0400 Subject: [PATCH 10/10] added error checking to install.js for categories --- src/categories.js | 2 +- src/install.js | 35 +++++++++++++++++------------------ 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/categories.js b/src/categories.js index 58c790c1a4..80ed12e621 100644 --- a/src/categories.js +++ b/src/categories.js @@ -275,7 +275,7 @@ var db = require('./database'), return callback(err); } - if (!Array.isArray(categories)) { + if (!Array.isArray(categories) || !categories.length) { return callback(null, []); } diff --git a/src/install.js b/src/install.js index 15005e8999..2fe604029b 100644 --- a/src/install.js +++ b/src/install.js @@ -366,26 +366,25 @@ function createCategories(next) { var Categories = require('./categories'); Categories.getAllCategories(function (err, categoryData) { - if (categoryData.length === 0) { - winston.warn('No categories found, populating instance with default categories'); - - fs.readFile(path.join(__dirname, '../', 'install/data/categories.json'), function (err, default_categories) { - default_categories = JSON.parse(default_categories); - - async.eachSeries(default_categories, function (category, next) { - Categories.create(category, next); - }, function (err) { - if (!err) { - next(); - } else { - winston.error('Could not set up categories'); - } - }); - }); - } else { + if (err) { + return next(err); + } + + if (Array.isArray(categoryData) && categoryData.length) { winston.info('Categories OK. Found ' + categoryData.length + ' categories.'); - next(); + return next(); } + + winston.warn('No categories found, populating instance with default categories'); + + fs.readFile(path.join(__dirname, '../', 'install/data/categories.json'), function (err, default_categories) { + if (err) { + return next(err); + } + default_categories = JSON.parse(default_categories); + + async.eachSeries(default_categories, Categories.create, next); + }); }); }