aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/middlewares/validators/abuse.ts
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-07-31 14:34:36 +0200
committerChocobozzz <me@florianbigard.com>2023-08-11 15:02:33 +0200
commit3a4992633ee62d5edfbb484d9c6bcb3cf158489d (patch)
treee4510b39bdac9c318fdb4b47018d08f15368b8f0 /server/middlewares/validators/abuse.ts
parent04d1da5621d25d59bd5fa1543b725c497bf5d9a8 (diff)
downloadPeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.gz
PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.zst
PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.zip
Migrate server to ESM
Sorry for the very big commit that may lead to git log issues and merge conflicts, but it's a major step forward: * Server can be faster at startup because imports() are async and we can easily lazy import big modules * Angular doesn't seem to support ES import (with .js extension), so we had to correctly organize peertube into a monorepo: * Use yarn workspace feature * Use typescript reference projects for dependencies * Shared projects have been moved into "packages", each one is now a node module (with a dedicated package.json/tsconfig.json) * server/tools have been moved into apps/ and is now a dedicated app bundled and published on NPM so users don't have to build peertube cli tools manually * server/tests have been moved into packages/ so we don't compile them every time we want to run the server * Use isolatedModule option: * Had to move from const enum to const (https://www.typescriptlang.org/docs/handbook/enums.html#objects-vs-enums) * Had to explictely specify "type" imports when used in decorators * Prefer tsx (that uses esbuild under the hood) instead of ts-node to load typescript files (tests with mocha or scripts): * To reduce test complexity as esbuild doesn't support decorator metadata, we only test server files that do not import server models * We still build tests files into js files for a faster CI * Remove unmaintained peertube CLI import script * Removed some barrels to speed up execution (less imports)
Diffstat (limited to 'server/middlewares/validators/abuse.ts')
-rw-r--r--server/middlewares/validators/abuse.ts255
1 files changed, 0 insertions, 255 deletions
diff --git a/server/middlewares/validators/abuse.ts b/server/middlewares/validators/abuse.ts
deleted file mode 100644
index 70bae1775..000000000
--- a/server/middlewares/validators/abuse.ts
+++ /dev/null
@@ -1,255 +0,0 @@
1import express from 'express'
2import { body, param, query } from 'express-validator'
3import {
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'
15import { exists, isIdOrUUIDValid, isIdValid, toCompleteUUID, toIntOrNull } from '@server/helpers/custom-validators/misc'
16import { logger } from '@server/helpers/logger'
17import { AbuseMessageModel } from '@server/models/abuse/abuse-message'
18import { AbuseCreate, UserRight } from '@shared/models'
19import { HttpStatusCode } from '../../../shared/models/http/http-error-codes'
20import { areValidationErrors, doesAbuseExist, doesAccountIdExist, doesCommentIdExist, doesVideoExist } from './shared'
21import { forceNumber } from '@shared/core-utils'
22
23const abuseReportValidator = [
24 body('account.id')
25 .optional()
26 .custom(isIdValid),
27
28 body('video.id')
29 .optional()
30 .customSanitizer(toCompleteUUID)
31 .custom(isIdOrUUIDValid),
32 body('video.startAt')
33 .optional()
34 .customSanitizer(toIntOrNull)
35 .custom(isAbuseTimestampValid),
36 body('video.endAt')
37 .optional()
38 .customSanitizer(toIntOrNull)
39 .custom(isAbuseTimestampValid)
40 .bail()
41 .custom(isAbuseTimestampCoherent)
42 .withMessage('Should have a startAt timestamp beginning before endAt'),
43
44 body('comment.id')
45 .optional()
46 .custom(isIdValid),
47
48 body('reason')
49 .custom(isAbuseReasonValid),
50
51 body('predefinedReasons')
52 .optional()
53 .custom(areAbusePredefinedReasonsValid),
54
55 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
56 if (areValidationErrors(req, res)) return
57
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) {
65 res.fail({ message: 'video id or account id or comment id is required.' })
66 return
67 }
68
69 return next()
70 }
71]
72
73const abuseGetValidator = [
74 param('id')
75 .custom(isIdValid),
76
77 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
78 if (areValidationErrors(req, res)) return
79 if (!await doesAbuseExist(req.params.id, res)) return
80
81 return next()
82 }
83]
84
85const abuseUpdateValidator = [
86 param('id')
87 .custom(isIdValid),
88
89 body('state')
90 .optional()
91 .custom(isAbuseStateValid),
92 body('moderationComment')
93 .optional()
94 .custom(isAbuseModerationCommentValid),
95
96 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
97 if (areValidationErrors(req, res)) return
98 if (!await doesAbuseExist(req.params.id, res)) return
99
100 return next()
101 }
102]
103
104const abuseListForAdminsValidator = [
105 query('id')
106 .optional()
107 .custom(isIdValid),
108 query('filter')
109 .optional()
110 .custom(isAbuseFilterValid),
111 query('predefinedReason')
112 .optional()
113 .custom(isAbusePredefinedReasonValid),
114 query('search')
115 .optional()
116 .custom(exists),
117 query('state')
118 .optional()
119 .custom(isAbuseStateValid),
120 query('videoIs')
121 .optional()
122 .custom(isAbuseVideoIsValid),
123 query('searchReporter')
124 .optional()
125 .custom(exists),
126 query('searchReportee')
127 .optional()
128 .custom(exists),
129 query('searchVideo')
130 .optional()
131 .custom(exists),
132 query('searchVideoChannel')
133 .optional()
134 .custom(exists),
135
136 (req: express.Request, res: express.Response, next: express.NextFunction) => {
137 if (areValidationErrors(req, res)) return
138
139 return next()
140 }
141]
142
143const abuseListForUserValidator = [
144 query('id')
145 .optional()
146 .custom(isIdValid),
147
148 query('search')
149 .optional()
150 .custom(exists),
151
152 query('state')
153 .optional()
154 .custom(isAbuseStateValid),
155
156 (req: express.Request, res: express.Response, next: express.NextFunction) => {
157 if (areValidationErrors(req, res)) return
158
159 return next()
160 }
161]
162
163const getAbuseValidator = [
164 param('id')
165 .custom(isIdValid),
166
167 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
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
178 return res.fail({
179 status: HttpStatusCode.FORBIDDEN_403,
180 message
181 })
182 }
183
184 return next()
185 }
186]
187
188const checkAbuseValidForMessagesValidator = [
189 (req: express.Request, res: express.Response, next: express.NextFunction) => {
190 const abuse = res.locals.abuse
191 if (abuse.ReporterAccount.isOwned() === false) {
192 return res.fail({ message: 'This abuse was created by a user of your instance.' })
193 }
194
195 return next()
196 }
197]
198
199const addAbuseMessageValidator = [
200 body('message')
201 .custom(isAbuseMessageValid),
202
203 (req: express.Request, res: express.Response, next: express.NextFunction) => {
204 if (areValidationErrors(req, res)) return
205
206 return next()
207 }
208]
209
210const deleteAbuseMessageValidator = [
211 param('messageId')
212 .custom(isIdValid),
213
214 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
215 if (areValidationErrors(req, res)) return
216
217 const user = res.locals.oauth.token.user
218 const abuse = res.locals.abuse
219
220 const messageId = forceNumber(req.params.messageId)
221 const abuseMessage = await AbuseMessageModel.loadByIdAndAbuseId(messageId, abuse.id)
222
223 if (!abuseMessage) {
224 return res.fail({
225 status: HttpStatusCode.NOT_FOUND_404,
226 message: 'Abuse message not found'
227 })
228 }
229
230 if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuseMessage.accountId !== user.Account.id) {
231 return res.fail({
232 status: HttpStatusCode.FORBIDDEN_403,
233 message: 'Cannot delete this abuse message'
234 })
235 }
236
237 res.locals.abuseMessage = abuseMessage
238
239 return next()
240 }
241]
242
243// ---------------------------------------------------------------------------
244
245export {
246 abuseListForAdminsValidator,
247 abuseReportValidator,
248 abuseGetValidator,
249 addAbuseMessageValidator,
250 checkAbuseValidForMessagesValidator,
251 abuseUpdateValidator,
252 deleteAbuseMessageValidator,
253 abuseListForUserValidator,
254 getAbuseValidator
255}