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