From 875d09c29b825fe00ef13105cd8290f371404dc4 Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Thu, 4 Jun 2015 19:30:27 -0700 Subject: [PATCH 1/8] add hpp to address express vulnerability --- package.json | 1 + server/server.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/package.json b/package.json index e75a2f2a1d..0357e33ed0 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "gulp-minify-css": "~0.5.1", "helmet": "~0.9.0", "helmet-csp": "^0.2.3", + "hpp": "^0.2.0", "jade": "~1.8.0", "less": "~1.7.5", "less-middleware": "~2.0.1", diff --git a/server/server.js b/server/server.js index 4ed7607a0f..a1d0ce08d1 100755 --- a/server/server.js +++ b/server/server.js @@ -27,6 +27,7 @@ var R = require('ramda'), expressValidator = require('express-validator'), forceDomain = require('forcedomain'), lessMiddleware = require('less-middleware'), + hpp = require('hpp'), passportProviders = require('./passport-providers'), /** @@ -59,6 +60,7 @@ app.use(lessMiddleware(path.join(__dirname, '/public'))); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); +app.use(hpp()); app.use(expressValidator({ customValidators: { matchRegex: function (param, regex) { From 8b7bfb23abb52de6b18621dd44c8c375e26ae741 Mon Sep 17 00:00:00 2001 From: terakilobyte Date: Fri, 5 Jun 2015 09:07:46 -0400 Subject: [PATCH 2/8] Update story api to use stories instead of news --- public/js/main_0.0.2.js | 2 +- server/boot/story.js | 12 ++++++------ server/views/partials/navbar.jade | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/public/js/main_0.0.2.js b/public/js/main_0.0.2.js index 601baef073..209ccde97e 100644 --- a/public/js/main_0.0.2.js +++ b/public/js/main_0.0.2.js @@ -324,7 +324,7 @@ $(document).ready(function() { $('#story-submit').bind('click', storySubmitButtonHandler); }) .done(function (data, textStatus, xhr) { - window.location = '/news/' + JSON.parse(data).storyLink; + window.location = '/stories/' + JSON.parse(data).storyLink; }); }; diff --git a/server/boot/story.js b/server/boot/story.js index 3184a02141..3aac952cc6 100755 --- a/server/boot/story.js +++ b/server/boot/story.js @@ -22,9 +22,9 @@ module.exports = function(app) { router.get('/stories/submit/new-story', preSubmit); router.post('/stories/preliminary', newStory); router.post('/stories/', storySubmission); - router.get('/news/', hot); + router.get('/stories/', hot); router.post('/stories/search', getStories); - router.get('/news/:storyName', returnIndividualStory); + router.get('/stories/:storyName', returnIndividualStory); router.post('/stories/upvote/', upvote); app.use(router); @@ -152,7 +152,7 @@ module.exports = function(app) { 'Please double check the name.' }); - return res.redirect('/news/'); + return res.redirect('/stories/'); } story = story.pop(); @@ -160,7 +160,7 @@ module.exports = function(app) { .replace(/\s+/g, ' ') .replace(/\s/g, '-'); if (dashedNameFull !== dashedName) { - return res.redirect('../news/' + dashedNameFull); + return res.redirect('../stories/' + dashedNameFull); } var userVoted = false; @@ -324,7 +324,7 @@ module.exports = function(app) { }); return res.json({ alreadyPosted: true, - storyURL: '/news/' + story.pop().storyLink + storyURL: '/stories/' + story.pop().storyLink }); } utils.getURLTitle(url, processResponse); @@ -600,7 +600,7 @@ module.exports = function(app) { data.author.username + ' replied to you on Camper News.', 'You can keep this conversation going.', 'Just head back to the discussion here: ', - 'http://freecodecamp.com/news/' + data.originalStoryLink, + 'http://freecodecamp.com/stories/' + data.originalStoryLink, '- the Free Code Camp Volunteer Team' ].join('\n') }; diff --git a/server/views/partials/navbar.jade b/server/views/partials/navbar.jade index 8c6e2ff37d..cdbefeb583 100644 --- a/server/views/partials/navbar.jade +++ b/server/views/partials/navbar.jade @@ -25,7 +25,7 @@ nav.navbar.navbar-default.navbar-fixed-top.nav-height li a(href='/challenges/waypoint-join-our-chat-room') Chat li - a(href='/news') News + a(href='/stories') News li a(href='/field-guide') Guide li.hidden-xs.hidden-sm From a0b34c8e9052fe48ce5ebe42df4c20c3eb111235 Mon Sep 17 00:00:00 2001 From: terakilobyte Date: Fri, 5 Jun 2015 09:41:53 -0400 Subject: [PATCH 3/8] Redirect to home path on unsuccessful query rather than induce infinite redirect loop. --- server/boot/fieldGuide.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/server/boot/fieldGuide.js b/server/boot/fieldGuide.js index f30f7b73fc..59b9796b06 100644 --- a/server/boot/fieldGuide.js +++ b/server/boot/fieldGuide.js @@ -1,6 +1,6 @@ var R = require('ramda'), // Rx = require('rx'), - // debug = require('debug')('freecc:fieldguides'), + debug = require('debug')('freecc:fieldguides'), utils = require('../utils'); module.exports = function(app) { @@ -15,7 +15,7 @@ module.exports = function(app) { app.use(router); function returnIndividualFieldGuide(req, res, next) { - var dashedName = req.params.fieldGuideName; + var dashedNameFromQuery = req.params.fieldGuideName; if (req.user) { var completed = req.user.completedFieldGuides; @@ -33,8 +33,13 @@ module.exports = function(app) { } // NOTE(berks): loopback might have issue with regex here. - FieldGuide.find( - { dashedName: new RegExp(dashedName, 'i') }, + var pattern = new RegExp(dashedNameFromQuery, 'i'); + debug('looking for %s', pattern); + FieldGuide.find({ where: + { dashedName: + { like: pattern} + } + }, function(err, fieldGuideFromMongo) { if (err) { return next(err); @@ -46,13 +51,13 @@ module.exports = function(app) { 'Please double check the name.' }); - return res.redirect('/field-guide'); + return res.redirect('/'); } var fieldGuide = R.head(fieldGuideFromMongo); fieldGuide.name.toLowerCase().replace(/\s/g, '-').replace(/\?/g, ''); - if (fieldGuide.dashedName !== dashedName) { + if (fieldGuide.dashedName !== dashedNameFromQuery) { return res.redirect('../field-guide/' + fieldGuide.dashedName); } res.render('field-guide/show', { From d782ac9520df1c2600bef47f59660394ee36376b Mon Sep 17 00:00:00 2001 From: terakilobyte Date: Fri, 5 Jun 2015 13:25:28 -0400 Subject: [PATCH 4/8] Update find method in fieldGuide.js --- server/boot/fieldGuide.js | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/server/boot/fieldGuide.js b/server/boot/fieldGuide.js index 59b9796b06..eba6cb88a1 100644 --- a/server/boot/fieldGuide.js +++ b/server/boot/fieldGuide.js @@ -1,6 +1,6 @@ var R = require('ramda'), // Rx = require('rx'), - debug = require('debug')('freecc:fieldguides'), + // debug = require('debug')('freecc:fieldguides'), utils = require('../utils'); module.exports = function(app) { @@ -32,14 +32,7 @@ module.exports = function(app) { }); } - // NOTE(berks): loopback might have issue with regex here. - var pattern = new RegExp(dashedNameFromQuery, 'i'); - debug('looking for %s', pattern); - FieldGuide.find({ where: - { dashedName: - { like: pattern} - } - }, + FieldGuide.find({ where: {'dashedName': dashedNameFromQuery}}, function(err, fieldGuideFromMongo) { if (err) { return next(err); @@ -57,9 +50,9 @@ module.exports = function(app) { var fieldGuide = R.head(fieldGuideFromMongo); fieldGuide.name.toLowerCase().replace(/\s/g, '-').replace(/\?/g, ''); - if (fieldGuide.dashedName !== dashedNameFromQuery) { - return res.redirect('../field-guide/' + fieldGuide.dashedName); - } + //if (fieldGuide.dashedName !== dashedNameFromQuery) { + // return res.redirect('../field-guide/' + fieldGuide.dashedName); + //} res.render('field-guide/show', { title: fieldGuide.name, fieldGuideId: fieldGuide.id, From 4f9061bffb1db5c4df9a7008c13cc2aabb6a8ff8 Mon Sep 17 00:00:00 2001 From: terakilobyte Date: Fri, 5 Jun 2015 14:53:12 -0400 Subject: [PATCH 5/8] Sort out story model. --- common/models/story.json | 11 ++--------- server/boot/story.js | 23 +++++++++-------------- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/common/models/story.json b/common/models/story.json index 2ce2dc5ce4..b10b87ac31 100644 --- a/common/models/story.json +++ b/common/models/story.json @@ -14,7 +14,7 @@ }, "timePosted": { "type": "number", - "default": "0" + "default": 0 }, "link": { "type": "string", @@ -35,7 +35,7 @@ }, "rank": { "type": "number", - "default": "-Infinity" + "default": 0 }, "upVotes": { "type": "array", @@ -53,13 +53,6 @@ "storyLink": { "type": "string", "default": "" - }, - "difficulty": "string", - "description": "array", - "tests": "array", - "challengeSeed": "array", - "MDNlinks": { - "type": "array" } }, "validations": [], diff --git a/server/boot/story.js b/server/boot/story.js index 3aac952cc6..915463ffc8 100755 --- a/server/boot/story.js +++ b/server/boot/story.js @@ -13,7 +13,6 @@ module.exports = function(app) { var Story = app.models.Story; router.get('/stories/hotStories', hotJSON); - router.get('/stories/recentStories', recentJSON); router.get('/stories/comments/:id', comments); router.post('/stories/comment/', commentSubmit); router.post('/stories/comment/:id/comment', commentOnCommentSubmit); @@ -44,12 +43,18 @@ module.exports = function(app) { } function hotJSON(req, res, next) { - var story = Story.find({}).sort({'timePosted': -1}).limit(1000); - story.exec(function(err, stories) { + //var story = Story.find({}).sort({'timePosted': -1}).limit(1000); + //story.exec(function(err, stories) { + // if (err) { + // return next(err); + // } + //Story.find([{$match: {}}, + // {$sort: {'timePosted': -1}}, + // {$limit: 1000}], function(err, stories) { + Story.find({order: 'timePosted DESC', limit: 1000}, function(err, stories) { if (err) { return next(err); } - var foundationDate = 1413298800000; var sliceVal = stories.length >= 100 ? 100 : stories.length; @@ -63,16 +68,6 @@ module.exports = function(app) { }); } - function recentJSON(req, res, next) { - var story = Story.find({}).sort({'timePosted': -1}).limit(100); - story.exec(function(err, stories) { - if (err) { - return next(err); - } - return res.json(stories); - }); - } - function hot(req, res) { return res.render('stories/index', { title: 'Hot stories currently trending on Camper News', From 21b9405f0604813bc662b914cce9b52c1b1cc688 Mon Sep 17 00:00:00 2001 From: terakilobyte Date: Fri, 5 Jun 2015 14:58:42 -0400 Subject: [PATCH 6/8] Update links for new api model in views for stories. --- server/boot/story.js | 3 ++- server/views/stories/hot-stories.jade | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/server/boot/story.js b/server/boot/story.js index 915463ffc8..9f8a034724 100755 --- a/server/boot/story.js +++ b/server/boot/story.js @@ -2,7 +2,7 @@ var nodemailer = require('nodemailer'), sanitizeHtml = require('sanitize-html'), moment = require('moment'), mongodb = require('mongodb'), - // debug = require('debug')('freecc:cntr:story'), + debug = require('debug')('freecc:cntr:story'), utils = require('../utils'), MongoClient = mongodb.MongoClient, secrets = require('../../config/secrets'); @@ -55,6 +55,7 @@ module.exports = function(app) { if (err) { return next(err); } + debug(stories); var foundationDate = 1413298800000; var sliceVal = stories.length >= 100 ? 100 : stories.length; diff --git a/server/views/stories/hot-stories.jade b/server/views/stories/hot-stories.jade index 73ef1fde8e..425588dd05 100644 --- a/server/views/stories/hot-stories.jade +++ b/server/views/stories/hot-stories.jade @@ -38,7 +38,7 @@ " by @" + data[i].author.username + " " + "" + "
" + - "
discuss" + + "
discuss" + "
" + "" + "" + "