cubash-archive/routes/poll.js

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