forked from kaverti/website
194 lines
4.9 KiB
JavaScript
194 lines
4.9 KiB
JavaScript
let express = require('express')
|
|
let router = express.Router()
|
|
const auth = require('../lib/auth')
|
|
|
|
const Errors = require('../lib/errors.js')
|
|
let { User, Thread, Notification, Category, Post, Ban, Report, Sequelize } = require('../models')
|
|
let pagination = require('../lib/pagination.js')
|
|
const rateLimit = require("express-rate-limit");
|
|
const postLimiter = rateLimit({
|
|
windowMs: 60000,
|
|
max: 10,
|
|
message: "{\"errors\":[{\"name\":\"rateLimit\",\"message\":\"You may only make 10 requests to this endpoint per minute.\",\"status\":429}]}"
|
|
});
|
|
router.get('/:thread_id', async(req, res, next) => {
|
|
try {
|
|
let { from, limit } = pagination.getPaginationProps(req.query)
|
|
let thread = await Thread.findByPk(req.params.thread_id, {
|
|
include: Thread.includeOptions(from, limit)
|
|
})
|
|
if(!thread) throw Errors.invalidParameter('id', 'thread does not exist')
|
|
|
|
let meta = thread.getMeta(limit)
|
|
|
|
res.json(Object.assign( thread.toJSON(), { meta } ))
|
|
|
|
} catch (e) { next(e) }
|
|
})
|
|
|
|
//Only logged in routes
|
|
router.all('*', auth, (req, res, next) => {
|
|
if(req.userData.loggedIn) {
|
|
next()
|
|
} else {
|
|
res.status(401)
|
|
res.json({
|
|
errors: [Errors.requestNotAuthorized]
|
|
})
|
|
}
|
|
})
|
|
|
|
router.post('/', postLimiter, auth, async(req, res, next) => {
|
|
let validationErrors = []
|
|
|
|
try {
|
|
await Ban.ReadOnlyMode(req.userData.UserId)
|
|
|
|
let category = await Category.findOne({ where: {
|
|
value: req.body.category
|
|
}})
|
|
if (req.body.category == "ALL") throw Errors.selectCategory
|
|
if (req.body.category == "") throw Errors.selectCategory
|
|
if (!category) throw Errors.invalidCategory
|
|
if (category.locked && !req.userData.admin) throw Errors.lockedCategory
|
|
|
|
let user = await User.findOne({ where: {
|
|
username: req.userData.username
|
|
}})
|
|
|
|
if(!user.emailVerified) {
|
|
throw Errors.verifyEmail
|
|
}
|
|
|
|
|
|
let thread = await Thread.create({
|
|
name: req.body.name
|
|
})
|
|
await thread.increment('postsCount')
|
|
|
|
await thread.setCategory(category)
|
|
await thread.setUser(user)
|
|
user = await User.findOne({ where: {
|
|
username: req.userData.username
|
|
}})
|
|
|
|
|
|
if(req.body.replyingToId) {
|
|
let replyingToPost1 = Post.findByPk(
|
|
req.body.replyingToId, { include: [Thread, { model: User, attributes: ['username'] }] }
|
|
)
|
|
console.log(replyingToPost1)
|
|
replyingToPost = await Post.getReplyingToPost(
|
|
req.body.replyingToId, thread, replyingToPost1
|
|
)
|
|
|
|
var post = await Post.create({ content: req.body.content, postNumber: thread.postsCount })
|
|
|
|
await post.setReplyingTo(replyingToPost)
|
|
await replyingToPost.addReplies(post)
|
|
|
|
let replyNotification = await Notification.createPostNotification({
|
|
usernameTo: replyingToPost.User.username,
|
|
userFrom: user,
|
|
type: 'reply',
|
|
post: post
|
|
})
|
|
await replyNotification.emitNotificationMessage(
|
|
req.app.get('io-users'),
|
|
req.app.get('io')
|
|
)
|
|
} else {
|
|
var post = await Post.create({ content: req.body.content, postNumber: thread.postsCount })
|
|
}
|
|
|
|
await post.setUser(user)
|
|
await post.setThread(thread)
|
|
|
|
res.json(await thread.reload({
|
|
include: [
|
|
{ model: User, attributes: ['username', 'createdAt', 'updatedAt', 'id'] },
|
|
Category
|
|
]
|
|
}))
|
|
|
|
req.app.get('io').to('index').emit('new thread', {
|
|
name: category.name,
|
|
value: category.value
|
|
})
|
|
|
|
} catch (e) { next(e) }
|
|
})
|
|
|
|
//Only admin routes
|
|
router.all('*', auth, async(req, res, next) => {
|
|
let user = await User.findOne({ where: {
|
|
username: req.userData.username
|
|
}})
|
|
if(!user) throw Errors.requestNotAuthorized
|
|
if(req.userData.admin && user.admin) {
|
|
next()
|
|
} else {
|
|
res.status(401)
|
|
res.json({
|
|
errors: [Errors.sessionAdminProtection]
|
|
})
|
|
}
|
|
})
|
|
|
|
router.delete('/:thread_id', auth, async(req, res, next) => {
|
|
try {
|
|
let thread = await Thread.findByPk(req.params.thread_id)
|
|
|
|
if(!thread) {
|
|
throw Errors.sequelizeValidation(Sequelize, {
|
|
error: 'invalid thread id',
|
|
value: req.params.thread_id
|
|
})
|
|
} else {
|
|
//Find all posts with reports and get reports
|
|
//Then delete those reports
|
|
//Temporary fix because cascade is not working
|
|
let posts = await Post.findAll({
|
|
where: {
|
|
ThreadId: thread.id
|
|
},
|
|
include: [Report]
|
|
})
|
|
let reports = posts
|
|
.map(post => post.Reports)
|
|
.reduce((a, b) => a.concat(b), [])
|
|
|
|
let destroyPromises = reports.map(report => report.destroy())
|
|
|
|
await Promise.all(destroyPromises)
|
|
await Post.destroy({ where: { ThreadId: thread.id } })
|
|
await thread.destroy()
|
|
|
|
res.json({ success: true })
|
|
}
|
|
} catch (e) { next(e) }
|
|
})
|
|
|
|
router.put('/:thread_id', auth, async(req, res, next) => {
|
|
try {
|
|
let thread = await Thread.findByPk(req.params.thread_id)
|
|
|
|
if(!thread) {
|
|
res.status(400)
|
|
res.json({ errors:
|
|
[Errors.invalidParameter('threadId', 'thread does not exist')]
|
|
})
|
|
} else {
|
|
if(req.body.locked) {
|
|
await thread.update({ locked: true })
|
|
} else {
|
|
await thread.update({ locked: false })
|
|
}
|
|
|
|
res.json({ success: true })
|
|
}
|
|
} catch (e) { next(e) }
|
|
})
|
|
|
|
module.exports = router
|