aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts2
-rw-r--r--client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts4
-rw-r--r--client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts4
-rw-r--r--client/src/app/shared/forms/form-validators/user.ts2
-rw-r--r--client/src/app/shared/misc/utils.ts2
-rw-r--r--client/src/app/shared/video/video.service.ts10
-rw-r--r--server/helpers/custom-validators/misc.ts16
-rw-r--r--server/middlewares/validators/videos.ts95
-rw-r--r--server/tests/api/check-params/videos.ts26
9 files changed, 100 insertions, 61 deletions
diff --git a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts
index 2b7ba353c..468be022c 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts
@@ -47,7 +47,7 @@ export class MyAccountProfileComponent extends FormReactive implements OnInit {
47 47
48 updateMyProfile () { 48 updateMyProfile () {
49 const displayName = this.form.value['display-name'] 49 const displayName = this.form.value['display-name']
50 const description = this.form.value['description'] 50 const description = this.form.value['description'] || null
51 51
52 this.error = null 52 this.error = null
53 53
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts
index 0f03548ad..fab9cacd8 100644
--- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts
+++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts
@@ -64,8 +64,8 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE
64 const body = this.form.value 64 const body = this.form.value
65 const videoChannelCreate: VideoChannelCreate = { 65 const videoChannelCreate: VideoChannelCreate = {
66 displayName: body['display-name'], 66 displayName: body['display-name'],
67 description: body.description || undefined, 67 description: body.description || null,
68 support: body.support || undefined 68 support: body.support || null
69 } 69 }
70 70
71 this.videoChannelService.createVideoChannel(videoChannelCreate).subscribe( 71 this.videoChannelService.createVideoChannel(videoChannelCreate).subscribe(
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
index c0dc6a939..9adc38691 100644
--- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
+++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
@@ -92,8 +92,8 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE
92 const body = this.form.value 92 const body = this.form.value
93 const videoChannelUpdate: VideoChannelUpdate = { 93 const videoChannelUpdate: VideoChannelUpdate = {
94 displayName: body['display-name'], 94 displayName: body['display-name'],
95 description: body.description || undefined, 95 description: body.description || null,
96 support: body.support || undefined 96 support: body.support || null
97 } 97 }
98 98
99 this.videoChannelService.updateVideoChannel(this.videoChannelToUpdate.uuid, videoChannelUpdate).subscribe( 99 this.videoChannelService.updateVideoChannel(this.videoChannelToUpdate.uuid, videoChannelUpdate).subscribe(
diff --git a/client/src/app/shared/forms/form-validators/user.ts b/client/src/app/shared/forms/form-validators/user.ts
index c6b65e0df..0973f1b00 100644
--- a/client/src/app/shared/forms/form-validators/user.ts
+++ b/client/src/app/shared/forms/form-validators/user.ts
@@ -60,12 +60,10 @@ export const USER_DISPLAY_NAME = {
60} 60}
61export const USER_DESCRIPTION = { 61export const USER_DESCRIPTION = {
62 VALIDATORS: [ 62 VALIDATORS: [
63 Validators.required,
64 Validators.minLength(3), 63 Validators.minLength(3),
65 Validators.maxLength(250) 64 Validators.maxLength(250)
66 ], 65 ],
67 MESSAGES: { 66 MESSAGES: {
68 'required': 'Description is required.',
69 'minlength': 'Description must be at least 3 characters long.', 67 'minlength': 'Description must be at least 3 characters long.',
70 'maxlength': 'Description cannot be more than 250 characters long.' 68 'maxlength': 'Description cannot be more than 250 characters long.'
71 } 69 }
diff --git a/client/src/app/shared/misc/utils.ts b/client/src/app/shared/misc/utils.ts
index 99f6b3cf0..b5bf99be2 100644
--- a/client/src/app/shared/misc/utils.ts
+++ b/client/src/app/shared/misc/utils.ts
@@ -66,7 +66,7 @@ function objectToFormData (obj: any, form?: FormData, namespace?: string) {
66 66
67 if (obj[key] === undefined) continue 67 if (obj[key] === undefined) continue
68 68
69 if (typeof obj[ key ] === 'object' && !(obj[ key ] instanceof File)) { 69 if (obj[key] !== null && typeof obj[ key ] === 'object' && !(obj[ key ] instanceof File)) {
70 objectToFormData(obj[ key ], fd, key) 70 objectToFormData(obj[ key ], fd, key)
71 } else { 71 } else {
72 fd.append(formKey, obj[ key ]) 72 fd.append(formKey, obj[ key ])
diff --git a/client/src/app/shared/video/video.service.ts b/client/src/app/shared/video/video.service.ts
index 8870cbee4..b45777c55 100644
--- a/client/src/app/shared/video/video.service.ts
+++ b/client/src/app/shared/video/video.service.ts
@@ -54,11 +54,11 @@ export class VideoService {
54 } 54 }
55 55
56 updateVideo (video: VideoEdit) { 56 updateVideo (video: VideoEdit) {
57 const language = video.language || undefined 57 const language = video.language || null
58 const licence = video.licence || undefined 58 const licence = video.licence || null
59 const category = video.category || undefined 59 const category = video.category || null
60 const description = video.description || undefined 60 const description = video.description || null
61 const support = video.support || undefined 61 const support = video.support || null
62 62
63 const body: VideoUpdate = { 63 const body: VideoUpdate = {
64 name: video.name, 64 name: video.name,
diff --git a/server/helpers/custom-validators/misc.ts b/server/helpers/custom-validators/misc.ts
index 8a270b777..275482fa1 100644
--- a/server/helpers/custom-validators/misc.ts
+++ b/server/helpers/custom-validators/misc.ts
@@ -25,10 +25,22 @@ function isIdOrUUIDValid (value: string) {
25 return isIdValid(value) || isUUIDValid(value) 25 return isIdValid(value) || isUUIDValid(value)
26} 26}
27 27
28function isBooleanValid (value: string) { 28function isBooleanValid (value: any) {
29 return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value)) 29 return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
30} 30}
31 31
32function toIntOrNull (value: string) {
33 if (value === 'null') return null
34
35 return validator.toInt(value)
36}
37
38function toStringOrNull (value: string) {
39 if (value === 'null') return null
40
41 return value
42}
43
32function isFileValid ( 44function isFileValid (
33 files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], 45 files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[],
34 mimeTypeRegex: string, 46 mimeTypeRegex: string,
@@ -61,6 +73,8 @@ export {
61 isUUIDValid, 73 isUUIDValid,
62 isIdOrUUIDValid, 74 isIdOrUUIDValid,
63 isDateValid, 75 isDateValid,
76 toStringOrNull,
64 isBooleanValid, 77 isBooleanValid,
78 toIntOrNull,
65 isFileValid 79 isFileValid
66} 80}
diff --git a/server/middlewares/validators/videos.ts b/server/middlewares/validators/videos.ts
index e3543ef93..b93dccc50 100644
--- a/server/middlewares/validators/videos.ts
+++ b/server/middlewares/validators/videos.ts
@@ -2,7 +2,7 @@ import * as express from 'express'
2import 'express-validator' 2import 'express-validator'
3import { body, param, query } from 'express-validator/check' 3import { body, param, query } from 'express-validator/check'
4import { UserRight, VideoPrivacy } from '../../../shared' 4import { UserRight, VideoPrivacy } from '../../../shared'
5import { isBooleanValid, isIdOrUUIDValid, isIdValid, isUUIDValid } from '../../helpers/custom-validators/misc' 5import { isBooleanValid, isIdOrUUIDValid, isIdValid, isUUIDValid, toIntOrNull, toStringOrNull } from '../../helpers/custom-validators/misc'
6import { 6import {
7 isVideoAbuseReasonValid, 7 isVideoAbuseReasonValid,
8 isVideoCategoryValid, 8 isVideoCategoryValid,
@@ -14,7 +14,8 @@ import {
14 isVideoLicenceValid, 14 isVideoLicenceValid,
15 isVideoNameValid, 15 isVideoNameValid,
16 isVideoPrivacyValid, 16 isVideoPrivacyValid,
17 isVideoRatingTypeValid, isVideoSupportValid, 17 isVideoRatingTypeValid,
18 isVideoSupportValid,
18 isVideoTagsValid 19 isVideoTagsValid
19} from '../../helpers/custom-validators/videos' 20} from '../../helpers/custom-validators/videos'
20import { getDurationFromVideoFile } from '../../helpers/ffmpeg-utils' 21import { getDurationFromVideoFile } from '../../helpers/ffmpeg-utils'
@@ -41,16 +42,40 @@ const videosAddValidator = [
41 + CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ') 42 + CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ')
42 ), 43 ),
43 body('name').custom(isVideoNameValid).withMessage('Should have a valid name'), 44 body('name').custom(isVideoNameValid).withMessage('Should have a valid name'),
44 body('category').optional().custom(isVideoCategoryValid).withMessage('Should have a valid category'), 45 body('category')
45 body('licence').optional().custom(isVideoLicenceValid).withMessage('Should have a valid licence'), 46 .optional()
46 body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'), 47 .customSanitizer(toIntOrNull)
47 body('nsfw').custom(isBooleanValid).withMessage('Should have a valid NSFW attribute'), 48 .custom(isVideoCategoryValid).withMessage('Should have a valid category'),
48 body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'), 49 body('licence')
49 body('support').optional().custom(isVideoSupportValid).withMessage('Should have a valid support text'), 50 .optional()
51 .customSanitizer(toIntOrNull)
52 .custom(isVideoLicenceValid).withMessage('Should have a valid licence'),
53 body('language')
54 .optional()
55 .customSanitizer(toStringOrNull)
56 .custom(isVideoLanguageValid).withMessage('Should have a valid language'),
57 body('nsfw')
58 .toBoolean()
59 .custom(isBooleanValid).withMessage('Should have a valid NSFW attribute'),
60 body('description')
61 .optional()
62 .customSanitizer(toStringOrNull)
63 .custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
64 body('support')
65 .optional()
66 .customSanitizer(toStringOrNull)
67 .custom(isVideoSupportValid).withMessage('Should have a valid support text'),
68 body('tags')
69 .optional()
70 .custom(isVideoTagsValid).withMessage('Should have correct tags'),
71 body('commentsEnabled')
72 .toBoolean()
73 .custom(isBooleanValid).withMessage('Should have comments enabled boolean'),
74 body('privacy')
75 .optional()
76 .toInt()
77 .custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'),
50 body('channelId').custom(isIdValid).withMessage('Should have correct video channel id'), 78 body('channelId').custom(isIdValid).withMessage('Should have correct video channel id'),
51 body('privacy').custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'),
52 body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'),
53 body('commentsEnabled').custom(isBooleanValid).withMessage('Should have comments enabled boolean'),
54 79
55 async (req: express.Request, res: express.Response, next: express.NextFunction) => { 80 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
56 logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) 81 logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files })
@@ -110,16 +135,44 @@ const videosUpdateValidator = [
110 'This preview file is not supported. Please, make sure it is of the following type : ' 135 'This preview file is not supported. Please, make sure it is of the following type : '
111 + CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ') 136 + CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME.join(', ')
112 ), 137 ),
113 body('name').optional().custom(isVideoNameValid).withMessage('Should have a valid name'), 138 body('name')
114 body('category').optional().custom(isVideoCategoryValid).withMessage('Should have a valid category'), 139 .optional()
115 body('licence').optional().custom(isVideoLicenceValid).withMessage('Should have a valid licence'), 140 .custom(isVideoNameValid).withMessage('Should have a valid name'),
116 body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'), 141 body('category')
117 body('nsfw').optional().custom(isBooleanValid).withMessage('Should have a valid NSFW attribute'), 142 .optional()
118 body('privacy').optional().custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'), 143 .customSanitizer(toIntOrNull)
119 body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'), 144 .custom(isVideoCategoryValid).withMessage('Should have a valid category'),
120 body('support').optional().custom(isVideoSupportValid).withMessage('Should have a valid support text'), 145 body('licence')
121 body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'), 146 .optional()
122 body('commentsEnabled').optional().custom(isBooleanValid).withMessage('Should have comments enabled boolean'), 147 .customSanitizer(toIntOrNull)
148 .custom(isVideoLicenceValid).withMessage('Should have a valid licence'),
149 body('language')
150 .optional()
151 .customSanitizer(toStringOrNull)
152 .custom(isVideoLanguageValid).withMessage('Should have a valid language'),
153 body('nsfw')
154 .optional()
155 .toBoolean()
156 .custom(isBooleanValid).withMessage('Should have a valid NSFW attribute'),
157 body('privacy')
158 .optional()
159 .toInt()
160 .custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'),
161 body('description')
162 .optional()
163 .customSanitizer(toStringOrNull)
164 .custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
165 body('support')
166 .optional()
167 .customSanitizer(toStringOrNull)
168 .custom(isVideoSupportValid).withMessage('Should have a valid support text'),
169 body('tags')
170 .optional()
171 .custom(isVideoTagsValid).withMessage('Should have correct tags'),
172 body('commentsEnabled')
173 .optional()
174 .toBoolean()
175 .custom(isBooleanValid).withMessage('Should have comments enabled boolean'),
123 176
124 async (req: express.Request, res: express.Response, next: express.NextFunction) => { 177 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
125 logger.debug('Checking videosUpdate parameters', { parameters: req.body }) 178 logger.debug('Checking videosUpdate parameters', { parameters: req.body })
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts
index 499a4fc94..2b341a5b3 100644
--- a/server/tests/api/check-params/videos.ts
+++ b/server/tests/api/check-params/videos.ts
@@ -231,13 +231,6 @@ describe('Test videos API validator', function () {
231 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) 231 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
232 }) 232 })
233 233
234 it('Should fail with a bad nsfw attribute', async function () {
235 const fields = immutableAssign(baseCorrectParams, { nsfw: 2 })
236 const attaches = baseCorrectAttaches
237
238 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
239 })
240
241 it('Should fail without commentsEnabled attribute', async function () { 234 it('Should fail without commentsEnabled attribute', async function () {
242 const fields = omit(baseCorrectParams, 'commentsEnabled') 235 const fields = omit(baseCorrectParams, 'commentsEnabled')
243 const attaches = baseCorrectAttaches 236 const attaches = baseCorrectAttaches
@@ -245,13 +238,6 @@ describe('Test videos API validator', function () {
245 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) 238 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
246 }) 239 })
247 240
248 it('Should fail with a bad commentsEnabled attribute', async function () {
249 const fields = immutableAssign(baseCorrectParams, { commentsEnabled: 2 })
250 const attaches = baseCorrectAttaches
251
252 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
253 })
254
255 it('Should fail with a long description', async function () { 241 it('Should fail with a long description', async function () {
256 const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(2500) }) 242 const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(2500) })
257 const attaches = baseCorrectAttaches 243 const attaches = baseCorrectAttaches
@@ -485,18 +471,6 @@ describe('Test videos API validator', function () {
485 await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields }) 471 await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
486 }) 472 })
487 473
488 it('Should fail with a bad nsfw attribute', async function () {
489 const fields = immutableAssign(baseCorrectParams, { nsfw: 2 })
490
491 await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
492 })
493
494 it('Should fail with a bad commentsEnabled attribute', async function () {
495 const fields = immutableAssign(baseCorrectParams, { commentsEnabled: 2 })
496
497 await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
498 })
499
500 it('Should fail with a long description', async function () { 474 it('Should fail with a long description', async function () {
501 const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(2500) }) 475 const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(2500) })
502 476