]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/middlewares/validators/video-comments.ts
add resize listener (#1182)
[github/Chocobozzz/PeerTube.git] / server / middlewares / validators / video-comments.ts
1 import * as express from 'express'
2 import { body, param } from 'express-validator/check'
3 import { UserRight } from '../../../shared'
4 import { isIdOrUUIDValid, isIdValid } from '../../helpers/custom-validators/misc'
5 import { isValidVideoCommentText } from '../../helpers/custom-validators/video-comments'
6 import { isVideoExist } from '../../helpers/custom-validators/videos'
7 import { logger } from '../../helpers/logger'
8 import { UserModel } from '../../models/account/user'
9 import { VideoModel } from '../../models/video/video'
10 import { VideoCommentModel } from '../../models/video/video-comment'
11 import { areValidationErrors } from './utils'
12
13 const listVideoCommentThreadsValidator = [
14 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
15
16 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
17 logger.debug('Checking listVideoCommentThreads parameters.', { parameters: req.params })
18
19 if (areValidationErrors(req, res)) return
20 if (!await isVideoExist(req.params.videoId, res, 'only-video')) return
21
22 return next()
23 }
24 ]
25
26 const listVideoThreadCommentsValidator = [
27 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
28 param('threadId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid threadId'),
29
30 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
31 logger.debug('Checking listVideoThreadComments parameters.', { parameters: req.params })
32
33 if (areValidationErrors(req, res)) return
34 if (!await isVideoExist(req.params.videoId, res, 'only-video')) return
35 if (!await isVideoCommentThreadExist(req.params.threadId, res.locals.video, res)) return
36
37 return next()
38 }
39 ]
40
41 const addVideoCommentThreadValidator = [
42 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
43 body('text').custom(isValidVideoCommentText).not().isEmpty().withMessage('Should have a valid comment text'),
44
45 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
46 logger.debug('Checking addVideoCommentThread parameters.', { parameters: req.params, body: req.body })
47
48 if (areValidationErrors(req, res)) return
49 if (!await isVideoExist(req.params.videoId, res)) return
50 if (!isVideoCommentsEnabled(res.locals.video, res)) return
51
52 return next()
53 }
54 ]
55
56 const addVideoCommentReplyValidator = [
57 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
58 param('commentId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid commentId'),
59 body('text').custom(isValidVideoCommentText).not().isEmpty().withMessage('Should have a valid comment text'),
60
61 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
62 logger.debug('Checking addVideoCommentReply parameters.', { parameters: req.params, body: req.body })
63
64 if (areValidationErrors(req, res)) return
65 if (!await isVideoExist(req.params.videoId, res)) return
66 if (!isVideoCommentsEnabled(res.locals.video, res)) return
67 if (!await isVideoCommentExist(req.params.commentId, res.locals.video, res)) return
68
69 return next()
70 }
71 ]
72
73 const videoCommentGetValidator = [
74 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
75 param('commentId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid commentId'),
76
77 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
78 logger.debug('Checking videoCommentGetValidator parameters.', { parameters: req.params })
79
80 if (areValidationErrors(req, res)) return
81 if (!await isVideoExist(req.params.videoId, res, 'id')) return
82 if (!await isVideoCommentExist(req.params.commentId, res.locals.video, res)) return
83
84 return next()
85 }
86 ]
87
88 const removeVideoCommentValidator = [
89 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
90 param('commentId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid commentId'),
91
92 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
93 logger.debug('Checking removeVideoCommentValidator parameters.', { parameters: req.params })
94
95 if (areValidationErrors(req, res)) return
96 if (!await isVideoExist(req.params.videoId, res)) return
97 if (!await isVideoCommentExist(req.params.commentId, res.locals.video, res)) return
98
99 // Check if the user who did the request is able to delete the video
100 if (!checkUserCanDeleteVideoComment(res.locals.oauth.token.User, res.locals.videoComment, res)) return
101
102 return next()
103 }
104 ]
105
106 // ---------------------------------------------------------------------------
107
108 export {
109 listVideoCommentThreadsValidator,
110 listVideoThreadCommentsValidator,
111 addVideoCommentThreadValidator,
112 addVideoCommentReplyValidator,
113 videoCommentGetValidator,
114 removeVideoCommentValidator
115 }
116
117 // ---------------------------------------------------------------------------
118
119 async function isVideoCommentThreadExist (id: number, video: VideoModel, res: express.Response) {
120 const videoComment = await VideoCommentModel.loadById(id)
121
122 if (!videoComment) {
123 res.status(404)
124 .json({ error: 'Video comment thread not found' })
125 .end()
126
127 return false
128 }
129
130 if (videoComment.videoId !== video.id) {
131 res.status(400)
132 .json({ error: 'Video comment is associated to this video.' })
133 .end()
134
135 return false
136 }
137
138 if (videoComment.inReplyToCommentId !== null) {
139 res.status(400)
140 .json({ error: 'Video comment is not a thread.' })
141 .end()
142
143 return false
144 }
145
146 res.locals.videoCommentThread = videoComment
147 return true
148 }
149
150 async function isVideoCommentExist (id: number, video: VideoModel, res: express.Response) {
151 const videoComment = await VideoCommentModel.loadByIdAndPopulateVideoAndAccountAndReply(id)
152
153 if (!videoComment) {
154 res.status(404)
155 .json({ error: 'Video comment thread not found' })
156 .end()
157
158 return false
159 }
160
161 if (videoComment.videoId !== video.id) {
162 res.status(400)
163 .json({ error: 'Video comment is associated to this video.' })
164 .end()
165
166 return false
167 }
168
169 res.locals.videoComment = videoComment
170 return true
171 }
172
173 function isVideoCommentsEnabled (video: VideoModel, res: express.Response) {
174 if (video.commentsEnabled !== true) {
175 res.status(409)
176 .json({ error: 'Video comments are disabled for this video.' })
177 .end()
178
179 return false
180 }
181
182 return true
183 }
184
185 function checkUserCanDeleteVideoComment (user: UserModel, videoComment: VideoCommentModel, res: express.Response) {
186 const account = videoComment.Account
187 if (user.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT) === false && account.userId !== user.id) {
188 res.status(403)
189 .json({ error: 'Cannot remove video comment of another user' })
190 .end()
191 return false
192 }
193
194 return true
195 }