diff options
Diffstat (limited to 'client/src/app/shared/forms/form-validators')
8 files changed, 121 insertions, 40 deletions
diff --git a/client/src/app/shared/forms/form-validators/form-validator.service.ts b/client/src/app/shared/forms/form-validators/form-validator.service.ts index 19a8bef25..249fdf119 100644 --- a/client/src/app/shared/forms/form-validators/form-validator.service.ts +++ b/client/src/app/shared/forms/form-validators/form-validator.service.ts | |||
@@ -7,10 +7,10 @@ export type BuildFormValidator = { | |||
7 | MESSAGES: { [ name: string ]: string } | 7 | MESSAGES: { [ name: string ]: string } |
8 | } | 8 | } |
9 | export type BuildFormArgument = { | 9 | export type BuildFormArgument = { |
10 | [ id: string ]: BuildFormValidator | 10 | [ id: string ]: BuildFormValidator | BuildFormArgument |
11 | } | 11 | } |
12 | export type BuildFormDefaultValues = { | 12 | export type BuildFormDefaultValues = { |
13 | [ name: string ]: string | string[] | 13 | [ name: string ]: string | string[] | BuildFormDefaultValues |
14 | } | 14 | } |
15 | 15 | ||
16 | @Injectable() | 16 | @Injectable() |
@@ -29,7 +29,16 @@ export class FormValidatorService { | |||
29 | formErrors[name] = '' | 29 | formErrors[name] = '' |
30 | 30 | ||
31 | const field = obj[name] | 31 | const field = obj[name] |
32 | if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES | 32 | if (this.isRecursiveField(field)) { |
33 | const result = this.buildForm(field as BuildFormArgument, defaultValues[name] as BuildFormDefaultValues) | ||
34 | group[name] = result.form | ||
35 | formErrors[name] = result.formErrors | ||
36 | validationMessages[name] = result.validationMessages | ||
37 | |||
38 | continue | ||
39 | } | ||
40 | |||
41 | if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES as { [ name: string ]: string } | ||
33 | 42 | ||
34 | const defaultValue = defaultValues[name] || '' | 43 | const defaultValue = defaultValues[name] || '' |
35 | 44 | ||
@@ -52,13 +61,27 @@ export class FormValidatorService { | |||
52 | formErrors[name] = '' | 61 | formErrors[name] = '' |
53 | 62 | ||
54 | const field = obj[name] | 63 | const field = obj[name] |
55 | if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES | 64 | if (this.isRecursiveField(field)) { |
65 | this.updateForm( | ||
66 | form[name], | ||
67 | formErrors[name] as FormReactiveErrors, | ||
68 | validationMessages[name] as FormReactiveValidationMessages, | ||
69 | obj[name] as BuildFormArgument, | ||
70 | defaultValues[name] as BuildFormDefaultValues | ||
71 | ) | ||
72 | continue | ||
73 | } | ||
74 | |||
75 | if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES as { [ name: string ]: string } | ||
56 | 76 | ||
57 | const defaultValue = defaultValues[name] || '' | 77 | const defaultValue = defaultValues[name] || '' |
58 | 78 | ||
59 | if (field && field.VALIDATORS) form.addControl(name, new FormControl(defaultValue, field.VALIDATORS)) | 79 | if (field && field.VALIDATORS) form.addControl(name, new FormControl(defaultValue, field.VALIDATORS as ValidatorFn[])) |
60 | else form.addControl(name, new FormControl(defaultValue)) | 80 | else form.addControl(name, new FormControl(defaultValue)) |
61 | } | 81 | } |
62 | } | 82 | } |
63 | 83 | ||
84 | private isRecursiveField (field: any) { | ||
85 | return field && typeof field === 'object' && !field.MESSAGES && !field.VALIDATORS | ||
86 | } | ||
64 | } | 87 | } |
diff --git a/client/src/app/shared/forms/form-validators/index.ts b/client/src/app/shared/forms/form-validators/index.ts index 74e385b3d..fdcbedb71 100644 --- a/client/src/app/shared/forms/form-validators/index.ts +++ b/client/src/app/shared/forms/form-validators/index.ts | |||
@@ -1,6 +1,7 @@ | |||
1 | export * from './custom-config-validators.service' | 1 | export * from './custom-config-validators.service' |
2 | export * from './form-validator.service' | 2 | export * from './form-validator.service' |
3 | export * from './host' | 3 | export * from './host' |
4 | export * from './instance-validators.service' | ||
4 | export * from './login-validators.service' | 5 | export * from './login-validators.service' |
5 | export * from './reset-password-validators.service' | 6 | export * from './reset-password-validators.service' |
6 | export * from './user-validators.service' | 7 | export * from './user-validators.service' |
diff --git a/client/src/app/shared/forms/form-validators/instance-validators.service.ts b/client/src/app/shared/forms/form-validators/instance-validators.service.ts new file mode 100644 index 000000000..5bb852858 --- /dev/null +++ b/client/src/app/shared/forms/form-validators/instance-validators.service.ts | |||
@@ -0,0 +1,48 @@ | |||
1 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
2 | import { Validators } from '@angular/forms' | ||
3 | import { BuildFormValidator } from '@app/shared' | ||
4 | import { Injectable } from '@angular/core' | ||
5 | |||
6 | @Injectable() | ||
7 | export class InstanceValidatorsService { | ||
8 | readonly FROM_EMAIL: BuildFormValidator | ||
9 | readonly FROM_NAME: BuildFormValidator | ||
10 | readonly BODY: BuildFormValidator | ||
11 | |||
12 | constructor (private i18n: I18n) { | ||
13 | |||
14 | this.FROM_EMAIL = { | ||
15 | VALIDATORS: [ Validators.required, Validators.email ], | ||
16 | MESSAGES: { | ||
17 | 'required': this.i18n('Email is required.'), | ||
18 | 'email': this.i18n('Email must be valid.') | ||
19 | } | ||
20 | } | ||
21 | |||
22 | this.FROM_NAME = { | ||
23 | VALIDATORS: [ | ||
24 | Validators.required, | ||
25 | Validators.minLength(1), | ||
26 | Validators.maxLength(120) | ||
27 | ], | ||
28 | MESSAGES: { | ||
29 | 'required': this.i18n('Your name is required.'), | ||
30 | 'minlength': this.i18n('Your name must be at least 1 character long.'), | ||
31 | 'maxlength': this.i18n('Your name cannot be more than 120 characters long.') | ||
32 | } | ||
33 | } | ||
34 | |||
35 | this.BODY = { | ||
36 | VALIDATORS: [ | ||
37 | Validators.required, | ||
38 | Validators.minLength(3), | ||
39 | Validators.maxLength(5000) | ||
40 | ], | ||
41 | MESSAGES: { | ||
42 | 'required': this.i18n('A message is required.'), | ||
43 | 'minlength': this.i18n('The message must be at least 3 characters long.'), | ||
44 | 'maxlength': this.i18n('The message cannot be more than 5000 characters long.') | ||
45 | } | ||
46 | } | ||
47 | } | ||
48 | } | ||
diff --git a/client/src/app/shared/forms/form-validators/user-validators.service.ts b/client/src/app/shared/forms/form-validators/user-validators.service.ts index 1fd1cdf68..6589b2580 100644 --- a/client/src/app/shared/forms/form-validators/user-validators.service.ts +++ b/client/src/app/shared/forms/form-validators/user-validators.service.ts | |||
@@ -23,15 +23,15 @@ export class UserValidatorsService { | |||
23 | this.USER_USERNAME = { | 23 | this.USER_USERNAME = { |
24 | VALIDATORS: [ | 24 | VALIDATORS: [ |
25 | Validators.required, | 25 | Validators.required, |
26 | Validators.minLength(3), | 26 | Validators.minLength(1), |
27 | Validators.maxLength(20), | 27 | Validators.maxLength(50), |
28 | Validators.pattern(/^[a-z0-9._]+$/) | 28 | Validators.pattern(/^[a-z0-9][a-z0-9._]*$/) |
29 | ], | 29 | ], |
30 | MESSAGES: { | 30 | MESSAGES: { |
31 | 'required': this.i18n('Username is required.'), | 31 | 'required': this.i18n('Username is required.'), |
32 | 'minlength': this.i18n('Username must be at least 3 characters long.'), | 32 | 'minlength': this.i18n('Username must be at least 1 character long.'), |
33 | 'maxlength': this.i18n('Username cannot be more than 20 characters long.'), | 33 | 'maxlength': this.i18n('Username cannot be more than 50 characters long.'), |
34 | 'pattern': this.i18n('Username should be only lowercase alphanumeric characters.') | 34 | 'pattern': this.i18n('Username should be lowercase alphanumeric; dots and underscores are allowed.') |
35 | } | 35 | } |
36 | } | 36 | } |
37 | 37 | ||
@@ -88,24 +88,24 @@ export class UserValidatorsService { | |||
88 | this.USER_DISPLAY_NAME = { | 88 | this.USER_DISPLAY_NAME = { |
89 | VALIDATORS: [ | 89 | VALIDATORS: [ |
90 | Validators.required, | 90 | Validators.required, |
91 | Validators.minLength(3), | 91 | Validators.minLength(1), |
92 | Validators.maxLength(120) | 92 | Validators.maxLength(50) |
93 | ], | 93 | ], |
94 | MESSAGES: { | 94 | MESSAGES: { |
95 | 'required': this.i18n('Display name is required.'), | 95 | 'required': this.i18n('Display name is required.'), |
96 | 'minlength': this.i18n('Display name must be at least 3 characters long.'), | 96 | 'minlength': this.i18n('Display name must be at least 1 character long.'), |
97 | 'maxlength': this.i18n('Display name cannot be more than 120 characters long.') | 97 | 'maxlength': this.i18n('Display name cannot be more than 50 characters long.') |
98 | } | 98 | } |
99 | } | 99 | } |
100 | 100 | ||
101 | this.USER_DESCRIPTION = { | 101 | this.USER_DESCRIPTION = { |
102 | VALIDATORS: [ | 102 | VALIDATORS: [ |
103 | Validators.minLength(3), | 103 | Validators.minLength(3), |
104 | Validators.maxLength(250) | 104 | Validators.maxLength(1000) |
105 | ], | 105 | ], |
106 | MESSAGES: { | 106 | MESSAGES: { |
107 | 'minlength': this.i18n('Description must be at least 3 characters long.'), | 107 | 'minlength': this.i18n('Description must be at least 3 characters long.'), |
108 | 'maxlength': this.i18n('Description cannot be more than 250 characters long.') | 108 | 'maxlength': this.i18n('Description cannot be more than 1000 characters long.') |
109 | } | 109 | } |
110 | } | 110 | } |
111 | 111 | ||
diff --git a/client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts b/client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts index 6e9806611..fcc966b84 100644 --- a/client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts +++ b/client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts | |||
@@ -10,20 +10,20 @@ export class VideoAbuseValidatorsService { | |||
10 | 10 | ||
11 | constructor (private i18n: I18n) { | 11 | constructor (private i18n: I18n) { |
12 | this.VIDEO_ABUSE_REASON = { | 12 | this.VIDEO_ABUSE_REASON = { |
13 | VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(300) ], | 13 | VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ], |
14 | MESSAGES: { | 14 | MESSAGES: { |
15 | 'required': this.i18n('Report reason is required.'), | 15 | 'required': this.i18n('Report reason is required.'), |
16 | 'minlength': this.i18n('Report reason must be at least 2 characters long.'), | 16 | 'minlength': this.i18n('Report reason must be at least 2 characters long.'), |
17 | 'maxlength': this.i18n('Report reason cannot be more than 300 characters long.') | 17 | 'maxlength': this.i18n('Report reason cannot be more than 3000 characters long.') |
18 | } | 18 | } |
19 | } | 19 | } |
20 | 20 | ||
21 | this.VIDEO_ABUSE_MODERATION_COMMENT = { | 21 | this.VIDEO_ABUSE_MODERATION_COMMENT = { |
22 | VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(300) ], | 22 | VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ], |
23 | MESSAGES: { | 23 | MESSAGES: { |
24 | 'required': this.i18n('Moderation comment is required.'), | 24 | 'required': this.i18n('Moderation comment is required.'), |
25 | 'minlength': this.i18n('Moderation comment must be at least 2 characters long.'), | 25 | 'minlength': this.i18n('Moderation comment must be at least 2 characters long.'), |
26 | 'maxlength': this.i18n('Moderation comment cannot be more than 300 characters long.') | 26 | 'maxlength': this.i18n('Moderation comment cannot be more than 3000 characters long.') |
27 | } | 27 | } |
28 | } | 28 | } |
29 | } | 29 | } |
diff --git a/client/src/app/shared/forms/form-validators/video-change-ownership-validators.service.ts b/client/src/app/shared/forms/form-validators/video-change-ownership-validators.service.ts index 087b80b44..c6fbb7538 100644 --- a/client/src/app/shared/forms/form-validators/video-change-ownership-validators.service.ts +++ b/client/src/app/shared/forms/form-validators/video-change-ownership-validators.service.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { I18n } from '@ngx-translate/i18n-polyfill' | 1 | import { I18n } from '@ngx-translate/i18n-polyfill' |
2 | import { Validators } from '@angular/forms' | 2 | import { AbstractControl, ValidationErrors, Validators } from '@angular/forms' |
3 | import { Injectable } from '@angular/core' | 3 | import { Injectable } from '@angular/core' |
4 | import { BuildFormValidator } from '@app/shared' | 4 | import { BuildFormValidator } from '@app/shared' |
5 | 5 | ||
@@ -9,10 +9,19 @@ export class VideoChangeOwnershipValidatorsService { | |||
9 | 9 | ||
10 | constructor (private i18n: I18n) { | 10 | constructor (private i18n: I18n) { |
11 | this.USERNAME = { | 11 | this.USERNAME = { |
12 | VALIDATORS: [ Validators.required ], | 12 | VALIDATORS: [ Validators.required, this.localAccountValidator ], |
13 | MESSAGES: { | 13 | MESSAGES: { |
14 | 'required': this.i18n('The username is required.') | 14 | 'required': this.i18n('The username is required.'), |
15 | 'localAccountOnly': this.i18n('You can only transfer ownership to a local account') | ||
15 | } | 16 | } |
16 | } | 17 | } |
17 | } | 18 | } |
19 | |||
20 | localAccountValidator (control: AbstractControl): ValidationErrors { | ||
21 | if (control.value.includes('@')) { | ||
22 | return { 'localAccountOnly': true } | ||
23 | } | ||
24 | |||
25 | return null | ||
26 | } | ||
18 | } | 27 | } |
diff --git a/client/src/app/shared/forms/form-validators/video-channel-validators.service.ts b/client/src/app/shared/forms/form-validators/video-channel-validators.service.ts index 1ce3a0dca..1c519c10a 100644 --- a/client/src/app/shared/forms/form-validators/video-channel-validators.service.ts +++ b/client/src/app/shared/forms/form-validators/video-channel-validators.service.ts | |||
@@ -14,50 +14,50 @@ export class VideoChannelValidatorsService { | |||
14 | this.VIDEO_CHANNEL_NAME = { | 14 | this.VIDEO_CHANNEL_NAME = { |
15 | VALIDATORS: [ | 15 | VALIDATORS: [ |
16 | Validators.required, | 16 | Validators.required, |
17 | Validators.minLength(3), | 17 | Validators.minLength(1), |
18 | Validators.maxLength(20), | 18 | Validators.maxLength(50), |
19 | Validators.pattern(/^[a-z0-9._]+$/) | 19 | Validators.pattern(/^[a-z0-9][a-z0-9._]*$/) |
20 | ], | 20 | ], |
21 | MESSAGES: { | 21 | MESSAGES: { |
22 | 'required': this.i18n('Name is required.'), | 22 | 'required': this.i18n('Name is required.'), |
23 | 'minlength': this.i18n('Name must be at least 3 characters long.'), | 23 | 'minlength': this.i18n('Name must be at least 1 character long.'), |
24 | 'maxlength': this.i18n('Name cannot be more than 20 characters long.'), | 24 | 'maxlength': this.i18n('Name cannot be more than 50 characters long.'), |
25 | 'pattern': this.i18n('Name should be only lowercase alphanumeric characters.') | 25 | 'pattern': this.i18n('Name should be lowercase alphanumeric; dots and underscores are allowed.') |
26 | } | 26 | } |
27 | } | 27 | } |
28 | 28 | ||
29 | this.VIDEO_CHANNEL_DISPLAY_NAME = { | 29 | this.VIDEO_CHANNEL_DISPLAY_NAME = { |
30 | VALIDATORS: [ | 30 | VALIDATORS: [ |
31 | Validators.required, | 31 | Validators.required, |
32 | Validators.minLength(3), | 32 | Validators.minLength(1), |
33 | Validators.maxLength(120) | 33 | Validators.maxLength(50) |
34 | ], | 34 | ], |
35 | MESSAGES: { | 35 | MESSAGES: { |
36 | 'required': i18n('Display name is required.'), | 36 | 'required': i18n('Display name is required.'), |
37 | 'minlength': i18n('Display name must be at least 3 characters long.'), | 37 | 'minlength': i18n('Display name must be at least 1 character long.'), |
38 | 'maxlength': i18n('Display name cannot be more than 120 characters long.') | 38 | 'maxlength': i18n('Display name cannot be more than 50 characters long.') |
39 | } | 39 | } |
40 | } | 40 | } |
41 | 41 | ||
42 | this.VIDEO_CHANNEL_DESCRIPTION = { | 42 | this.VIDEO_CHANNEL_DESCRIPTION = { |
43 | VALIDATORS: [ | 43 | VALIDATORS: [ |
44 | Validators.minLength(3), | 44 | Validators.minLength(3), |
45 | Validators.maxLength(500) | 45 | Validators.maxLength(1000) |
46 | ], | 46 | ], |
47 | MESSAGES: { | 47 | MESSAGES: { |
48 | 'minlength': i18n('Description must be at least 3 characters long.'), | 48 | 'minlength': i18n('Description must be at least 3 characters long.'), |
49 | 'maxlength': i18n('Description cannot be more than 500 characters long.') | 49 | 'maxlength': i18n('Description cannot be more than 1000 characters long.') |
50 | } | 50 | } |
51 | } | 51 | } |
52 | 52 | ||
53 | this.VIDEO_CHANNEL_SUPPORT = { | 53 | this.VIDEO_CHANNEL_SUPPORT = { |
54 | VALIDATORS: [ | 54 | VALIDATORS: [ |
55 | Validators.minLength(3), | 55 | Validators.minLength(3), |
56 | Validators.maxLength(500) | 56 | Validators.maxLength(1000) |
57 | ], | 57 | ], |
58 | MESSAGES: { | 58 | MESSAGES: { |
59 | 'minlength': i18n('Support text must be at least 3 characters long.'), | 59 | 'minlength': i18n('Support text must be at least 3 characters long.'), |
60 | 'maxlength': i18n('Support text cannot be more than 500 characters long.') | 60 | 'maxlength': i18n('Support text cannot be more than 1000 characters long.') |
61 | } | 61 | } |
62 | } | 62 | } |
63 | } | 63 | } |
diff --git a/client/src/app/shared/forms/form-validators/video-validators.service.ts b/client/src/app/shared/forms/form-validators/video-validators.service.ts index 396be6f3b..81ed0666f 100644 --- a/client/src/app/shared/forms/form-validators/video-validators.service.ts +++ b/client/src/app/shared/forms/form-validators/video-validators.service.ts | |||
@@ -79,10 +79,10 @@ export class VideoValidatorsService { | |||
79 | } | 79 | } |
80 | 80 | ||
81 | this.VIDEO_SUPPORT = { | 81 | this.VIDEO_SUPPORT = { |
82 | VALIDATORS: [ Validators.minLength(3), Validators.maxLength(500) ], | 82 | VALIDATORS: [ Validators.minLength(3), Validators.maxLength(1000) ], |
83 | MESSAGES: { | 83 | MESSAGES: { |
84 | 'minlength': this.i18n('Video support must be at least 3 characters long.'), | 84 | 'minlength': this.i18n('Video support must be at least 3 characters long.'), |
85 | 'maxlength': this.i18n('Video support cannot be more than 500 characters long.') | 85 | 'maxlength': this.i18n('Video support cannot be more than 1000 characters long.') |
86 | } | 86 | } |
87 | } | 87 | } |
88 | 88 | ||