diff options
Diffstat (limited to 'server/helpers/custom-validators')
-rw-r--r-- | server/helpers/custom-validators/activitypub/playlist.ts | 7 | ||||
-rw-r--r-- | server/helpers/custom-validators/misc.ts | 86 | ||||
-rw-r--r-- | server/helpers/custom-validators/video-comments.ts | 81 | ||||
-rw-r--r-- | server/helpers/custom-validators/video-imports.ts | 19 | ||||
-rw-r--r-- | server/helpers/custom-validators/video-ownership.ts | 32 |
5 files changed, 65 insertions, 160 deletions
diff --git a/server/helpers/custom-validators/activitypub/playlist.ts b/server/helpers/custom-validators/activitypub/playlist.ts index bd0d16a4a..72c5b80e9 100644 --- a/server/helpers/custom-validators/activitypub/playlist.ts +++ b/server/helpers/custom-validators/activitypub/playlist.ts | |||
@@ -1,13 +1,16 @@ | |||
1 | import { exists, isDateValid } from '../misc' | ||
2 | import { PlaylistObject } from '../../../../shared/models/activitypub/objects/playlist-object' | ||
3 | import validator from 'validator' | 1 | import validator from 'validator' |
4 | import { PlaylistElementObject } from '../../../../shared/models/activitypub/objects/playlist-element-object' | 2 | import { PlaylistElementObject } from '../../../../shared/models/activitypub/objects/playlist-element-object' |
3 | import { PlaylistObject } from '../../../../shared/models/activitypub/objects/playlist-object' | ||
4 | import { exists, isDateValid, isUUIDValid } from '../misc' | ||
5 | import { isVideoPlaylistNameValid } from '../video-playlists' | ||
5 | import { isActivityPubUrlValid } from './misc' | 6 | import { isActivityPubUrlValid } from './misc' |
6 | 7 | ||
7 | function isPlaylistObjectValid (object: PlaylistObject) { | 8 | function isPlaylistObjectValid (object: PlaylistObject) { |
8 | return exists(object) && | 9 | return exists(object) && |
9 | object.type === 'Playlist' && | 10 | object.type === 'Playlist' && |
10 | validator.isInt(object.totalItems + '') && | 11 | validator.isInt(object.totalItems + '') && |
12 | isVideoPlaylistNameValid(object.name) && | ||
13 | isUUIDValid(object.uuid) && | ||
11 | isDateValid(object.published) && | 14 | isDateValid(object.published) && |
12 | isDateValid(object.updated) | 15 | isDateValid(object.updated) |
13 | } | 16 | } |
diff --git a/server/helpers/custom-validators/misc.ts b/server/helpers/custom-validators/misc.ts index fd3b45804..528bfcfb8 100644 --- a/server/helpers/custom-validators/misc.ts +++ b/server/helpers/custom-validators/misc.ts | |||
@@ -2,6 +2,7 @@ import 'multer' | |||
2 | import { UploadFilesForCheck } from 'express' | 2 | import { UploadFilesForCheck } from 'express' |
3 | import { sep } from 'path' | 3 | import { sep } from 'path' |
4 | import validator from 'validator' | 4 | import validator from 'validator' |
5 | import { isShortUUID, shortToUUID } from '../uuid' | ||
5 | 6 | ||
6 | function exists (value: any) { | 7 | function exists (value: any) { |
7 | return value !== undefined && value !== null | 8 | return value !== undefined && value !== null |
@@ -14,7 +15,7 @@ function isSafePath (p: string) { | |||
14 | }) | 15 | }) |
15 | } | 16 | } |
16 | 17 | ||
17 | function isArray (value: any) { | 18 | function isArray (value: any): value is any[] { |
18 | return Array.isArray(value) | 19 | return Array.isArray(value) |
19 | } | 20 | } |
20 | 21 | ||
@@ -50,42 +51,7 @@ function isIntOrNull (value: any) { | |||
50 | return value === null || validator.isInt('' + value) | 51 | return value === null || validator.isInt('' + value) |
51 | } | 52 | } |
52 | 53 | ||
53 | function toIntOrNull (value: string) { | 54 | // --------------------------------------------------------------------------- |
54 | const v = toValueOrNull(value) | ||
55 | |||
56 | if (v === null || v === undefined) return v | ||
57 | if (typeof v === 'number') return v | ||
58 | |||
59 | return validator.toInt('' + v) | ||
60 | } | ||
61 | |||
62 | function toBooleanOrNull (value: any) { | ||
63 | const v = toValueOrNull(value) | ||
64 | |||
65 | if (v === null || v === undefined) return v | ||
66 | if (typeof v === 'boolean') return v | ||
67 | |||
68 | return validator.toBoolean('' + v) | ||
69 | } | ||
70 | |||
71 | function toValueOrNull (value: string) { | ||
72 | if (value === 'null') return null | ||
73 | |||
74 | return value | ||
75 | } | ||
76 | |||
77 | function toArray (value: any) { | ||
78 | if (value && isArray(value) === false) return [ value ] | ||
79 | |||
80 | return value | ||
81 | } | ||
82 | |||
83 | function toIntArray (value: any) { | ||
84 | if (!value) return [] | ||
85 | if (isArray(value) === false) return [ validator.toInt(value) ] | ||
86 | |||
87 | return value.map(v => validator.toInt(v)) | ||
88 | } | ||
89 | 55 | ||
90 | function isFileFieldValid ( | 56 | function isFileFieldValid ( |
91 | files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], | 57 | files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], |
@@ -160,6 +126,51 @@ function isFileValid ( | |||
160 | 126 | ||
161 | // --------------------------------------------------------------------------- | 127 | // --------------------------------------------------------------------------- |
162 | 128 | ||
129 | function toCompleteUUID (value: string) { | ||
130 | if (isShortUUID(value)) return shortToUUID(value) | ||
131 | |||
132 | return value | ||
133 | } | ||
134 | |||
135 | function toIntOrNull (value: string) { | ||
136 | const v = toValueOrNull(value) | ||
137 | |||
138 | if (v === null || v === undefined) return v | ||
139 | if (typeof v === 'number') return v | ||
140 | |||
141 | return validator.toInt('' + v) | ||
142 | } | ||
143 | |||
144 | function toBooleanOrNull (value: any) { | ||
145 | const v = toValueOrNull(value) | ||
146 | |||
147 | if (v === null || v === undefined) return v | ||
148 | if (typeof v === 'boolean') return v | ||
149 | |||
150 | return validator.toBoolean('' + v) | ||
151 | } | ||
152 | |||
153 | function toValueOrNull (value: string) { | ||
154 | if (value === 'null') return null | ||
155 | |||
156 | return value | ||
157 | } | ||
158 | |||
159 | function toArray (value: any) { | ||
160 | if (value && isArray(value) === false) return [ value ] | ||
161 | |||
162 | return value | ||
163 | } | ||
164 | |||
165 | function toIntArray (value: any) { | ||
166 | if (!value) return [] | ||
167 | if (isArray(value) === false) return [ validator.toInt(value) ] | ||
168 | |||
169 | return value.map(v => validator.toInt(v)) | ||
170 | } | ||
171 | |||
172 | // --------------------------------------------------------------------------- | ||
173 | |||
163 | export { | 174 | export { |
164 | exists, | 175 | exists, |
165 | isArrayOf, | 176 | isArrayOf, |
@@ -169,6 +180,7 @@ export { | |||
169 | isIdValid, | 180 | isIdValid, |
170 | isSafePath, | 181 | isSafePath, |
171 | isUUIDValid, | 182 | isUUIDValid, |
183 | toCompleteUUID, | ||
172 | isIdOrUUIDValid, | 184 | isIdOrUUIDValid, |
173 | isDateValid, | 185 | isDateValid, |
174 | toValueOrNull, | 186 | toValueOrNull, |
diff --git a/server/helpers/custom-validators/video-comments.ts b/server/helpers/custom-validators/video-comments.ts index 8d3ce580e..94bdf237a 100644 --- a/server/helpers/custom-validators/video-comments.ts +++ b/server/helpers/custom-validators/video-comments.ts | |||
@@ -1,9 +1,5 @@ | |||
1 | import * as express from 'express' | ||
2 | import validator from 'validator' | 1 | import validator from 'validator' |
3 | import { VideoCommentModel } from '@server/models/video/video-comment' | ||
4 | import { CONSTRAINTS_FIELDS } from '../../initializers/constants' | 2 | import { CONSTRAINTS_FIELDS } from '../../initializers/constants' |
5 | import { MVideoId } from '@server/types/models' | ||
6 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
7 | 3 | ||
8 | const VIDEO_COMMENTS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_COMMENTS | 4 | const VIDEO_COMMENTS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_COMMENTS |
9 | 5 | ||
@@ -11,83 +7,8 @@ function isValidVideoCommentText (value: string) { | |||
11 | return value === null || validator.isLength(value, VIDEO_COMMENTS_CONSTRAINTS_FIELDS.TEXT) | 7 | return value === null || validator.isLength(value, VIDEO_COMMENTS_CONSTRAINTS_FIELDS.TEXT) |
12 | } | 8 | } |
13 | 9 | ||
14 | async function doesVideoCommentThreadExist (idArg: number | string, video: MVideoId, res: express.Response) { | ||
15 | const id = parseInt(idArg + '', 10) | ||
16 | const videoComment = await VideoCommentModel.loadById(id) | ||
17 | |||
18 | if (!videoComment) { | ||
19 | res.status(HttpStatusCode.NOT_FOUND_404) | ||
20 | .json({ error: 'Video comment thread not found' }) | ||
21 | .end() | ||
22 | |||
23 | return false | ||
24 | } | ||
25 | |||
26 | if (videoComment.videoId !== video.id) { | ||
27 | res.status(HttpStatusCode.BAD_REQUEST_400) | ||
28 | .json({ error: 'Video comment is not associated to this video.' }) | ||
29 | .end() | ||
30 | |||
31 | return false | ||
32 | } | ||
33 | |||
34 | if (videoComment.inReplyToCommentId !== null) { | ||
35 | res.status(HttpStatusCode.BAD_REQUEST_400) | ||
36 | .json({ error: 'Video comment is not a thread.' }) | ||
37 | .end() | ||
38 | |||
39 | return false | ||
40 | } | ||
41 | |||
42 | res.locals.videoCommentThread = videoComment | ||
43 | return true | ||
44 | } | ||
45 | |||
46 | async function doesVideoCommentExist (idArg: number | string, video: MVideoId, res: express.Response) { | ||
47 | const id = parseInt(idArg + '', 10) | ||
48 | const videoComment = await VideoCommentModel.loadByIdAndPopulateVideoAndAccountAndReply(id) | ||
49 | |||
50 | if (!videoComment) { | ||
51 | res.status(HttpStatusCode.NOT_FOUND_404) | ||
52 | .json({ error: 'Video comment thread not found' }) | ||
53 | .end() | ||
54 | |||
55 | return false | ||
56 | } | ||
57 | |||
58 | if (videoComment.videoId !== video.id) { | ||
59 | res.status(HttpStatusCode.BAD_REQUEST_400) | ||
60 | .json({ error: 'Video comment is not associated to this video.' }) | ||
61 | .end() | ||
62 | |||
63 | return false | ||
64 | } | ||
65 | |||
66 | res.locals.videoCommentFull = videoComment | ||
67 | return true | ||
68 | } | ||
69 | |||
70 | async function doesCommentIdExist (idArg: number | string, res: express.Response) { | ||
71 | const id = parseInt(idArg + '', 10) | ||
72 | const videoComment = await VideoCommentModel.loadByIdAndPopulateVideoAndAccountAndReply(id) | ||
73 | |||
74 | if (!videoComment) { | ||
75 | res.status(HttpStatusCode.NOT_FOUND_404) | ||
76 | .json({ error: 'Video comment thread not found' }) | ||
77 | |||
78 | return false | ||
79 | } | ||
80 | |||
81 | res.locals.videoCommentFull = videoComment | ||
82 | |||
83 | return true | ||
84 | } | ||
85 | |||
86 | // --------------------------------------------------------------------------- | 10 | // --------------------------------------------------------------------------- |
87 | 11 | ||
88 | export { | 12 | export { |
89 | isValidVideoCommentText, | 13 | isValidVideoCommentText |
90 | doesVideoCommentThreadExist, | ||
91 | doesVideoCommentExist, | ||
92 | doesCommentIdExist | ||
93 | } | 14 | } |
diff --git a/server/helpers/custom-validators/video-imports.ts b/server/helpers/custom-validators/video-imports.ts index 0063d3337..dbf6a3504 100644 --- a/server/helpers/custom-validators/video-imports.ts +++ b/server/helpers/custom-validators/video-imports.ts | |||
@@ -2,9 +2,6 @@ import 'multer' | |||
2 | import validator from 'validator' | 2 | import validator from 'validator' |
3 | import { CONSTRAINTS_FIELDS, MIMETYPES, VIDEO_IMPORT_STATES } from '../../initializers/constants' | 3 | import { CONSTRAINTS_FIELDS, MIMETYPES, VIDEO_IMPORT_STATES } from '../../initializers/constants' |
4 | import { exists, isFileValid } from './misc' | 4 | import { exists, isFileValid } from './misc' |
5 | import * as express from 'express' | ||
6 | import { VideoImportModel } from '../../models/video/video-import' | ||
7 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
8 | 5 | ||
9 | function isVideoImportTargetUrlValid (url: string) { | 6 | function isVideoImportTargetUrlValid (url: string) { |
10 | const isURLOptions = { | 7 | const isURLOptions = { |
@@ -32,26 +29,10 @@ function isVideoImportTorrentFile (files: { [ fieldname: string ]: Express.Multe | |||
32 | return isFileValid(files, videoTorrentImportRegex, 'torrentfile', CONSTRAINTS_FIELDS.VIDEO_IMPORTS.TORRENT_FILE.FILE_SIZE.max, true) | 29 | return isFileValid(files, videoTorrentImportRegex, 'torrentfile', CONSTRAINTS_FIELDS.VIDEO_IMPORTS.TORRENT_FILE.FILE_SIZE.max, true) |
33 | } | 30 | } |
34 | 31 | ||
35 | async function doesVideoImportExist (id: number, res: express.Response) { | ||
36 | const videoImport = await VideoImportModel.loadAndPopulateVideo(id) | ||
37 | |||
38 | if (!videoImport) { | ||
39 | res.status(HttpStatusCode.NOT_FOUND_404) | ||
40 | .json({ error: 'Video import not found' }) | ||
41 | .end() | ||
42 | |||
43 | return false | ||
44 | } | ||
45 | |||
46 | res.locals.videoImport = videoImport | ||
47 | return true | ||
48 | } | ||
49 | |||
50 | // --------------------------------------------------------------------------- | 32 | // --------------------------------------------------------------------------- |
51 | 33 | ||
52 | export { | 34 | export { |
53 | isVideoImportStateValid, | 35 | isVideoImportStateValid, |
54 | isVideoImportTargetUrlValid, | 36 | isVideoImportTargetUrlValid, |
55 | doesVideoImportExist, | ||
56 | isVideoImportTorrentFile | 37 | isVideoImportTorrentFile |
57 | } | 38 | } |
diff --git a/server/helpers/custom-validators/video-ownership.ts b/server/helpers/custom-validators/video-ownership.ts index ee3cebe10..0e1c63bad 100644 --- a/server/helpers/custom-validators/video-ownership.ts +++ b/server/helpers/custom-validators/video-ownership.ts | |||
@@ -1,32 +1,20 @@ | |||
1 | import { Response } from 'express' | 1 | import { Response } from 'express' |
2 | import { VideoChangeOwnershipModel } from '../../models/video/video-change-ownership' | ||
3 | import { MVideoChangeOwnershipFull } from '@server/types/models/video/video-change-ownership' | ||
4 | import { MUserId } from '@server/types/models' | 2 | import { MUserId } from '@server/types/models' |
3 | import { MVideoChangeOwnershipFull } from '@server/types/models/video/video-change-ownership' | ||
5 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | 4 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' |
6 | 5 | ||
7 | export async function doesChangeVideoOwnershipExist (idArg: number | string, res: Response) { | 6 | function checkUserCanTerminateOwnershipChange (user: MUserId, videoChangeOwnership: MVideoChangeOwnershipFull, res: Response) { |
8 | const id = parseInt(idArg + '', 10) | ||
9 | const videoChangeOwnership = await VideoChangeOwnershipModel.load(id) | ||
10 | |||
11 | if (!videoChangeOwnership) { | ||
12 | res.status(HttpStatusCode.NOT_FOUND_404) | ||
13 | .json({ error: 'Video change ownership not found' }) | ||
14 | .end() | ||
15 | |||
16 | return false | ||
17 | } | ||
18 | |||
19 | res.locals.videoChangeOwnership = videoChangeOwnership | ||
20 | return true | ||
21 | } | ||
22 | |||
23 | export function checkUserCanTerminateOwnershipChange (user: MUserId, videoChangeOwnership: MVideoChangeOwnershipFull, res: Response) { | ||
24 | if (videoChangeOwnership.NextOwner.userId === user.id) { | 7 | if (videoChangeOwnership.NextOwner.userId === user.id) { |
25 | return true | 8 | return true |
26 | } | 9 | } |
27 | 10 | ||
28 | res.status(HttpStatusCode.FORBIDDEN_403) | 11 | res.fail({ |
29 | .json({ error: 'Cannot terminate an ownership change of another user' }) | 12 | status: HttpStatusCode.FORBIDDEN_403, |
30 | .end() | 13 | message: 'Cannot terminate an ownership change of another user' |
14 | }) | ||
31 | return false | 15 | return false |
32 | } | 16 | } |
17 | |||
18 | export { | ||
19 | checkUserCanTerminateOwnershipChange | ||
20 | } | ||