]>
Commit | Line | Data |
---|---|---|
1 | import * as express from 'express' | |
2 | import { body, param, query } from 'express-validator' | |
3 | import { | |
4 | areAbusePredefinedReasonsValid, | |
5 | isAbuseFilterValid, | |
6 | isAbuseMessageValid, | |
7 | isAbuseModerationCommentValid, | |
8 | isAbusePredefinedReasonValid, | |
9 | isAbuseReasonValid, | |
10 | isAbuseStateValid, | |
11 | isAbuseTimestampCoherent, | |
12 | isAbuseTimestampValid, | |
13 | isAbuseVideoIsValid | |
14 | } from '@server/helpers/custom-validators/abuses' | |
15 | import { exists, isIdOrUUIDValid, isIdValid, toIntOrNull } from '@server/helpers/custom-validators/misc' | |
16 | import { doesCommentIdExist } from '@server/helpers/custom-validators/video-comments' | |
17 | import { logger } from '@server/helpers/logger' | |
18 | import { doesAbuseExist, doesAccountIdExist, doesVideoExist } from '@server/helpers/middlewares' | |
19 | import { AbuseMessageModel } from '@server/models/abuse/abuse-message' | |
20 | import { AbuseCreate, UserRight } from '@shared/models' | |
21 | import { areValidationErrors } from './utils' | |
22 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | |
23 | ||
24 | const abuseReportValidator = [ | |
25 | body('account.id') | |
26 | .optional() | |
27 | .custom(isIdValid) | |
28 | .withMessage('Should have a valid accountId'), | |
29 | ||
30 | body('video.id') | |
31 | .optional() | |
32 | .custom(isIdOrUUIDValid) | |
33 | .withMessage('Should have a valid videoId'), | |
34 | body('video.startAt') | |
35 | .optional() | |
36 | .customSanitizer(toIntOrNull) | |
37 | .custom(isAbuseTimestampValid) | |
38 | .withMessage('Should have valid starting time value'), | |
39 | body('video.endAt') | |
40 | .optional() | |
41 | .customSanitizer(toIntOrNull) | |
42 | .custom(isAbuseTimestampValid) | |
43 | .withMessage('Should have valid ending time value') | |
44 | .bail() | |
45 | .custom(isAbuseTimestampCoherent) | |
46 | .withMessage('Should have a startAt timestamp beginning before endAt'), | |
47 | ||
48 | body('comment.id') | |
49 | .optional() | |
50 | .custom(isIdValid) | |
51 | .withMessage('Should have a valid commentId'), | |
52 | ||
53 | body('reason') | |
54 | .custom(isAbuseReasonValid) | |
55 | .withMessage('Should have a valid reason'), | |
56 | ||
57 | body('predefinedReasons') | |
58 | .optional() | |
59 | .custom(areAbusePredefinedReasonsValid) | |
60 | .withMessage('Should have a valid list of predefined reasons'), | |
61 | ||
62 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
63 | logger.debug('Checking abuseReport parameters', { parameters: req.body }) | |
64 | ||
65 | if (areValidationErrors(req, res)) return | |
66 | ||
67 | const body: AbuseCreate = req.body | |
68 | ||
69 | if (body.video?.id && !await doesVideoExist(body.video.id, res)) return | |
70 | if (body.account?.id && !await doesAccountIdExist(body.account.id, res)) return | |
71 | if (body.comment?.id && !await doesCommentIdExist(body.comment.id, res)) return | |
72 | ||
73 | if (!body.video?.id && !body.account?.id && !body.comment?.id) { | |
74 | res.status(HttpStatusCode.BAD_REQUEST_400) | |
75 | .json({ error: 'video id or account id or comment id is required.' }) | |
76 | ||
77 | return | |
78 | } | |
79 | ||
80 | return next() | |
81 | } | |
82 | ] | |
83 | ||
84 | const abuseGetValidator = [ | |
85 | param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'), | |
86 | ||
87 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
88 | logger.debug('Checking abuseGetValidator parameters', { parameters: req.body }) | |
89 | ||
90 | if (areValidationErrors(req, res)) return | |
91 | if (!await doesAbuseExist(req.params.id, res)) return | |
92 | ||
93 | return next() | |
94 | } | |
95 | ] | |
96 | ||
97 | const abuseUpdateValidator = [ | |
98 | param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'), | |
99 | ||
100 | body('state') | |
101 | .optional() | |
102 | .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'), | |
103 | body('moderationComment') | |
104 | .optional() | |
105 | .custom(isAbuseModerationCommentValid).withMessage('Should have a valid moderation comment'), | |
106 | ||
107 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
108 | logger.debug('Checking abuseUpdateValidator parameters', { parameters: req.body }) | |
109 | ||
110 | if (areValidationErrors(req, res)) return | |
111 | if (!await doesAbuseExist(req.params.id, res)) return | |
112 | ||
113 | return next() | |
114 | } | |
115 | ] | |
116 | ||
117 | const abuseListForAdminsValidator = [ | |
118 | query('id') | |
119 | .optional() | |
120 | .custom(isIdValid).withMessage('Should have a valid id'), | |
121 | query('filter') | |
122 | .optional() | |
123 | .custom(isAbuseFilterValid) | |
124 | .withMessage('Should have a valid filter'), | |
125 | query('predefinedReason') | |
126 | .optional() | |
127 | .custom(isAbusePredefinedReasonValid) | |
128 | .withMessage('Should have a valid predefinedReason'), | |
129 | query('search') | |
130 | .optional() | |
131 | .custom(exists).withMessage('Should have a valid search'), | |
132 | query('state') | |
133 | .optional() | |
134 | .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'), | |
135 | query('videoIs') | |
136 | .optional() | |
137 | .custom(isAbuseVideoIsValid).withMessage('Should have a valid "video is" attribute'), | |
138 | query('searchReporter') | |
139 | .optional() | |
140 | .custom(exists).withMessage('Should have a valid reporter search'), | |
141 | query('searchReportee') | |
142 | .optional() | |
143 | .custom(exists).withMessage('Should have a valid reportee search'), | |
144 | query('searchVideo') | |
145 | .optional() | |
146 | .custom(exists).withMessage('Should have a valid video search'), | |
147 | query('searchVideoChannel') | |
148 | .optional() | |
149 | .custom(exists).withMessage('Should have a valid video channel search'), | |
150 | ||
151 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
152 | logger.debug('Checking abuseListForAdminsValidator parameters', { parameters: req.body }) | |
153 | ||
154 | if (areValidationErrors(req, res)) return | |
155 | ||
156 | return next() | |
157 | } | |
158 | ] | |
159 | ||
160 | const abuseListForUserValidator = [ | |
161 | query('id') | |
162 | .optional() | |
163 | .custom(isIdValid).withMessage('Should have a valid id'), | |
164 | ||
165 | query('search') | |
166 | .optional() | |
167 | .custom(exists).withMessage('Should have a valid search'), | |
168 | ||
169 | query('state') | |
170 | .optional() | |
171 | .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'), | |
172 | ||
173 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
174 | logger.debug('Checking abuseListForUserValidator parameters', { parameters: req.body }) | |
175 | ||
176 | if (areValidationErrors(req, res)) return | |
177 | ||
178 | return next() | |
179 | } | |
180 | ] | |
181 | ||
182 | const getAbuseValidator = [ | |
183 | param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'), | |
184 | ||
185 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
186 | logger.debug('Checking getAbuseValidator parameters', { parameters: req.body }) | |
187 | ||
188 | if (areValidationErrors(req, res)) return | |
189 | if (!await doesAbuseExist(req.params.id, res)) return | |
190 | ||
191 | const user = res.locals.oauth.token.user | |
192 | const abuse = res.locals.abuse | |
193 | ||
194 | if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuse.reporterAccountId !== user.Account.id) { | |
195 | const message = `User ${user.username} does not have right to get abuse ${abuse.id}` | |
196 | logger.warn(message) | |
197 | ||
198 | return res.status(HttpStatusCode.FORBIDDEN_403) | |
199 | .json({ error: message }) | |
200 | } | |
201 | ||
202 | return next() | |
203 | } | |
204 | ] | |
205 | ||
206 | const checkAbuseValidForMessagesValidator = [ | |
207 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
208 | logger.debug('Checking checkAbuseValidForMessagesValidator parameters', { parameters: req.body }) | |
209 | ||
210 | const abuse = res.locals.abuse | |
211 | if (abuse.ReporterAccount.isOwned() === false) { | |
212 | return res.status(HttpStatusCode.BAD_REQUEST_400) | |
213 | .json({ | |
214 | error: 'This abuse was created by a user of your instance.' | |
215 | }) | |
216 | } | |
217 | ||
218 | return next() | |
219 | } | |
220 | ] | |
221 | ||
222 | const addAbuseMessageValidator = [ | |
223 | body('message').custom(isAbuseMessageValid).not().isEmpty().withMessage('Should have a valid abuse message'), | |
224 | ||
225 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
226 | logger.debug('Checking addAbuseMessageValidator parameters', { parameters: req.body }) | |
227 | ||
228 | if (areValidationErrors(req, res)) return | |
229 | ||
230 | return next() | |
231 | } | |
232 | ] | |
233 | ||
234 | const deleteAbuseMessageValidator = [ | |
235 | param('messageId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid message id'), | |
236 | ||
237 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
238 | logger.debug('Checking deleteAbuseMessageValidator parameters', { parameters: req.body }) | |
239 | ||
240 | if (areValidationErrors(req, res)) return | |
241 | ||
242 | const user = res.locals.oauth.token.user | |
243 | const abuse = res.locals.abuse | |
244 | ||
245 | const messageId = parseInt(req.params.messageId + '', 10) | |
246 | const abuseMessage = await AbuseMessageModel.loadByIdAndAbuseId(messageId, abuse.id) | |
247 | ||
248 | if (!abuseMessage) { | |
249 | return res.status(HttpStatusCode.NOT_FOUND_404) | |
250 | .json({ error: 'Abuse message not found' }) | |
251 | } | |
252 | ||
253 | if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuseMessage.accountId !== user.Account.id) { | |
254 | return res.status(HttpStatusCode.FORBIDDEN_403) | |
255 | .json({ error: 'Cannot delete this abuse message' }) | |
256 | } | |
257 | ||
258 | res.locals.abuseMessage = abuseMessage | |
259 | ||
260 | return next() | |
261 | } | |
262 | ] | |
263 | ||
264 | // --------------------------------------------------------------------------- | |
265 | ||
266 | export { | |
267 | abuseListForAdminsValidator, | |
268 | abuseReportValidator, | |
269 | abuseGetValidator, | |
270 | addAbuseMessageValidator, | |
271 | checkAbuseValidForMessagesValidator, | |
272 | abuseUpdateValidator, | |
273 | deleteAbuseMessageValidator, | |
274 | abuseListForUserValidator, | |
275 | getAbuseValidator | |
276 | } |