diff options
Diffstat (limited to 'server/helpers/custom-validators')
-rw-r--r-- | server/helpers/custom-validators/index.ts | 2 | ||||
-rw-r--r-- | server/helpers/custom-validators/misc.ts | 24 | ||||
-rw-r--r-- | server/helpers/custom-validators/remote/videos.ts | 104 | ||||
-rw-r--r-- | server/helpers/custom-validators/video-authors.ts | 45 | ||||
-rw-r--r-- | server/helpers/custom-validators/video-channels.ts | 57 | ||||
-rw-r--r-- | server/helpers/custom-validators/videos.ts | 20 |
6 files changed, 193 insertions, 59 deletions
diff --git a/server/helpers/custom-validators/index.ts b/server/helpers/custom-validators/index.ts index 1dcab624a..c79982660 100644 --- a/server/helpers/custom-validators/index.ts +++ b/server/helpers/custom-validators/index.ts | |||
@@ -3,4 +3,6 @@ export * from './misc' | |||
3 | export * from './pods' | 3 | export * from './pods' |
4 | export * from './pods' | 4 | export * from './pods' |
5 | export * from './users' | 5 | export * from './users' |
6 | export * from './video-authors' | ||
7 | export * from './video-channels' | ||
6 | export * from './videos' | 8 | export * from './videos' |
diff --git a/server/helpers/custom-validators/misc.ts b/server/helpers/custom-validators/misc.ts index 60fcdd5bb..160ec91f3 100644 --- a/server/helpers/custom-validators/misc.ts +++ b/server/helpers/custom-validators/misc.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import 'express-validator' | 1 | import * as validator from 'validator' |
2 | 2 | ||
3 | function exists (value: any) { | 3 | function exists (value: any) { |
4 | return value !== undefined && value !== null | 4 | return value !== undefined && value !== null |
@@ -8,9 +8,29 @@ function isArray (value: any) { | |||
8 | return Array.isArray(value) | 8 | return Array.isArray(value) |
9 | } | 9 | } |
10 | 10 | ||
11 | function isDateValid (value: string) { | ||
12 | return exists(value) && validator.isISO8601(value) | ||
13 | } | ||
14 | |||
15 | function isIdValid (value: string) { | ||
16 | return exists(value) && validator.isInt('' + value) | ||
17 | } | ||
18 | |||
19 | function isUUIDValid (value: string) { | ||
20 | return exists(value) && validator.isUUID('' + value, 4) | ||
21 | } | ||
22 | |||
23 | function isIdOrUUIDValid (value: string) { | ||
24 | return isIdValid(value) || isUUIDValid(value) | ||
25 | } | ||
26 | |||
11 | // --------------------------------------------------------------------------- | 27 | // --------------------------------------------------------------------------- |
12 | 28 | ||
13 | export { | 29 | export { |
14 | exists, | 30 | exists, |
15 | isArray | 31 | isArray, |
32 | isIdValid, | ||
33 | isUUIDValid, | ||
34 | isIdOrUUIDValid, | ||
35 | isDateValid | ||
16 | } | 36 | } |
diff --git a/server/helpers/custom-validators/remote/videos.ts b/server/helpers/custom-validators/remote/videos.ts index e261e05a8..057996f1c 100644 --- a/server/helpers/custom-validators/remote/videos.ts +++ b/server/helpers/custom-validators/remote/videos.ts | |||
@@ -6,18 +6,15 @@ import { | |||
6 | REQUEST_ENDPOINT_ACTIONS, | 6 | REQUEST_ENDPOINT_ACTIONS, |
7 | REQUEST_VIDEO_EVENT_TYPES | 7 | REQUEST_VIDEO_EVENT_TYPES |
8 | } from '../../../initializers' | 8 | } from '../../../initializers' |
9 | import { isArray } from '../misc' | 9 | import { isArray, isDateValid, isUUIDValid } from '../misc' |
10 | import { | 10 | import { |
11 | isVideoAuthorValid, | ||
12 | isVideoThumbnailDataValid, | 11 | isVideoThumbnailDataValid, |
13 | isVideoUUIDValid, | ||
14 | isVideoAbuseReasonValid, | 12 | isVideoAbuseReasonValid, |
15 | isVideoAbuseReporterUsernameValid, | 13 | isVideoAbuseReporterUsernameValid, |
16 | isVideoViewsValid, | 14 | isVideoViewsValid, |
17 | isVideoLikesValid, | 15 | isVideoLikesValid, |
18 | isVideoDislikesValid, | 16 | isVideoDislikesValid, |
19 | isVideoEventCountValid, | 17 | isVideoEventCountValid, |
20 | isVideoDateValid, | ||
21 | isVideoCategoryValid, | 18 | isVideoCategoryValid, |
22 | isVideoLicenceValid, | 19 | isVideoLicenceValid, |
23 | isVideoLanguageValid, | 20 | isVideoLanguageValid, |
@@ -30,9 +27,22 @@ import { | |||
30 | isVideoFileExtnameValid, | 27 | isVideoFileExtnameValid, |
31 | isVideoFileResolutionValid | 28 | isVideoFileResolutionValid |
32 | } from '../videos' | 29 | } from '../videos' |
30 | import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../video-channels' | ||
31 | import { isVideoAuthorNameValid } from '../video-authors' | ||
33 | 32 | ||
34 | const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS] | 33 | const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS] |
35 | 34 | ||
35 | const checkers: { [ id: string ]: (obj: any) => boolean } = {} | ||
36 | checkers[ENDPOINT_ACTIONS.ADD_VIDEO] = checkAddVideo | ||
37 | checkers[ENDPOINT_ACTIONS.UPDATE_VIDEO] = checkUpdateVideo | ||
38 | checkers[ENDPOINT_ACTIONS.REMOVE_VIDEO] = checkRemoveVideo | ||
39 | checkers[ENDPOINT_ACTIONS.REPORT_ABUSE] = checkReportVideo | ||
40 | checkers[ENDPOINT_ACTIONS.ADD_CHANNEL] = checkAddVideoChannel | ||
41 | checkers[ENDPOINT_ACTIONS.UPDATE_CHANNEL] = checkUpdateVideoChannel | ||
42 | checkers[ENDPOINT_ACTIONS.REMOVE_CHANNEL] = checkRemoveVideoChannel | ||
43 | checkers[ENDPOINT_ACTIONS.ADD_AUTHOR] = checkAddAuthor | ||
44 | checkers[ENDPOINT_ACTIONS.REMOVE_AUTHOR] = checkRemoveAuthor | ||
45 | |||
36 | function isEachRemoteRequestVideosValid (requests: any[]) { | 46 | function isEachRemoteRequestVideosValid (requests: any[]) { |
37 | return isArray(requests) && | 47 | return isArray(requests) && |
38 | requests.every(request => { | 48 | requests.every(request => { |
@@ -40,26 +50,11 @@ function isEachRemoteRequestVideosValid (requests: any[]) { | |||
40 | 50 | ||
41 | if (!video) return false | 51 | if (!video) return false |
42 | 52 | ||
43 | return ( | 53 | const checker = checkers[request.type] |
44 | isRequestTypeAddValid(request.type) && | 54 | // We don't know the request type |
45 | isCommonVideoAttributesValid(video) && | 55 | if (checker === undefined) return false |
46 | isVideoAuthorValid(video.author) && | 56 | |
47 | isVideoThumbnailDataValid(video.thumbnailData) | 57 | return checker(video) |
48 | ) || | ||
49 | ( | ||
50 | isRequestTypeUpdateValid(request.type) && | ||
51 | isCommonVideoAttributesValid(video) | ||
52 | ) || | ||
53 | ( | ||
54 | isRequestTypeRemoveValid(request.type) && | ||
55 | isVideoUUIDValid(video.uuid) | ||
56 | ) || | ||
57 | ( | ||
58 | isRequestTypeReportAbuseValid(request.type) && | ||
59 | isVideoUUIDValid(request.data.videoUUID) && | ||
60 | isVideoAbuseReasonValid(request.data.reportReason) && | ||
61 | isVideoAbuseReporterUsernameValid(request.data.reporterUsername) | ||
62 | ) | ||
63 | }) | 58 | }) |
64 | } | 59 | } |
65 | 60 | ||
@@ -71,7 +66,7 @@ function isEachRemoteRequestVideosQaduValid (requests: any[]) { | |||
71 | if (!video) return false | 66 | if (!video) return false |
72 | 67 | ||
73 | return ( | 68 | return ( |
74 | isVideoUUIDValid(video.uuid) && | 69 | isUUIDValid(video.uuid) && |
75 | (has(video, 'views') === false || isVideoViewsValid(video.views)) && | 70 | (has(video, 'views') === false || isVideoViewsValid(video.views)) && |
76 | (has(video, 'likes') === false || isVideoLikesValid(video.likes)) && | 71 | (has(video, 'likes') === false || isVideoLikesValid(video.likes)) && |
77 | (has(video, 'dislikes') === false || isVideoDislikesValid(video.dislikes)) | 72 | (has(video, 'dislikes') === false || isVideoDislikesValid(video.dislikes)) |
@@ -87,7 +82,7 @@ function isEachRemoteRequestVideosEventsValid (requests: any[]) { | |||
87 | if (!eventData) return false | 82 | if (!eventData) return false |
88 | 83 | ||
89 | return ( | 84 | return ( |
90 | isVideoUUIDValid(eventData.uuid) && | 85 | isUUIDValid(eventData.uuid) && |
91 | values(REQUEST_VIDEO_EVENT_TYPES).indexOf(eventData.eventType) !== -1 && | 86 | values(REQUEST_VIDEO_EVENT_TYPES).indexOf(eventData.eventType) !== -1 && |
92 | isVideoEventCountValid(eventData.count) | 87 | isVideoEventCountValid(eventData.count) |
93 | ) | 88 | ) |
@@ -105,8 +100,8 @@ export { | |||
105 | // --------------------------------------------------------------------------- | 100 | // --------------------------------------------------------------------------- |
106 | 101 | ||
107 | function isCommonVideoAttributesValid (video: any) { | 102 | function isCommonVideoAttributesValid (video: any) { |
108 | return isVideoDateValid(video.createdAt) && | 103 | return isDateValid(video.createdAt) && |
109 | isVideoDateValid(video.updatedAt) && | 104 | isDateValid(video.updatedAt) && |
110 | isVideoCategoryValid(video.category) && | 105 | isVideoCategoryValid(video.category) && |
111 | isVideoLicenceValid(video.licence) && | 106 | isVideoLicenceValid(video.licence) && |
112 | isVideoLanguageValid(video.language) && | 107 | isVideoLanguageValid(video.language) && |
@@ -115,7 +110,7 @@ function isCommonVideoAttributesValid (video: any) { | |||
115 | isVideoDurationValid(video.duration) && | 110 | isVideoDurationValid(video.duration) && |
116 | isVideoNameValid(video.name) && | 111 | isVideoNameValid(video.name) && |
117 | isVideoTagsValid(video.tags) && | 112 | isVideoTagsValid(video.tags) && |
118 | isVideoUUIDValid(video.uuid) && | 113 | isUUIDValid(video.uuid) && |
119 | isVideoViewsValid(video.views) && | 114 | isVideoViewsValid(video.views) && |
120 | isVideoLikesValid(video.likes) && | 115 | isVideoLikesValid(video.likes) && |
121 | isVideoDislikesValid(video.dislikes) && | 116 | isVideoDislikesValid(video.dislikes) && |
@@ -131,18 +126,53 @@ function isCommonVideoAttributesValid (video: any) { | |||
131 | }) | 126 | }) |
132 | } | 127 | } |
133 | 128 | ||
134 | function isRequestTypeAddValid (value: string) { | 129 | function checkAddVideo (video: any) { |
135 | return value === ENDPOINT_ACTIONS.ADD | 130 | return isCommonVideoAttributesValid(video) && |
131 | isUUIDValid(video.channelUUID) && | ||
132 | isVideoThumbnailDataValid(video.thumbnailData) | ||
133 | } | ||
134 | |||
135 | function checkUpdateVideo (video: any) { | ||
136 | return isCommonVideoAttributesValid(video) | ||
137 | } | ||
138 | |||
139 | function checkRemoveVideo (video: any) { | ||
140 | return isUUIDValid(video.uuid) | ||
141 | } | ||
142 | |||
143 | function checkReportVideo (abuse: any) { | ||
144 | return isUUIDValid(abuse.videoUUID) && | ||
145 | isVideoAbuseReasonValid(abuse.reportReason) && | ||
146 | isVideoAbuseReporterUsernameValid(abuse.reporterUsername) | ||
147 | } | ||
148 | |||
149 | function checkAddVideoChannel (videoChannel: any) { | ||
150 | return isUUIDValid(videoChannel.uuid) && | ||
151 | isVideoChannelNameValid(videoChannel.name) && | ||
152 | isVideoChannelDescriptionValid(videoChannel.description) && | ||
153 | isDateValid(videoChannel.createdAt) && | ||
154 | isDateValid(videoChannel.updatedAt) && | ||
155 | isUUIDValid(videoChannel.ownerUUID) | ||
156 | } | ||
157 | |||
158 | function checkUpdateVideoChannel (videoChannel: any) { | ||
159 | return isUUIDValid(videoChannel.uuid) && | ||
160 | isVideoChannelNameValid(videoChannel.name) && | ||
161 | isVideoChannelDescriptionValid(videoChannel.description) && | ||
162 | isDateValid(videoChannel.createdAt) && | ||
163 | isDateValid(videoChannel.updatedAt) && | ||
164 | isUUIDValid(videoChannel.ownerUUID) | ||
136 | } | 165 | } |
137 | 166 | ||
138 | function isRequestTypeUpdateValid (value: string) { | 167 | function checkRemoveVideoChannel (videoChannel: any) { |
139 | return value === ENDPOINT_ACTIONS.UPDATE | 168 | return isUUIDValid(videoChannel.uuid) |
140 | } | 169 | } |
141 | 170 | ||
142 | function isRequestTypeRemoveValid (value: string) { | 171 | function checkAddAuthor (author: any) { |
143 | return value === ENDPOINT_ACTIONS.REMOVE | 172 | return isUUIDValid(author.uuid) && |
173 | isVideoAuthorNameValid(author.name) | ||
144 | } | 174 | } |
145 | 175 | ||
146 | function isRequestTypeReportAbuseValid (value: string) { | 176 | function checkRemoveAuthor (author: any) { |
147 | return value === ENDPOINT_ACTIONS.REPORT_ABUSE | 177 | return isUUIDValid(author.uuid) |
148 | } | 178 | } |
diff --git a/server/helpers/custom-validators/video-authors.ts b/server/helpers/custom-validators/video-authors.ts new file mode 100644 index 000000000..48ca9b200 --- /dev/null +++ b/server/helpers/custom-validators/video-authors.ts | |||
@@ -0,0 +1,45 @@ | |||
1 | import * as Promise from 'bluebird' | ||
2 | import * as validator from 'validator' | ||
3 | import * as express from 'express' | ||
4 | import 'express-validator' | ||
5 | |||
6 | import { database as db } from '../../initializers' | ||
7 | import { AuthorInstance } from '../../models' | ||
8 | import { logger } from '../logger' | ||
9 | |||
10 | import { isUserUsernameValid } from './users' | ||
11 | |||
12 | function isVideoAuthorNameValid (value: string) { | ||
13 | return isUserUsernameValid(value) | ||
14 | } | ||
15 | |||
16 | function checkVideoAuthorExists (id: string, res: express.Response, callback: () => void) { | ||
17 | let promise: Promise<AuthorInstance> | ||
18 | if (validator.isInt(id)) { | ||
19 | promise = db.Author.load(+id) | ||
20 | } else { // UUID | ||
21 | promise = db.Author.loadByUUID(id) | ||
22 | } | ||
23 | |||
24 | promise.then(author => { | ||
25 | if (!author) { | ||
26 | return res.status(404) | ||
27 | .json({ error: 'Video author not found' }) | ||
28 | .end() | ||
29 | } | ||
30 | |||
31 | res.locals.author = author | ||
32 | callback() | ||
33 | }) | ||
34 | .catch(err => { | ||
35 | logger.error('Error in video author request validator.', err) | ||
36 | return res.sendStatus(500) | ||
37 | }) | ||
38 | } | ||
39 | |||
40 | // --------------------------------------------------------------------------- | ||
41 | |||
42 | export { | ||
43 | checkVideoAuthorExists, | ||
44 | isVideoAuthorNameValid | ||
45 | } | ||
diff --git a/server/helpers/custom-validators/video-channels.ts b/server/helpers/custom-validators/video-channels.ts new file mode 100644 index 000000000..b6be557e6 --- /dev/null +++ b/server/helpers/custom-validators/video-channels.ts | |||
@@ -0,0 +1,57 @@ | |||
1 | import * as Promise from 'bluebird' | ||
2 | import * as validator from 'validator' | ||
3 | import * as express from 'express' | ||
4 | import 'express-validator' | ||
5 | import 'multer' | ||
6 | |||
7 | import { database as db, CONSTRAINTS_FIELDS } from '../../initializers' | ||
8 | import { VideoChannelInstance } from '../../models' | ||
9 | import { logger } from '../logger' | ||
10 | import { exists } from './misc' | ||
11 | |||
12 | const VIDEO_CHANNELS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_CHANNELS | ||
13 | |||
14 | function isVideoChannelDescriptionValid (value: string) { | ||
15 | return value === null || validator.isLength(value, VIDEO_CHANNELS_CONSTRAINTS_FIELDS.DESCRIPTION) | ||
16 | } | ||
17 | |||
18 | function isVideoChannelNameValid (value: string) { | ||
19 | return exists(value) && validator.isLength(value, VIDEO_CHANNELS_CONSTRAINTS_FIELDS.NAME) | ||
20 | } | ||
21 | |||
22 | function isVideoChannelUUIDValid (value: string) { | ||
23 | return exists(value) && validator.isUUID('' + value, 4) | ||
24 | } | ||
25 | |||
26 | function checkVideoChannelExists (id: string, res: express.Response, callback: () => void) { | ||
27 | let promise: Promise<VideoChannelInstance> | ||
28 | if (validator.isInt(id)) { | ||
29 | promise = db.VideoChannel.loadAndPopulateAuthor(+id) | ||
30 | } else { // UUID | ||
31 | promise = db.VideoChannel.loadByUUIDAndPopulateAuthor(id) | ||
32 | } | ||
33 | |||
34 | promise.then(videoChannel => { | ||
35 | if (!videoChannel) { | ||
36 | return res.status(404) | ||
37 | .json({ error: 'Video channel not found' }) | ||
38 | .end() | ||
39 | } | ||
40 | |||
41 | res.locals.videoChannel = videoChannel | ||
42 | callback() | ||
43 | }) | ||
44 | .catch(err => { | ||
45 | logger.error('Error in video channel request validator.', err) | ||
46 | return res.sendStatus(500) | ||
47 | }) | ||
48 | } | ||
49 | |||
50 | // --------------------------------------------------------------------------- | ||
51 | |||
52 | export { | ||
53 | isVideoChannelDescriptionValid, | ||
54 | isVideoChannelNameValid, | ||
55 | isVideoChannelUUIDValid, | ||
56 | checkVideoChannelExists | ||
57 | } | ||
diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts index 05d1dc607..4e441fe5f 100644 --- a/server/helpers/custom-validators/videos.ts +++ b/server/helpers/custom-validators/videos.ts | |||
@@ -23,18 +23,6 @@ const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS | |||
23 | const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES | 23 | const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES |
24 | const VIDEO_EVENTS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_EVENTS | 24 | const VIDEO_EVENTS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_EVENTS |
25 | 25 | ||
26 | function isVideoIdOrUUIDValid (value: string) { | ||
27 | return validator.isInt(value) || isVideoUUIDValid(value) | ||
28 | } | ||
29 | |||
30 | function isVideoAuthorValid (value: string) { | ||
31 | return isUserUsernameValid(value) | ||
32 | } | ||
33 | |||
34 | function isVideoDateValid (value: string) { | ||
35 | return exists(value) && validator.isISO8601(value) | ||
36 | } | ||
37 | |||
38 | function isVideoCategoryValid (value: number) { | 26 | function isVideoCategoryValid (value: number) { |
39 | return VIDEO_CATEGORIES[value] !== undefined | 27 | return VIDEO_CATEGORIES[value] !== undefined |
40 | } | 28 | } |
@@ -79,10 +67,6 @@ function isVideoThumbnailDataValid (value: string) { | |||
79 | return exists(value) && validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL_DATA) | 67 | return exists(value) && validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL_DATA) |
80 | } | 68 | } |
81 | 69 | ||
82 | function isVideoUUIDValid (value: string) { | ||
83 | return exists(value) && validator.isUUID('' + value, 4) | ||
84 | } | ||
85 | |||
86 | function isVideoAbuseReasonValid (value: string) { | 70 | function isVideoAbuseReasonValid (value: string) { |
87 | return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON) | 71 | return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON) |
88 | } | 72 | } |
@@ -170,9 +154,6 @@ function checkVideoExists (id: string, res: express.Response, callback: () => vo | |||
170 | // --------------------------------------------------------------------------- | 154 | // --------------------------------------------------------------------------- |
171 | 155 | ||
172 | export { | 156 | export { |
173 | isVideoIdOrUUIDValid, | ||
174 | isVideoAuthorValid, | ||
175 | isVideoDateValid, | ||
176 | isVideoCategoryValid, | 157 | isVideoCategoryValid, |
177 | isVideoLicenceValid, | 158 | isVideoLicenceValid, |
178 | isVideoLanguageValid, | 159 | isVideoLanguageValid, |
@@ -185,7 +166,6 @@ export { | |||
185 | isVideoThumbnailValid, | 166 | isVideoThumbnailValid, |
186 | isVideoThumbnailDataValid, | 167 | isVideoThumbnailDataValid, |
187 | isVideoFileExtnameValid, | 168 | isVideoFileExtnameValid, |
188 | isVideoUUIDValid, | ||
189 | isVideoAbuseReasonValid, | 169 | isVideoAbuseReasonValid, |
190 | isVideoAbuseReporterUsernameValid, | 170 | isVideoAbuseReporterUsernameValid, |
191 | isVideoFile, | 171 | isVideoFile, |