From c711b41fa0400961115ce80637211866e1f575f9 Mon Sep 17 00:00:00 2001 From: MrRenter Date: Fri, 17 Apr 2015 22:33:07 -0400 Subject: [PATCH 1/8] Added code to display edit button next to discuss button when viewing a story. Button will vanish if comment was posted > 10 minutes --- views/stories/comments.jade | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/views/stories/comments.jade b/views/stories/comments.jade index f21f43ac3a..ae2b051d06 100644 --- a/views/stories/comments.jade +++ b/views/stories/comments.jade @@ -21,7 +21,10 @@ success: function (data, textStatus, xhr) { commentDetails = data; var div = document.createElement('div'); - + var editButton = ""; + if ((Date.now() - commentDetails.commentOn) < 600000){ + editButton = "Edit · "; + } $(div) .html( '
' + @@ -36,6 +39,7 @@ '
' + '
' + "Reply · " + + editButton + "commented " + moment(commentDetails.commentOn).fromNow() + " by " + "@" + commentDetails.author.username + "" + '
' + From 47bb301a9112c305f102caf39c888075e97d2247 Mon Sep 17 00:00:00 2001 From: MrRenter Date: Fri, 17 Apr 2015 22:36:09 -0400 Subject: [PATCH 2/8] Made it so edit will only be displayed for the user. Since its on client side (following practices used) a final check should be used when actually saving edit to db --- views/stories/comments.jade | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/views/stories/comments.jade b/views/stories/comments.jade index ae2b051d06..a47a969c95 100644 --- a/views/stories/comments.jade +++ b/views/stories/comments.jade @@ -22,8 +22,10 @@ commentDetails = data; var div = document.createElement('div'); var editButton = ""; - if ((Date.now() - commentDetails.commentOn) < 600000){ - editButton = "Edit · "; + if (commentDetails.author.username === user.profile.username){ + if ((Date.now() - commentDetails.commentOn) < 600000){ + editButton = "Edit · "; + } } $(div) .html( From 349dbbc2af22bfc1304154b6b3b7159461baa3e2 Mon Sep 17 00:00:00 2001 From: MrRenter Date: Sat, 18 Apr 2015 02:40:48 -0400 Subject: [PATCH 3/8] Added functuality to the edit button. Added router to /commets/:id/edit as well as commentEdit method in story js. --- app.js | 5 +++++ controllers/story.js | 35 ++++++++++++++++++++++++++++++++ views/stories/comments.jade | 40 +++++++++++++++++++++++++++++++++---- 3 files changed, 76 insertions(+), 4 deletions(-) mode change 100644 => 100755 app.js mode change 100644 => 100755 controllers/story.js mode change 100644 => 100755 views/stories/comments.jade diff --git a/app.js b/app.js old mode 100644 new mode 100755 index f03046711b..eadf61888e --- a/app.js +++ b/app.js @@ -470,6 +470,11 @@ app.post( storyController.commentOnCommentSubmit ); +app.post( + '/stories/comment/:id/edit', + storyController.commentEdit +); + app.get( '/stories/submit', storyController.submitNew diff --git a/controllers/story.js b/controllers/story.js old mode 100644 new mode 100755 index 34b8693890..4ab8351393 --- a/controllers/story.js +++ b/controllers/story.js @@ -423,6 +423,41 @@ exports.commentOnCommentSubmit = function(req, res, next) { commentSave(comment, Comment, res, next); }; +exports.commentEdit = function(req, res, next){ + if (req.user._id.toString() !== req.body.data.author.userId.toString()) { + return next(new Error('Not authorized')); + } + + var data = req.params.id; + var sanitizedBody = sanitizeHtml(req.body.data.body,{ + allowedTags: [], + allowedAttributes: [] + }).replace(/"/g, '"'); + if (req.body.data.body !== sanitizedBody) { + req.flash('errors', { + msg: 'HTML is not allowed' + }); + return res.send(true); + } + + Comment.find({'_id': data}, function(err, cmt) { + if (err) { + return next(err); + } + cmt = cmt.pop(); + cmt.body = sanitizedBody; + cmt.commentOn = Date.now(); + cmt.save(function (err) { + if (err) { + return next(err); + } + res.send(true); + }); + //commentSave(comment, Comment, res, next); + }); + +}; + function commentSave(comment, Context, res, next) { comment.save(function(err, data) { if (err) { diff --git a/views/stories/comments.jade b/views/stories/comments.jade old mode 100644 new mode 100755 index a47a969c95..43d1701288 --- a/views/stories/comments.jade +++ b/views/stories/comments.jade @@ -24,7 +24,7 @@ var editButton = ""; if (commentDetails.author.username === user.profile.username){ if ((Date.now() - commentDetails.commentOn) < 600000){ - editButton = "Edit · "; + editButton = "Edit · "; } } $(div) @@ -61,7 +61,12 @@ complete: function () { sentinel--; if (!sentinel) { - $('.comment-a-comment').on('click', 'a', function () { + $('.comment-a-comment').on('click', 'a', function() { + alert($(this).hasClass("edit-btn")); + var editOrComment = 'comment'; + if ($(this).hasClass("edit-btn")){ + editOrComment = 'edit'; + } if (typeof user == "undefined" || !user) { window.location.href = '/signin'; return; @@ -77,7 +82,7 @@ "
" + "" + "" + - "" + + "" + "" + "
" + "
" + @@ -122,9 +127,36 @@ }); }; + var submitCommentForEditToCommentHandler = function submitCommentForEditToCommentHandler() { + $('#submit-comment-to-edit').unbind('click'); + console.log('in comments.jade', originalStoryAuthorEmail); + $.post('/stories/comment/' + commentId + '/edit', + { + data: { + associatedPost: commentId, + originalStoryLink: originalStoryLink, + originalStoryAuthorEmail: originalStoryAuthorEmail, + body: $('#comment-to-comment-textinput').val(), + author: { + picture: user.profile.picture, + userId: user._id, + username: user.profile.username, + email: user.email + } + } + }) + .fail(function (xhr, textStatus, errorThrown) { + $('#submit-comment-to-edit').bind('click', submitCommentForEditToCommentHandler); + }) + .done(function (data, textStatus, xhr) { + window.location.reload(); + }); + }; + + $('#submit-comment-to-edit').on('click', submitCommentForEditToCommentHandler) $('#submit-comment-to-comment').on('click', submitCommentToCommentHandler); - });// + }); } } }) From 790a4f941d3239c47f1282c540125c40536bf8e9 Mon Sep 17 00:00:00 2001 From: MrRenter Date: Sat, 18 Apr 2015 02:46:16 -0400 Subject: [PATCH 4/8] Removed alert and added server side check for 10minutes --- controllers/story.js | 21 +++++++++++++-------- views/stories/comments.jade | 1 - 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/controllers/story.js b/controllers/story.js index 4ab8351393..24b11ddba9 100755 --- a/controllers/story.js +++ b/controllers/story.js @@ -445,15 +445,20 @@ exports.commentEdit = function(req, res, next){ return next(err); } cmt = cmt.pop(); - cmt.body = sanitizedBody; - cmt.commentOn = Date.now(); - cmt.save(function (err) { - if (err) { - return next(err); - } - res.send(true); + var rightNow = Date.now(); + if ((rightNow - cmt.commentOn) < 600000){ + cmt.body = sanitizedBody; + cmt.commentOn = Date.now(); + cmt.save(function (err) { + if (err) { + return next(err); + } + res.send(true); + }); + } + req.flash('errors', { + msg: 'Comment is too old to edit' }); - //commentSave(comment, Comment, res, next); }); }; diff --git a/views/stories/comments.jade b/views/stories/comments.jade index 43d1701288..15d0b2deaf 100755 --- a/views/stories/comments.jade +++ b/views/stories/comments.jade @@ -62,7 +62,6 @@ sentinel--; if (!sentinel) { $('.comment-a-comment').on('click', 'a', function() { - alert($(this).hasClass("edit-btn")); var editOrComment = 'comment'; if ($(this).hasClass("edit-btn")){ editOrComment = 'edit'; From b2f18a790af5cd63c52aaa3e767c700866ee085b Mon Sep 17 00:00:00 2001 From: MrRenter Date: Sat, 18 Apr 2015 11:53:46 -0400 Subject: [PATCH 5/8] Changed from post to put for since updating not creatings --- app.js | 2 +- controllers/story.js | 8 +++++--- views/stories/comments.jade | 20 +++++++++++--------- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/app.js b/app.js index eadf61888e..a40b25f074 100755 --- a/app.js +++ b/app.js @@ -470,7 +470,7 @@ app.post( storyController.commentOnCommentSubmit ); -app.post( +app.put( '/stories/comment/:id/edit', storyController.commentEdit ); diff --git a/controllers/story.js b/controllers/story.js index 24b11ddba9..8b12c12ca9 100755 --- a/controllers/story.js +++ b/controllers/story.js @@ -424,16 +424,18 @@ exports.commentOnCommentSubmit = function(req, res, next) { }; exports.commentEdit = function(req, res, next){ - if (req.user._id.toString() !== req.body.data.author.userId.toString()) { + //console.log(JSON.stringify(req)); + console.log(JSON.stringify(req.body)); + if (req.user._id.toString() !== req.body.author.userId.toString()) { return next(new Error('Not authorized')); } var data = req.params.id; - var sanitizedBody = sanitizeHtml(req.body.data.body,{ + var sanitizedBody = sanitizeHtml(req.body.body,{ allowedTags: [], allowedAttributes: [] }).replace(/"/g, '"'); - if (req.body.data.body !== sanitizedBody) { + if (req.body.body !== sanitizedBody) { req.flash('errors', { msg: 'HTML is not allowed' }); diff --git a/views/stories/comments.jade b/views/stories/comments.jade index 15d0b2deaf..34f25b7b8b 100755 --- a/views/stories/comments.jade +++ b/views/stories/comments.jade @@ -129,8 +129,10 @@ var submitCommentForEditToCommentHandler = function submitCommentForEditToCommentHandler() { $('#submit-comment-to-edit').unbind('click'); console.log('in comments.jade', originalStoryAuthorEmail); - $.post('/stories/comment/' + commentId + '/edit', - { + + $.ajax({ + type: "PUT", + url: '/stories/comment/' + commentId + '/edit', data: { associatedPost: commentId, originalStoryLink: originalStoryLink, @@ -142,15 +144,15 @@ username: user.profile.username, email: user.email } + }, + dataType: "json", + success: function (msg) { + window.location.reload(); + }, + error: function (err){ + $('#submit-comment-to-edit').bind('click', submitCommentForEditToCommentHandler); } - }) - .fail(function (xhr, textStatus, errorThrown) { - $('#submit-comment-to-edit').bind('click', submitCommentForEditToCommentHandler); - }) - .done(function (data, textStatus, xhr) { - window.location.reload(); }); - }; $('#submit-comment-to-edit').on('click', submitCommentForEditToCommentHandler) From 083cd7d710fed92d3ac90982946a9bcace522c65 Mon Sep 17 00:00:00 2001 From: terakilobyte Date: Sun, 19 Apr 2015 21:07:38 -0400 Subject: [PATCH 6/8] Fix json for get 'started with ziplines' ziplines --- seed_data/coursewares.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seed_data/coursewares.json b/seed_data/coursewares.json index 08285288f8..36edc5fc11 100644 --- a/seed_data/coursewares.json +++ b/seed_data/coursewares.json @@ -654,7 +654,7 @@ "Click your user image in the top right corner, then click the \"New pen\" button that drops down.", "Drag the windows around and press the buttons in the lower-right hand corner to change the orientation to suit your preference.", "Click the gear next to CSS. Then in the \"External CSS File or Another Pen\" text field, type \"bootstrap\" and scroll down until you see the latest version of Bootstrap. Click it.", - "Verify that bootstrap is active by adding the following code to your HTML:

Hello CodePen!

. The text's color should be Bootstrap blue.", + "Verify that bootstrap is active by adding the following code to your HTML: <h1 class='text-primary'>Hello CodePen!</h1>. The text's color should be Bootstrap blue.", "Click the gear next the JavaScript. Click the \"Latest version of...\" select box and choose jQuery.", "Now add the following code to your JavaScript: $(document).ready(function() { $('.text-primary').text('Hi CodePen!') });. Click the \"Save\" button at the top. Your \"Hello CodePen!\" should change to \"Hi CodePen!\". This means that jQuery is working.", "Now you're ready for your first Zipline. Click the \"I've completed this challenge\" button and include a link to your CodePen. If you pair programmed, you should also include the Free Code Camp username of your pair." From 7cbd8e1c04f6ee44d24244ab4046b5e96dbc1eda Mon Sep 17 00:00:00 2001 From: terakilobyte Date: Mon, 20 Apr 2015 00:28:55 -0400 Subject: [PATCH 7/8] merge pr for unique story slugs --- controllers/bonfire.js | 4 +- controllers/story.js | 350 +++++++++++++++++++++------------------- seed_data/bonfires.json | 3 +- 3 files changed, 185 insertions(+), 172 deletions(-) diff --git a/controllers/bonfire.js b/controllers/bonfire.js index ee8b26a5ce..dbe60a0da0 100644 --- a/controllers/bonfire.js +++ b/controllers/bonfire.js @@ -109,8 +109,8 @@ exports.returnIndividualBonfire = function(req, res, next) { dashedName: dashedName, name: bonfire.name, difficulty: Math.floor(+bonfire.difficulty), - brief: bonfire.description[0], - details: bonfire.description.slice(1), + brief: bonfire.description.shift(), + details: bonfire.description, tests: bonfire.tests, challengeSeed: bonfire.challengeSeed, points: req.user ? req.user.points : undefined, diff --git a/controllers/story.js b/controllers/story.js index 94d99444f8..9047279e3f 100755 --- a/controllers/story.js +++ b/controllers/story.js @@ -57,7 +57,7 @@ exports.recentJSON = function(req, res, next) { }; exports.hot = function(req, res) { - return res.render('stories/index', { + return res.render('stories/index', { title: 'Hot stories currently trending on Camper News', page: 'hot' }); @@ -120,7 +120,7 @@ exports.returnIndividualStory = function(req, res, next) { var storyName = dashedName.replace(/\-/g, ' '); - Story.find({'storyLink': new RegExp(storyName, 'i')}, function(err, story) { + Story.find({'storyLink': storyName}, function(err, story) { if (err) { return next(err); } @@ -328,186 +328,198 @@ exports.storySubmission = function(req, res, next) { if (link.search(/^https?:\/\//g) === -1) { link = 'http://' + link; } - var story = new Story({ - headline: sanitizeHtml(data.headline, { - allowedTags: [], - allowedAttributes: [] - }).replace(/"/g, '"'), - timePosted: Date.now(), - link: link, - description: sanitizeHtml(data.description, { - allowedTags: [], - allowedAttributes: [] - }).replace(/"/g, '"'), - rank: 1, - upVotes: [({ - upVotedBy: req.user._id, - upVotedByUsername: req.user.profile.username - })], - author: { - picture: req.user.profile.picture, - userId: req.user._id, - username: req.user.profile.username, - email: req.user.email - }, - comments: [], - image: data.image, - storyLink: storyLink, - metaDescription: data.storyMetaDescription, - originalStoryAuthorEmail: req.user.email - }); - - story.save(function(err) { - if (err) { - return res.status(500); - } - res.send(JSON.stringify({ - storyLink: story.storyLink.replace(/\s/g, '-').toLowerCase() - })); - }); -}; - -exports.commentSubmit = function(req, res, next) { - var data = req.body.data; - if (!req.user) { - return next(new Error('Not authorized')); - } - var sanitizedBody = sanitizeHtml(data.body, - { - allowedTags: [], - allowedAttributes: [] - }).replace(/"/g, '"'); - if (data.body !== sanitizedBody) { - req.flash('errors', { - msg: 'HTML is not allowed' - }); - return res.send(true); - } - var comment = new Comment({ - associatedPost: data.associatedPost, - originalStoryLink: data.originalStoryLink, - originalStoryAuthorEmail: req.user.email, - body: sanitizedBody, - rank: 0, - upvotes: 0, - author: { - picture: req.user.profile.picture, - userId: req.user._id, - username: req.user.profile.username, - email: req.user.email - }, - comments: [], - topLevel: true, - commentOn: Date.now() - }); - - commentSave(comment, Story, res, next); -}; - -exports.commentOnCommentSubmit = function(req, res, next) { - var data = req.body.data; - if (!req.user) { - return next(new Error('Not authorized')); - } - - var sanitizedBody = sanitizeHtml(data.body, - { - allowedTags: [], - allowedAttributes: [] - }).replace(/"/g, '"'); - if (data.body !== sanitizedBody) { - req.flash('errors', { - msg: 'HTML is not allowed' - }); - return res.send(true); - } - var comment = new Comment({ - associatedPost: data.associatedPost, - body: sanitizedBody, - rank: 0, - upvotes: 0, - originalStoryLink: data.originalStoryLink, - originalStoryAuthorEmail: data.originalStoryAuthorEmail, - author: { - picture: req.user.profile.picture, - userId: req.user._id, - username: req.user.profile.username, - email: req.user.email - }, - comments: [], - topLevel: false, - commentOn: Date.now() - }); - commentSave(comment, Comment, res, next); -}; - -exports.commentEdit = function(req, res, next) { - - Comment.find({'_id': req.params.id}, function(err, cmt) { + Story.count({'storyLink': new RegExp('^' + storyLink + '(?: [0-9]+)?$', 'i')}, function (err, storyCount) { if (err) { - return next(err); + return res.status(500); } - cmt = cmt.pop(); - if (!req.user && cmt.author.userId !== req.user._id) { + // if duplicate storyLink add unique number + storyLink = (storyCount == 0) ? storyLink : storyLink + ' ' + storyCount; + + var link = data.link; + if (link.search(/^https?:\/\//g) === -1) { + link = 'http://' + link; + } + var story = new Story({ + headline: sanitizeHtml(data.headline, { + allowedTags: [], + allowedAttributes: [] + }).replace(/"/g, '"'), + timePosted: Date.now(), + link: link, + description: sanitizeHtml(data.description, { + allowedTags: [], + allowedAttributes: [] + }).replace(/"/g, '"'), + rank: 1, + upVotes: [({ + upVotedBy: req.user._id, + upVotedByUsername: req.user.profile.username + })], + author: { + picture: req.user.profile.picture, + userId: req.user._id, + username: req.user.profile.username, + email: req.user.email + }, + comments: [], + image: data.image, + storyLink: storyLink, + metaDescription: data.storyMetaDescription, + originalStoryAuthorEmail: req.user.email + }); + story.save(function (err) { + if (err) { + return res.status(500); + } + res.send(JSON.stringify({ + storyLink: story.storyLink.replace(/\s/g, '-').toLowerCase() + })); + }); + }); +}; + + exports.commentSubmit = function(req, res, next) { + var data = req.body.data; + if (!req.user) { return next(new Error('Not authorized')); } - - - var sanitizedBody = sanitizeHtml(req.body.body, { - allowedTags: [], - allowedAttributes: [] - }).replace(/"/g, '"'); - if (req.body.body !== sanitizedBody) { + var sanitizedBody = sanitizeHtml(data.body, + { + allowedTags: [], + allowedAttributes: [] + }).replace(/"/g, '"'); + if (data.body !== sanitizedBody) { req.flash('errors', { msg: 'HTML is not allowed' }); return res.send(true); } - - cmt.body = sanitizedBody; - cmt.commentOn = Date.now(); - cmt.save(function (err) { - if (err) { - return next(err); - } - res.send(true); + var comment = new Comment({ + associatedPost: data.associatedPost, + originalStoryLink: data.originalStoryLink, + originalStoryAuthorEmail: req.user.email, + body: sanitizedBody, + rank: 0, + upvotes: 0, + author: { + picture: req.user.profile.picture, + userId: req.user._id, + username: req.user.profile.username, + email: req.user.email + }, + comments: [], + topLevel: true, + commentOn: Date.now() }); - }); + commentSave(comment, Story, res, next); + }; -}; - -function commentSave(comment, Context, res, next) { - comment.save(function(err, data) { - if (err) { - return next(err); + exports.commentOnCommentSubmit = function(req, res, next) { + var data = req.body.data; + if (!req.user) { + return next(new Error('Not authorized')); } - try { - Context.find({'_id': comment.associatedPost}, function (err, associatedStory) { + + var sanitizedBody = sanitizeHtml(data.body, + { + allowedTags: [], + allowedAttributes: [] + }).replace(/"/g, '"'); + if (data.body !== sanitizedBody) { + req.flash('errors', { + msg: 'HTML is not allowed' + }); + return res.send(true); + } + var comment = new Comment({ + associatedPost: data.associatedPost, + body: sanitizedBody, + rank: 0, + upvotes: 0, + originalStoryLink: data.originalStoryLink, + originalStoryAuthorEmail: data.originalStoryAuthorEmail, + author: { + picture: req.user.profile.picture, + userId: req.user._id, + username: req.user.profile.username, + email: req.user.email + }, + comments: [], + topLevel: false, + commentOn: Date.now() + }); + commentSave(comment, Comment, res, next); + }; + + exports.commentEdit = function(req, res, next) { + + Comment.find({'_id': req.params.id}, function(err, cmt) { + if (err) { + return next(err); + } + cmt = cmt.pop(); + + if (!req.user && cmt.author.userId !== req.user._id) { + return next(new Error('Not authorized')); + } + + + var sanitizedBody = sanitizeHtml(req.body.body, { + allowedTags: [], + allowedAttributes: [] + }).replace(/"/g, '"'); + if (req.body.body !== sanitizedBody) { + req.flash('errors', { + msg: 'HTML is not allowed' + }); + return res.send(true); + } + + cmt.body = sanitizedBody; + cmt.commentOn = Date.now(); + cmt.save(function (err) { if (err) { return next(err); } - associatedStory = associatedStory.pop(); - if (associatedStory) { - associatedStory.comments.push(data._id); - associatedStory.save(function (err) { - if (err) { - return next(err); - } - res.send(true); - }); - } - User.findOne({'profile.username': associatedStory.author.username}, function(err, recipient) { + res.send(true); + }); + + }); + + }; + + function commentSave(comment, Context, res, next) { + comment.save(function(err, data) { + if (err) { + return next(err); + } + try { + Context.find({'_id': comment.associatedPost}, function (err, associatedStory) { if (err) { return next(err); } - var recipients = ''; - if (data.originalStoryAuthorEmail && (data.originalStoryAuthorEmail !== recipient.email)) { - recipients = data.originalStoryAuthorEmail + ',' + recipient.email; - } else { - recipients = recipient.email; - } + associatedStory = associatedStory.pop(); + if (associatedStory) { + associatedStory.comments.push(data._id); + associatedStory.save(function (err) { + if (err) { + return next(err); + } + res.send(true); + }); + } + User.findOne({'profile.username': associatedStory.author.username}, function(err, recipient) { + if (err) { + return next(err); + } + var recipients = ''; + if (data.originalStoryAuthorEmail && (data.originalStoryAuthorEmail !== recipient.email)) { + recipients = data.originalStoryAuthorEmail + ',' + recipient.email; + } else { + recipients = recipient.email; + } var transporter = nodemailer.createTransport({ service: 'Mandrill', auth: { @@ -531,11 +543,11 @@ function commentSave(comment, Context, res, next) { return err; } }); + }); }); - }); - } catch (e) { - // delete comment - return next(err); - } - }); -} + } catch (e) { + // delete comment + return next(err); + } + }); + } diff --git a/seed_data/bonfires.json b/seed_data/bonfires.json index 0f7373798a..31df4b8c1d 100644 --- a/seed_data/bonfires.json +++ b/seed_data/bonfires.json @@ -728,8 +728,9 @@ "Create a function that takes two or more arrays and returns an array of the symmetric difference of the provided arrays.", "The mathematical term symmetric difference refers to the elements in two sets that are in either the first or second set, but not in both." ], - "challengeSeed": "function sym(args) {\n return arr;\r\n}\n\nsym([1, 2, 3], [5, 2, 1, 4]);", + "challengeSeed": "function sym(args) {\n return arguments;\r\n}\n\nsym([1, 2, 3], [5, 2, 1, 4]);", "tests": [ + "expect(sym([1, 2, 3], [5, 2, 1, 4])).to.eqls([3, 5, 4])", "assert.deepEqual(sym([1, 2, 5], [2, 3, 5], [3, 4, 5]), [1, 4, 5], 'should return the symmetric difference of the given arrays');", "assert.deepEqual(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]), [1, 4, 5], 'should return an array of unique values');", "assert.deepEqual(sym([1, 1]), [1], 'should return an array of unique values');" From e3822edd9391bd0ad921520cfb8c3027ba2bca52 Mon Sep 17 00:00:00 2001 From: Nathan Date: Mon, 20 Apr 2015 02:20:14 -0400 Subject: [PATCH 8/8] Update README.md --- README.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/README.md b/README.md index 68b31e96fb..d621fd4b5e 100644 --- a/README.md +++ b/README.md @@ -149,17 +149,6 @@ List of Packages | supertest | HTTP assertion library. | | multiline | Multi-line strings for the generator. | - -Changelog ---------- - -### 0.1.0 (December 24, 2014) -- Improved how unique emails and usernames are handled (with Express-validator) -- Added a tweet button to challenge completion model -- Refactored all views to get rid of any hard-coded challenge information (to make for a better forking experience) -- Installed Helmet to maximize security of application -- Added .env and removed all trace of API keys from git history - License -------