|
@@ -2,20 +2,21 @@ let express = require('express')
|
|
|
let router = express.Router()
|
|
|
|
|
|
const Errors = require('../lib/errors')
|
|
|
-let { User, Thread, Post, Notification } = require('../models')
|
|
|
+let { User, Thread, Post, Notification, Sequelize, sequelize } = require('../models')
|
|
|
|
|
|
router.get('/:post_id', async (req, res) => {
|
|
|
try {
|
|
|
let post = await Post.findById(req.params.post_id, { include: Post.includeOptions() })
|
|
|
- if(!post) throw Errors.invalidParameter('id', 'post does not exist')
|
|
|
+ if(!post) throw Errors.sequelizeValidation(Sequelize, {
|
|
|
+ error: 'post does not exist',
|
|
|
+ path: 'id'
|
|
|
+ })
|
|
|
|
|
|
res.json(post.toJSON())
|
|
|
} catch (e) {
|
|
|
- if(e.name === 'invalidParameter') {
|
|
|
+ if(e instanceof Sequelize.ValidationError) {
|
|
|
res.status(400)
|
|
|
- res.json({
|
|
|
- errors: [e]
|
|
|
- })
|
|
|
+ res.json(e)
|
|
|
} else {
|
|
|
res.status(500)
|
|
|
res.json({
|
|
@@ -36,35 +37,6 @@ router.all('*', (req, res, next) => {
|
|
|
}
|
|
|
})
|
|
|
|
|
|
-router.delete('/:post_id', async (req, res) => {
|
|
|
- try {
|
|
|
- if(!req.session.admin) {
|
|
|
- throw Errors.requestNotAuthorized
|
|
|
- } else {
|
|
|
- let post = await Post.findById(req.params.post_id)
|
|
|
- if(!post) throw Errors.invalidParameter('postId', 'post does not exist')
|
|
|
-
|
|
|
- await post.update({ content: '[This post has been removed by an administrator]', removed: true })
|
|
|
-
|
|
|
- res.json({ success: true })
|
|
|
- }
|
|
|
- } catch (e) {
|
|
|
- if(e.name === 'requestNotAuthorized') {
|
|
|
- res.status(401)
|
|
|
- res.json({ errors: [e] })
|
|
|
- } else if(e.name === 'invalidParameter') {
|
|
|
- res.status(400)
|
|
|
- res.json({ errors: [e] })
|
|
|
- } else {
|
|
|
- console.log(e)
|
|
|
-
|
|
|
- res.status(500)
|
|
|
- res.json({
|
|
|
- errors: [Errors.unknown]
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
-})
|
|
|
|
|
|
router.put('/:post_id/like', async (req, res) => {
|
|
|
try {
|
|
@@ -125,31 +97,13 @@ router.delete('/:post_id/like', async (req, res) => {
|
|
|
|
|
|
router.post('/', async (req, res) => {
|
|
|
let validationErrors = []
|
|
|
- let thread, replyingToPost, post
|
|
|
+ let thread, replyingToPost, post, uniqueMentions = []
|
|
|
|
|
|
try {
|
|
|
- if(req.body.content === undefined) {
|
|
|
- validationErrors.push(Errors.missingParameter('content'))
|
|
|
- } else if(typeof req.body.content !== 'string') {
|
|
|
- validationErrors.push(Errors.invalidParameterType('content', 'string'))
|
|
|
- } if (req.body.threadId === undefined) {
|
|
|
- validationErrors.push(Errors.missingParameter('threadId'))
|
|
|
- } else if(!Number.isInteger(req.body.threadId)) {
|
|
|
- validationErrors.push(Errors.invalidParameterType('threadId', 'integer'))
|
|
|
- } if(req.body.replyingToId !== undefined && !Number.isInteger(req.body.replyingToId)) {
|
|
|
- validationErrors.push(Errors.invalidParameterType('replyingToId', 'integer'))
|
|
|
- } if(req.body.mentions !== undefined) {
|
|
|
- if(Array.isArray(req.body.mentions)) {
|
|
|
- if(req.body.mentions.some(m => typeof m !== 'string')) {
|
|
|
- validationErrors.push(Errors.invalidParameterType('mention', 'string'))
|
|
|
- }
|
|
|
- } else {
|
|
|
- validationErrors.push(Errors.invalidParameterType('mentions', 'array'))
|
|
|
- }
|
|
|
+ if(req.body.mentions) {
|
|
|
+ uniqueMentions = Notification.filterMentions(req.body.mentions)
|
|
|
}
|
|
|
|
|
|
- if(validationErrors.length) throw Errors.VALIDATION_ERROR
|
|
|
-
|
|
|
thread = await Thread.findOne({ where: {
|
|
|
id: req.body.threadId
|
|
|
}})
|
|
@@ -157,42 +111,32 @@ router.post('/', async (req, res) => {
|
|
|
username: req.session.username
|
|
|
}})
|
|
|
|
|
|
- if(!thread) throw Errors.invalidParameter('threadId', 'thread does not exist')
|
|
|
+ if(!thread) throw Errors.sequelizeValidation(Sequelize, {
|
|
|
+ error: 'thread does not exist',
|
|
|
+ path: 'id'
|
|
|
+ })
|
|
|
if(thread.locked) throw Errors.threadLocked
|
|
|
|
|
|
if(req.body.replyingToId) {
|
|
|
- replyingToPost = await Post.findById(
|
|
|
- req.body.replyingToId,
|
|
|
- { include: [Thread, { model: User, attributes: ['username'] }] }
|
|
|
+ replyingToPost = await Post.getReplyingToPost(
|
|
|
+ req.body.replyingToId, thread
|
|
|
)
|
|
|
|
|
|
- if(!replyingToPost) {
|
|
|
- throw Errors.invalidParameter('replyingToId', 'post does not exist')
|
|
|
- } else if(replyingToPost.Thread.id !== thread.id) {
|
|
|
- throw Errors.invalidParameter('replyingToId', 'replies must be in same thread')
|
|
|
- } else if (replyingToPost.removed) {
|
|
|
- throw Errors.postRemoved
|
|
|
- } else {
|
|
|
- post = await Post.create({ content: req.body.content, postNumber: thread.postsCount })
|
|
|
-
|
|
|
- await post.setReplyingTo(replyingToPost)
|
|
|
- await replyingToPost.addReplies(post)
|
|
|
+ post = await Post.create({ content: req.body.content, postNumber: thread.postsCount })
|
|
|
|
|
|
- let replyNotification = await Notification.createPostNotification({
|
|
|
- usernameTo: replyingToPost.User.username,
|
|
|
- userFrom: user,
|
|
|
- type: 'reply',
|
|
|
- post: post
|
|
|
- })
|
|
|
+ await post.setReplyingTo(replyingToPost)
|
|
|
+ await replyingToPost.addReplies(post)
|
|
|
|
|
|
- let ioUsers = req.app.get('io-users')
|
|
|
- if(ioUsers[replyingToPost.User.username]) {
|
|
|
- req.app
|
|
|
- .get('io')
|
|
|
- .to(ioUsers[replyingToPost.User.username])
|
|
|
- .emit('notification', replyNotification.toJSON())
|
|
|
- }
|
|
|
- }
|
|
|
+ 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 {
|
|
|
post = await Post.create({ content: req.body.content, postNumber: thread.postsCount })
|
|
|
}
|
|
@@ -202,26 +146,20 @@ router.post('/', async (req, res) => {
|
|
|
|
|
|
await thread.increment('postsCount')
|
|
|
|
|
|
- if(req.body.mentions) {
|
|
|
- let uniqueMentions = req.body.mentions.filter((mention, pos, self) => {
|
|
|
- return self.indexOf(mention) === pos
|
|
|
- })
|
|
|
-
|
|
|
- for(var i = 0; i < uniqueMentions.length; i++) {
|
|
|
- let mention = uniqueMentions[i]
|
|
|
- let ioUsers = req.app.get('io-users')
|
|
|
+ if(uniqueMentions.length) {
|
|
|
+ let ioUsers = req.app.get('io-users')
|
|
|
+ let io = req.app.get('io')
|
|
|
|
|
|
+ uniqueMentions.forEach(async mention => {
|
|
|
let mentionNotification = await Notification.createPostNotification({
|
|
|
usernameTo: mention,
|
|
|
userFrom: user,
|
|
|
type: 'mention',
|
|
|
post
|
|
|
})
|
|
|
-
|
|
|
- if(ioUsers[mention]) {
|
|
|
- req.app.get('io').to(ioUsers[mention]).emit('notification', mentionNotification.toJSON())
|
|
|
- }
|
|
|
- }
|
|
|
+
|
|
|
+ await mentionNotification.emitNotificationMessage(ioUsers, io)
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
res.json(await post.reload({
|
|
@@ -233,12 +171,10 @@ router.post('/', async (req, res) => {
|
|
|
})
|
|
|
|
|
|
} catch (e) {
|
|
|
- if(e === Errors.VALIDATION_ERROR) {
|
|
|
+ if(e instanceof Sequelize.ValidationError) {
|
|
|
res.status(400)
|
|
|
- res.json({
|
|
|
- errors: validationErrors
|
|
|
- })
|
|
|
- } else if(['invalidParameter', 'threadLocked', 'postRemoved'].indexOf(e.name) > -1) {
|
|
|
+ res.json(e)
|
|
|
+ } else if(e.name in Errors) {
|
|
|
res.status(400)
|
|
|
res.json({
|
|
|
errors: [e]
|
|
@@ -253,4 +189,41 @@ router.post('/', async (req, res) => {
|
|
|
}
|
|
|
})
|
|
|
|
|
|
+router.all('*', (req, res, next) => {
|
|
|
+ if(!req.session.admin) {
|
|
|
+ res.status(401)
|
|
|
+ res.json({
|
|
|
+ errors: [Errors.requestNotAuthorized]
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ next()
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+router.delete('/:post_id', async (req, res) => {
|
|
|
+ try {
|
|
|
+ let post = await Post.findById(req.params.post_id)
|
|
|
+ if(!post) throw Errors.sequelizeValidation(Sequelize, {
|
|
|
+ error: 'post does not exist',
|
|
|
+ path: 'id'
|
|
|
+ })
|
|
|
+
|
|
|
+ await post.update({ content: '[This post has been removed by an administrator]', removed: true })
|
|
|
+
|
|
|
+ res.json({ success: true })
|
|
|
+ } catch (e) {
|
|
|
+ if(e instanceof Sequelize.ValidationError) {
|
|
|
+ res.status(400)
|
|
|
+ res.json(e)
|
|
|
+ } else {
|
|
|
+ console.log(e)
|
|
|
+
|
|
|
+ res.status(500)
|
|
|
+ res.json({
|
|
|
+ errors: [Errors.unknown]
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
module.exports = router
|