Skip to content

Commit

Permalink
Review like functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
CaptainFreak committed Jun 14, 2018
1 parent e69e157 commit fd451da
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 12 deletions.
2 changes: 2 additions & 0 deletions app/js/controllers/ProductDetailsController.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ angular.module('juiceShop').controller('ProductDetailsController', [
var review = { message: $scope.message, author: $scope.author }
$scope.productReviews.push(review)
productReviewService.create(id, review)
$scope.refreshReviews()
}

$scope.likeReview = function (review) {
productReviewService.like(review._id)
$scope.refreshReviews()
}

$scope.refreshReviews = function () {
Expand Down
6 changes: 3 additions & 3 deletions app/views/ProductDetail.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ <h3 class="modal-title"><span translate="LABEL_PRODUCT"></span> #{{product.id}}<
<div class="col-md-3">
<p>{{ review.message }}</p>
</div>
<footer class="capitalize">{{ review.author | emailName }}</footer>
<div class="col-md-3" style="display: flex;">
<button class="btn btn-default" style="border-radius: 50%;" ng-click="likeReview(review)">
<button class="btn btn-default" style="border-radius: 50%;" ng-click="likeReview(review)" ng-disabled="review.liked || !isLoggedIn()">
<i class="fas fa-heart" style="color:black;"></i>
</button>
<p style="margin-left: 5px; margin-right: 5px;">{{ review.likesCount }}</p>
<p style="margin-left: 5px; margin-right: 5px; padding-top: 6px;">{{ review.likesCount }}</p>
</div>
</div>
<footer class="capitalize">{{ review.author | emailName }}</footer>
</blockquote>
</div>
<div class="col-md-12">
Expand Down
4 changes: 3 additions & 1 deletion data/datacreator.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,9 @@ function createProducts () {
mongodb.reviews.insert({
message: text,
author: `${author}@${config.get('application.domain')}`,
product: id
product: id,
likesCount: 0,
likedBy: []
}).catch((err) => {
console.error(`Could not insert Product Review ${text}`)
console.error(err)
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@
"sqlite3": "~4.0.0",
"swagger-ui-express": "~3.0.7",
"z85": "~0.0",
"unzipper": "0.8.12"
"unzipper": "0.8.12",
"sleep": "*"
},
"devDependencies": {
"chai": "~4.1",
Expand Down
6 changes: 4 additions & 2 deletions routes/createProductReviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ const insecurity = require('../lib/insecurity')
module.exports = function productReviews () {
return (req, res, next) => {
const user = insecurity.authenticatedUsers.from(req)
if (user.data.email !== req.body.author && utils.notSolved(challenges.forgedReviewChallenge)) {
if (user && user.data.email !== req.body.author && utils.notSolved(challenges.forgedReviewChallenge)) {
utils.solve(challenges.forgedReviewChallenge)
}
db.reviews.insert({
product: req.params.id,
message: req.body.message,
author: req.body.author
author: req.body.author,
likesCount: 0,
likedBy: []
}).then(result => {
res.status(201).json({ staus: 'success' })
}, err => {
Expand Down
42 changes: 42 additions & 0 deletions routes/likeProductReviews.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const utils = require('../lib/utils')
const challenges = require('../data/datacache').challenges
const db = require('../data/mongodb')
const insecurity = require('../lib/insecurity')
const sleep = require('sleep')

module.exports = function productReviews () {
return (req, res, next) => {
const id = req.body.id
const user = insecurity.authenticatedUsers.from(req)

db.reviews.findOne({ _id: id }).then(review => {
var likedBy = review.likedBy
if(!likedBy.includes(user.data.email)){
db.reviews.update(
{ _id: id },
{ '$inc': { likesCount: 1 } }
).then(
result => {
// Artificial wait for timing attack challenge
sleep.msleep(800)
likedBy.push(user.data.email)
db.reviews.update(
{ _id: id },
{ '$set': { likedBy: likedBy } }
).then(
result => {
res.json(result)
}, err => {
res.status(500).json(err)
})
}, err => {
res.status(500).json(err)
})
}else{
res.status(403).json({ error: 'Not allowed' })
}
}, () => {
res.status(400).json({ error: 'Wrong Params' })
})
}
}
14 changes: 10 additions & 4 deletions routes/showProductReviews.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const utils = require('../lib/utils')
const challenges = require('../data/datacache').challenges

const insecurity = require('../lib/insecurity')
const db = require('../data/mongodb')

// Blocking sleep function as in native MongoDB
Expand All @@ -16,10 +16,10 @@ global.sleep = time => {
}

module.exports = function productReviews () {
return ({params}, res, next) => {
const id = params.id
return (req, res, next) => {
const id = req.params.id

// Messure how long the query takes to find out if an there was a nosql dos attack
// Measure how long the query takes to find out if an there was a nosql dos attack
const t0 = new Date().getTime()
db.reviews.find({ '$where': 'this.product == ' + id }).then(reviews => {
const t1 = new Date().getTime()
Expand All @@ -28,6 +28,12 @@ module.exports = function productReviews () {
utils.solve(challenges.noSqlCommandChallenge)
}
}
const user = insecurity.authenticatedUsers.from(req)
for (var i =0 ; i<reviews.length; i++){
if(user === undefined || reviews[i].likedBy.includes(user.data.email)){
reviews[i].liked = true
}
}
res.json(utils.queryResultToJson(reviews))
}, () => {
res.status(400).json({ error: 'Wrong Params' })
Expand Down
2 changes: 1 addition & 1 deletion routes/updateProductReviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module.exports = function productReviews () {
).then(
result => {
if (result.modified > 1 && utils.notSolved(challenges.noSqlReviewsChallenge)) {
// More then one Review was modified => challange solved
// More than one Review was modified => challange solved
utils.solve(challenges.noSqlReviewsChallenge)
}
if (result.original[0].author !== user.data.email && utils.notSolved(challenges.forgedReviewChallenge && result.modified === 1)) {
Expand Down
2 changes: 2 additions & 0 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const b2bOrder = require('./routes/b2bOrder')
const showProductReviews = require('./routes/showProductReviews')
const createProductReviews = require('./routes/createProductReviews')
const updateProductReviews = require('./routes/updateProductReviews')
const likeProductReviews = require('./routes/likeProductReviews')
const utils = require('./lib/utils')
const insecurity = require('./lib/insecurity')
const models = require('./models')
Expand Down Expand Up @@ -230,6 +231,7 @@ app.get('/rest/country-mapping', countryMapping())
app.get('/rest/product/:id/reviews', showProductReviews())
app.put('/rest/product/:id/reviews', createProductReviews())
app.patch('/rest/product/reviews', insecurity.isAuthorized(), updateProductReviews())
app.post('/rest/product/reviews', insecurity.isAuthorized(), likeProductReviews())

/* B2B Order API */
app.post('/b2b/v2/orders', b2bOrder())
Expand Down

0 comments on commit fd451da

Please sign in to comment.