forked from kaverti/website
155 lines
4.2 KiB
JavaScript
155 lines
4.2 KiB
JavaScript
let express = require('express')
|
|
let router = express.Router()
|
|
const auth = require('../lib/auth')
|
|
|
|
let { PollAnswer, PollQuestion, PollVote, User, Sequelize, Thread } = require('../models')
|
|
const Errors = require('../lib/errors')
|
|
|
|
router.get('/:id', auth, async(req, res, next) => {
|
|
try {
|
|
let id = req.params.id
|
|
let pollQuestion = await PollQuestion.findByPk(id, {
|
|
include: [
|
|
{ model: User, attributes: { exclude: ['hash', 'email', 'emailVerified', 'koins', 'currency2', 'emailToken', 'passwordResetExpiry', 'passwordResetToken', 'experimentMode', 'developerMode', 'cookieOptOut', 'deleteCode', 'jwtOffset'] } },
|
|
{ model: PollAnswer, include: [PollVote] }
|
|
]
|
|
})
|
|
if(!pollQuestion) throw Errors.sequelizeValidation(Sequelize, {
|
|
error: 'Poll ID is invalid!',
|
|
value: id
|
|
})
|
|
|
|
let totalVotes = pollQuestion.PollAnswers.reduce((sum, answer) => {
|
|
return sum + answer.PollVotes.length
|
|
}, 0)
|
|
|
|
let answersWithPercent = pollQuestion.PollAnswers.map(answer => {
|
|
let jsonAnswer = answer.toJSON()
|
|
let percent = answer.PollVotes.length / totalVotes
|
|
jsonAnswer.percent = Math.round(percent*100 * 10) / 10
|
|
|
|
return jsonAnswer
|
|
})
|
|
|
|
let hasVoted = await PollVote.findOne({
|
|
where: {
|
|
UserId: req.userData.UserId,
|
|
PollQuestionId: id
|
|
}
|
|
})
|
|
|
|
let jsonPollQuestion = pollQuestion.toJSON()
|
|
jsonPollQuestion.totalVotes = totalVotes
|
|
jsonPollQuestion.PollAnswers = answersWithPercent
|
|
jsonPollQuestion.hasVoted = !!hasVoted
|
|
|
|
res.json(jsonPollQuestion)
|
|
} catch (e) { next(e) }
|
|
})
|
|
|
|
router.all('*', auth, (req, res, next) => {
|
|
if(req.userData.loggedIn) {
|
|
next()
|
|
} else {
|
|
res.status(401)
|
|
res.json({
|
|
errors: [Errors.requestNotAuthorized]
|
|
})
|
|
}
|
|
})
|
|
|
|
router.post('/', auth, async(req, res, next) => {
|
|
try {
|
|
let threadId = req.body.threadId
|
|
let thread = await Thread.findByPk(req.body.threadId)
|
|
if(!thread) {
|
|
throw Errors.sequelizeValidation(Sequelize, {
|
|
error: 'You tried voting on a poll on a post that didn\'t exist?',
|
|
value: threadId
|
|
})
|
|
} else if(thread.UserId !== req.userData.UserId) {
|
|
throw Errors.requestNotAuthorized
|
|
} else if(thread.PollQuestionId) {
|
|
throw Errors.sequelizeValidation(Sequelize, {
|
|
error: 'invalid thread id',
|
|
value: threadId
|
|
})
|
|
}
|
|
|
|
let answers = req.body.answers
|
|
|
|
if(!answers || answers.length > 6) {
|
|
throw Errors.sequelizeValidation(Sequelize, {
|
|
error: 'You can only make up to 6 answers per poll',
|
|
value: answers
|
|
})
|
|
}
|
|
if(!answers || answers.length < 2) {
|
|
throw Errors.sequelizeValidation(Sequelize, {
|
|
error: 'You must provide at least 2 answers',
|
|
value: answers
|
|
})
|
|
} else if(answers.length !== new Set(answers).size) {
|
|
throw Errors.sequelizeValidation(Sequelize, {
|
|
error: 'Answers cannot contain any duplicates',
|
|
value: answers
|
|
})
|
|
}
|
|
|
|
let pollQuestion = await PollQuestion.create({
|
|
UserId: req.userData.UserId,
|
|
question: req.body.question
|
|
})
|
|
let pollAnswers = await Promise.all(
|
|
answers.map(answer => {
|
|
return PollAnswer.create({ answer })
|
|
})
|
|
)
|
|
|
|
//Set associations
|
|
await thread.setPollQuestion(pollQuestion)
|
|
await Promise.all(
|
|
pollAnswers.map(pollAnswer => {
|
|
return pollQuestion.addPollAnswer(pollAnswer)
|
|
})
|
|
)
|
|
|
|
res.json(pollQuestion.toJSON())
|
|
|
|
} catch (e) { next(e) }
|
|
})
|
|
|
|
router.post('/:id', auth, async(req, res, next) => {
|
|
try {
|
|
let previousVote = await PollVote.findOne({
|
|
where: { PollQuestionId: req.params.id, UserId: req.userData.UserId }
|
|
})
|
|
if(previousVote) throw Errors.sequelizeValidation(Sequelize, {
|
|
error: 'you cannot vote twice',
|
|
value: req.params.id
|
|
})
|
|
|
|
let poll = await PollQuestion.findByPk(req.params.id, {
|
|
include: [PollAnswer]
|
|
})
|
|
if(!poll) throw Errors.sequelizeValidation(Sequelize, {
|
|
error: 'invalid poll id',
|
|
value: req.params.id
|
|
})
|
|
|
|
let pollAnswer = poll.PollAnswers.find(a => a.answer === req.body.answer)
|
|
if(!pollAnswer) throw Errors.sequelizeValidation(Sequelize, {
|
|
error: 'invalid answer',
|
|
value: req.body.answer
|
|
})
|
|
|
|
let pollVote = await PollVote.create({ UserId: req.userData.UserId })
|
|
await pollVote.setPollQuestion(poll)
|
|
await pollVote.setPollAnswer(pollAnswer)
|
|
|
|
res.redirect('/api/v1/forums/poll/' + req.params.id)
|
|
} catch (e) { next(e) }
|
|
})
|
|
|
|
module.exports = router
|