diff options
Diffstat (limited to 'server/middlewares/validators')
-rw-r--r-- | server/middlewares/validators/abuse.ts | 74 | ||||
-rw-r--r-- | server/middlewares/validators/videos/video-comments.ts | 70 |
2 files changed, 57 insertions, 87 deletions
diff --git a/server/middlewares/validators/abuse.ts b/server/middlewares/validators/abuse.ts index f098e2ff9..048dbead0 100644 --- a/server/middlewares/validators/abuse.ts +++ b/server/middlewares/validators/abuse.ts | |||
@@ -1,6 +1,7 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { body, param, query } from 'express-validator' | 2 | import { body, param, query } from 'express-validator' |
3 | import { | 3 | import { |
4 | isAbuseFilterValid, | ||
4 | isAbuseModerationCommentValid, | 5 | isAbuseModerationCommentValid, |
5 | isAbusePredefinedReasonsValid, | 6 | isAbusePredefinedReasonsValid, |
6 | isAbusePredefinedReasonValid, | 7 | isAbusePredefinedReasonValid, |
@@ -11,29 +12,28 @@ import { | |||
11 | isAbuseVideoIsValid | 12 | isAbuseVideoIsValid |
12 | } from '@server/helpers/custom-validators/abuses' | 13 | } from '@server/helpers/custom-validators/abuses' |
13 | import { exists, isIdOrUUIDValid, isIdValid, toIntOrNull } from '@server/helpers/custom-validators/misc' | 14 | import { exists, isIdOrUUIDValid, isIdValid, toIntOrNull } from '@server/helpers/custom-validators/misc' |
15 | import { doesCommentIdExist } from '@server/helpers/custom-validators/video-comments' | ||
14 | import { logger } from '@server/helpers/logger' | 16 | import { logger } from '@server/helpers/logger' |
15 | import { doesAbuseExist, doesVideoAbuseExist, doesVideoExist } from '@server/helpers/middlewares' | 17 | import { doesAbuseExist, doesAccountIdExist, doesVideoAbuseExist, doesVideoExist } from '@server/helpers/middlewares' |
18 | import { AbuseCreate } from '@shared/models' | ||
16 | import { areValidationErrors } from './utils' | 19 | import { areValidationErrors } from './utils' |
17 | 20 | ||
18 | const abuseReportValidator = [ | 21 | const abuseReportValidator = [ |
19 | param('videoId') | 22 | body('account.id') |
23 | .optional() | ||
24 | .custom(isIdValid) | ||
25 | .withMessage('Should have a valid accountId'), | ||
26 | |||
27 | body('video.id') | ||
28 | .optional() | ||
20 | .custom(isIdOrUUIDValid) | 29 | .custom(isIdOrUUIDValid) |
21 | .not() | ||
22 | .isEmpty() | ||
23 | .withMessage('Should have a valid videoId'), | 30 | .withMessage('Should have a valid videoId'), |
24 | body('reason') | 31 | body('video.startAt') |
25 | .custom(isAbuseReasonValid) | ||
26 | .withMessage('Should have a valid reason'), | ||
27 | body('predefinedReasons') | ||
28 | .optional() | ||
29 | .custom(isAbusePredefinedReasonsValid) | ||
30 | .withMessage('Should have a valid list of predefined reasons'), | ||
31 | body('startAt') | ||
32 | .optional() | 32 | .optional() |
33 | .customSanitizer(toIntOrNull) | 33 | .customSanitizer(toIntOrNull) |
34 | .custom(isAbuseTimestampValid) | 34 | .custom(isAbuseTimestampValid) |
35 | .withMessage('Should have valid starting time value'), | 35 | .withMessage('Should have valid starting time value'), |
36 | body('endAt') | 36 | body('video.endAt') |
37 | .optional() | 37 | .optional() |
38 | .customSanitizer(toIntOrNull) | 38 | .customSanitizer(toIntOrNull) |
39 | .custom(isAbuseTimestampValid) | 39 | .custom(isAbuseTimestampValid) |
@@ -42,47 +42,70 @@ const abuseReportValidator = [ | |||
42 | .custom(isAbuseTimestampCoherent) | 42 | .custom(isAbuseTimestampCoherent) |
43 | .withMessage('Should have a startAt timestamp beginning before endAt'), | 43 | .withMessage('Should have a startAt timestamp beginning before endAt'), |
44 | 44 | ||
45 | body('comment.id') | ||
46 | .optional() | ||
47 | .custom(isIdValid) | ||
48 | .withMessage('Should have a valid commentId'), | ||
49 | |||
50 | body('reason') | ||
51 | .custom(isAbuseReasonValid) | ||
52 | .withMessage('Should have a valid reason'), | ||
53 | |||
54 | body('predefinedReasons') | ||
55 | .optional() | ||
56 | .custom(isAbusePredefinedReasonsValid) | ||
57 | .withMessage('Should have a valid list of predefined reasons'), | ||
58 | |||
45 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { | 59 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
46 | logger.debug('Checking abuseReport parameters', { parameters: req.body }) | 60 | logger.debug('Checking abuseReport parameters', { parameters: req.body }) |
47 | 61 | ||
48 | if (areValidationErrors(req, res)) return | 62 | if (areValidationErrors(req, res)) return |
49 | if (!await doesVideoExist(req.params.videoId, res)) return | ||
50 | 63 | ||
51 | // TODO: check comment or video (exlusive) | 64 | const body: AbuseCreate = req.body |
65 | |||
66 | if (body.video?.id && !await doesVideoExist(body.video.id, res)) return | ||
67 | if (body.account?.id && !await doesAccountIdExist(body.account.id, res)) return | ||
68 | if (body.comment?.id && !await doesCommentIdExist(body.comment.id, res)) return | ||
69 | |||
70 | if (!body.video?.id && !body.account?.id && !body.comment?.id) { | ||
71 | res.status(400) | ||
72 | .json({ error: 'video id or account id or comment id is required.' }) | ||
73 | |||
74 | return | ||
75 | } | ||
52 | 76 | ||
53 | return next() | 77 | return next() |
54 | } | 78 | } |
55 | ] | 79 | ] |
56 | 80 | ||
57 | const abuseGetValidator = [ | 81 | const abuseGetValidator = [ |
58 | param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), | ||
59 | param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'), | 82 | param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'), |
60 | 83 | ||
61 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { | 84 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
62 | logger.debug('Checking abuseGetValidator parameters', { parameters: req.body }) | 85 | logger.debug('Checking abuseGetValidator parameters', { parameters: req.body }) |
63 | 86 | ||
64 | if (areValidationErrors(req, res)) return | 87 | if (areValidationErrors(req, res)) return |
65 | // if (!await doesAbuseExist(req.params.id, req.params.videoId, res)) return | 88 | if (!await doesAbuseExist(req.params.id, res)) return |
66 | 89 | ||
67 | return next() | 90 | return next() |
68 | } | 91 | } |
69 | ] | 92 | ] |
70 | 93 | ||
71 | const abuseUpdateValidator = [ | 94 | const abuseUpdateValidator = [ |
72 | param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), | ||
73 | param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'), | 95 | param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'), |
96 | |||
74 | body('state') | 97 | body('state') |
75 | .optional() | 98 | .optional() |
76 | .custom(isAbuseStateValid).withMessage('Should have a valid video abuse state'), | 99 | .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'), |
77 | body('moderationComment') | 100 | body('moderationComment') |
78 | .optional() | 101 | .optional() |
79 | .custom(isAbuseModerationCommentValid).withMessage('Should have a valid video moderation comment'), | 102 | .custom(isAbuseModerationCommentValid).withMessage('Should have a valid moderation comment'), |
80 | 103 | ||
81 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { | 104 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
82 | logger.debug('Checking abuseUpdateValidator parameters', { parameters: req.body }) | 105 | logger.debug('Checking abuseUpdateValidator parameters', { parameters: req.body }) |
83 | 106 | ||
84 | if (areValidationErrors(req, res)) return | 107 | if (areValidationErrors(req, res)) return |
85 | // if (!await doesAbuseExist(req.params.id, req.params.videoId, res)) return | 108 | if (!await doesAbuseExist(req.params.id, res)) return |
86 | 109 | ||
87 | return next() | 110 | return next() |
88 | } | 111 | } |
@@ -92,6 +115,10 @@ const abuseListValidator = [ | |||
92 | query('id') | 115 | query('id') |
93 | .optional() | 116 | .optional() |
94 | .custom(isIdValid).withMessage('Should have a valid id'), | 117 | .custom(isIdValid).withMessage('Should have a valid id'), |
118 | query('filter') | ||
119 | .optional() | ||
120 | .custom(isAbuseFilterValid) | ||
121 | .withMessage('Should have a valid filter'), | ||
95 | query('predefinedReason') | 122 | query('predefinedReason') |
96 | .optional() | 123 | .optional() |
97 | .custom(isAbusePredefinedReasonValid) | 124 | .custom(isAbusePredefinedReasonValid) |
@@ -151,10 +178,7 @@ const videoAbuseReportValidator = [ | |||
151 | .optional() | 178 | .optional() |
152 | .customSanitizer(toIntOrNull) | 179 | .customSanitizer(toIntOrNull) |
153 | .custom(isAbuseTimestampValid) | 180 | .custom(isAbuseTimestampValid) |
154 | .withMessage('Should have valid ending time value') | 181 | .withMessage('Should have valid ending time value'), |
155 | .bail() | ||
156 | .custom(isAbuseTimestampCoherent) | ||
157 | .withMessage('Should have a startAt timestamp beginning before endAt'), | ||
158 | 182 | ||
159 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { | 183 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
160 | logger.debug('Checking videoAbuseReport parameters', { parameters: req.body }) | 184 | logger.debug('Checking videoAbuseReport parameters', { parameters: req.body }) |
diff --git a/server/middlewares/validators/videos/video-comments.ts b/server/middlewares/validators/videos/video-comments.ts index ef019fcf9..77f5c6ff3 100644 --- a/server/middlewares/validators/videos/video-comments.ts +++ b/server/middlewares/validators/videos/video-comments.ts | |||
@@ -3,13 +3,16 @@ import { body, param } from 'express-validator' | |||
3 | import { MUserAccountUrl } from '@server/types/models' | 3 | import { MUserAccountUrl } from '@server/types/models' |
4 | import { UserRight } from '../../../../shared' | 4 | import { UserRight } from '../../../../shared' |
5 | import { isIdOrUUIDValid, isIdValid } from '../../../helpers/custom-validators/misc' | 5 | import { isIdOrUUIDValid, isIdValid } from '../../../helpers/custom-validators/misc' |
6 | import { isValidVideoCommentText } from '../../../helpers/custom-validators/video-comments' | 6 | import { |
7 | doesVideoCommentExist, | ||
8 | doesVideoCommentThreadExist, | ||
9 | isValidVideoCommentText | ||
10 | } from '../../../helpers/custom-validators/video-comments' | ||
7 | import { logger } from '../../../helpers/logger' | 11 | import { logger } from '../../../helpers/logger' |
8 | import { doesVideoExist } from '../../../helpers/middlewares' | 12 | import { doesVideoExist } from '../../../helpers/middlewares' |
9 | import { AcceptResult, isLocalVideoCommentReplyAccepted, isLocalVideoThreadAccepted } from '../../../lib/moderation' | 13 | import { AcceptResult, isLocalVideoCommentReplyAccepted, isLocalVideoThreadAccepted } from '../../../lib/moderation' |
10 | import { Hooks } from '../../../lib/plugins/hooks' | 14 | import { Hooks } from '../../../lib/plugins/hooks' |
11 | import { VideoCommentModel } from '../../../models/video/video-comment' | 15 | import { MCommentOwnerVideoReply, MVideo, MVideoFullLight } from '../../../types/models/video' |
12 | import { MCommentOwnerVideoReply, MVideo, MVideoFullLight, MVideoId } from '../../../types/models/video' | ||
13 | import { areValidationErrors } from '../utils' | 16 | import { areValidationErrors } from '../utils' |
14 | 17 | ||
15 | const listVideoCommentThreadsValidator = [ | 18 | const listVideoCommentThreadsValidator = [ |
@@ -120,67 +123,10 @@ export { | |||
120 | 123 | ||
121 | // --------------------------------------------------------------------------- | 124 | // --------------------------------------------------------------------------- |
122 | 125 | ||
123 | async function doesVideoCommentThreadExist (idArg: number | string, video: MVideoId, res: express.Response) { | ||
124 | const id = parseInt(idArg + '', 10) | ||
125 | const videoComment = await VideoCommentModel.loadById(id) | ||
126 | |||
127 | if (!videoComment) { | ||
128 | res.status(404) | ||
129 | .json({ error: 'Video comment thread not found' }) | ||
130 | .end() | ||
131 | |||
132 | return false | ||
133 | } | ||
134 | |||
135 | if (videoComment.videoId !== video.id) { | ||
136 | res.status(400) | ||
137 | .json({ error: 'Video comment is not associated to this video.' }) | ||
138 | .end() | ||
139 | |||
140 | return false | ||
141 | } | ||
142 | |||
143 | if (videoComment.inReplyToCommentId !== null) { | ||
144 | res.status(400) | ||
145 | .json({ error: 'Video comment is not a thread.' }) | ||
146 | .end() | ||
147 | |||
148 | return false | ||
149 | } | ||
150 | |||
151 | res.locals.videoCommentThread = videoComment | ||
152 | return true | ||
153 | } | ||
154 | |||
155 | async function doesVideoCommentExist (idArg: number | string, video: MVideoId, res: express.Response) { | ||
156 | const id = parseInt(idArg + '', 10) | ||
157 | const videoComment = await VideoCommentModel.loadByIdAndPopulateVideoAndAccountAndReply(id) | ||
158 | |||
159 | if (!videoComment) { | ||
160 | res.status(404) | ||
161 | .json({ error: 'Video comment thread not found' }) | ||
162 | .end() | ||
163 | |||
164 | return false | ||
165 | } | ||
166 | |||
167 | if (videoComment.videoId !== video.id) { | ||
168 | res.status(400) | ||
169 | .json({ error: 'Video comment is not associated to this video.' }) | ||
170 | .end() | ||
171 | |||
172 | return false | ||
173 | } | ||
174 | |||
175 | res.locals.videoCommentFull = videoComment | ||
176 | return true | ||
177 | } | ||
178 | |||
179 | function isVideoCommentsEnabled (video: MVideo, res: express.Response) { | 126 | function isVideoCommentsEnabled (video: MVideo, res: express.Response) { |
180 | if (video.commentsEnabled !== true) { | 127 | if (video.commentsEnabled !== true) { |
181 | res.status(409) | 128 | res.status(409) |
182 | .json({ error: 'Video comments are disabled for this video.' }) | 129 | .json({ error: 'Video comments are disabled for this video.' }) |
183 | .end() | ||
184 | 130 | ||
185 | return false | 131 | return false |
186 | } | 132 | } |
@@ -192,7 +138,7 @@ function checkUserCanDeleteVideoComment (user: MUserAccountUrl, videoComment: MC | |||
192 | if (videoComment.isDeleted()) { | 138 | if (videoComment.isDeleted()) { |
193 | res.status(409) | 139 | res.status(409) |
194 | .json({ error: 'This comment is already deleted' }) | 140 | .json({ error: 'This comment is already deleted' }) |
195 | .end() | 141 | |
196 | return false | 142 | return false |
197 | } | 143 | } |
198 | 144 | ||
@@ -240,7 +186,7 @@ async function isVideoCommentAccepted (req: express.Request, res: express.Respon | |||
240 | if (!acceptedResult || acceptedResult.accepted !== true) { | 186 | if (!acceptedResult || acceptedResult.accepted !== true) { |
241 | logger.info('Refused local comment.', { acceptedResult, acceptParameters }) | 187 | logger.info('Refused local comment.', { acceptedResult, acceptParameters }) |
242 | res.status(403) | 188 | res.status(403) |
243 | .json({ error: acceptedResult.errorMessage || 'Refused local comment' }) | 189 | .json({ error: acceptedResult.errorMessage || 'Refused local comment' }) |
244 | 190 | ||
245 | return false | 191 | return false |
246 | } | 192 | } |