From 7ed1edbbe4ffbef28093e4f5630751cb652814e4 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 17 Aug 2020 11:47:04 +0200 Subject: We don't need services anymore for validators --- .../app/shared/form-validators/abuse-validators.ts | 29 ++++ .../form-validators/batch-domains-validators.ts | 60 ++++++++ .../form-validators/custom-config-validators.ts | 80 ++++++++++ .../shared/form-validators/form-validator.model.ts | 14 ++ client/src/app/shared/form-validators/host.ts | 8 + client/src/app/shared/form-validators/index.ts | 17 +++ .../shared/form-validators/instance-validators.ts | 49 ++++++ .../app/shared/form-validators/login-validators.ts | 20 +++ .../form-validators/reset-password-validators.ts | 11 ++ .../app/shared/form-validators/user-validators.ts | 144 ++++++++++++++++++ .../form-validators/video-block-validators.ts | 10 ++ .../form-validators/video-captions-validators.ts | 16 ++ .../form-validators/video-channel-validators.ts | 52 +++++++ .../form-validators/video-comment-validators.ts | 11 ++ .../video-ownership-change-validators.ts | 25 ++++ .../form-validators/video-playlist-validators.ts | 54 +++++++ .../app/shared/form-validators/video-validators.ts | 101 +++++++++++++ .../abuse-message-modal.component.ts | 6 +- .../moderation-comment-modal.component.ts | 8 +- .../src/app/shared/shared-forms/form-reactive.ts | 3 +- .../shared/shared-forms/form-validator.service.ts | 77 ++++++++++ .../form-validators/abuse-validators.service.ts | 39 ----- .../batch-domains-validators.service.ts | 68 --------- .../custom-config-validators.service.ts | 97 ------------ .../form-validators/form-validator.service.ts | 87 ----------- .../shared/shared-forms/form-validators/host.ts | 8 - .../shared/shared-forms/form-validators/index.ts | 17 --- .../form-validators/instance-validators.service.ts | 61 -------- .../form-validators/login-validators.service.ts | 29 ---- .../reset-password-validators.service.ts | 19 --- .../form-validators/user-validators.service.ts | 166 --------------------- .../video-accept-ownership-validators.service.ts | 17 --- .../video-block-validators.service.ts | 18 --- .../video-captions-validators.service.ts | 26 ---- .../video-change-ownership-validators.service.ts | 26 ---- .../video-channel-validators.service.ts | 63 -------- .../video-comment-validators.service.ts | 19 --- .../video-playlist-validators.service.ts | 65 -------- .../form-validators/video-validators.service.ts | 122 --------------- client/src/app/shared/shared-forms/index.ts | 2 +- .../app/shared/shared-forms/shared-form.module.ts | 43 +----- .../batch-domains-modal.component.ts | 10 +- .../report-modals/account-report.component.ts | 6 +- .../report-modals/comment-report.component.ts | 6 +- .../report-modals/video-report.component.ts | 6 +- .../shared-moderation/user-ban-modal.component.ts | 8 +- .../shared-moderation/video-block.component.ts | 6 +- .../remote-subscribe.component.ts | 8 +- .../video-add-to-playlist.component.ts | 6 +- 49 files changed, 821 insertions(+), 1022 deletions(-) create mode 100644 client/src/app/shared/form-validators/abuse-validators.ts create mode 100644 client/src/app/shared/form-validators/batch-domains-validators.ts create mode 100644 client/src/app/shared/form-validators/custom-config-validators.ts create mode 100644 client/src/app/shared/form-validators/form-validator.model.ts create mode 100644 client/src/app/shared/form-validators/host.ts create mode 100644 client/src/app/shared/form-validators/index.ts create mode 100644 client/src/app/shared/form-validators/instance-validators.ts create mode 100644 client/src/app/shared/form-validators/login-validators.ts create mode 100644 client/src/app/shared/form-validators/reset-password-validators.ts create mode 100644 client/src/app/shared/form-validators/user-validators.ts create mode 100644 client/src/app/shared/form-validators/video-block-validators.ts create mode 100644 client/src/app/shared/form-validators/video-captions-validators.ts create mode 100644 client/src/app/shared/form-validators/video-channel-validators.ts create mode 100644 client/src/app/shared/form-validators/video-comment-validators.ts create mode 100644 client/src/app/shared/form-validators/video-ownership-change-validators.ts create mode 100644 client/src/app/shared/form-validators/video-playlist-validators.ts create mode 100644 client/src/app/shared/form-validators/video-validators.ts create mode 100644 client/src/app/shared/shared-forms/form-validator.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/abuse-validators.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/batch-domains-validators.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/custom-config-validators.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/form-validator.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/host.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/index.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/instance-validators.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/login-validators.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/reset-password-validators.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/user-validators.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/video-accept-ownership-validators.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/video-block-validators.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/video-captions-validators.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/video-change-ownership-validators.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/video-channel-validators.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/video-comment-validators.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/video-playlist-validators.service.ts delete mode 100644 client/src/app/shared/shared-forms/form-validators/video-validators.service.ts (limited to 'client/src/app/shared') diff --git a/client/src/app/shared/form-validators/abuse-validators.ts b/client/src/app/shared/form-validators/abuse-validators.ts new file mode 100644 index 000000000..75bfacf01 --- /dev/null +++ b/client/src/app/shared/form-validators/abuse-validators.ts @@ -0,0 +1,29 @@ +import { Validators } from '@angular/forms' +import { BuildFormValidator } from './form-validator.model' + +export const ABUSE_REASON_VALIDATOR: BuildFormValidator = { + VALIDATORS: [Validators.required, Validators.minLength(2), Validators.maxLength(3000)], + MESSAGES: { + 'required': $localize`Report reason is required.`, + 'minlength': $localize`Report reason must be at least 2 characters long.`, + 'maxlength': $localize`Report reason cannot be more than 3000 characters long.` + } +} + +export const ABUSE_MODERATION_COMMENT_VALIDATOR: BuildFormValidator = { + VALIDATORS: [Validators.required, Validators.minLength(2), Validators.maxLength(3000)], + MESSAGES: { + 'required': $localize`Moderation comment is required.`, + 'minlength': $localize`Moderation comment must be at least 2 characters long.`, + 'maxlength': $localize`Moderation comment cannot be more than 3000 characters long.` + } +} + +export const ABUSE_MESSAGE_VALIDATOR: BuildFormValidator = { + VALIDATORS: [Validators.required, Validators.minLength(2), Validators.maxLength(3000)], + MESSAGES: { + 'required': $localize`Abuse message is required.`, + 'minlength': $localize`Abuse message must be at least 2 characters long.`, + 'maxlength': $localize`Abuse message cannot be more than 3000 characters long.` + } +} diff --git a/client/src/app/shared/form-validators/batch-domains-validators.ts b/client/src/app/shared/form-validators/batch-domains-validators.ts new file mode 100644 index 000000000..423d1337f --- /dev/null +++ b/client/src/app/shared/form-validators/batch-domains-validators.ts @@ -0,0 +1,60 @@ +import { AbstractControl, FormControl, ValidatorFn, Validators } from '@angular/forms' +import { BuildFormValidator } from './form-validator.model' +import { validateHost } from './host' + +export function getNotEmptyHosts (hosts: string) { + return hosts + .split('\n') + .filter((host: string) => host && host.length !== 0) // Eject empty hosts +} + +const validDomains: ValidatorFn = (control: FormControl) => { + if (!control.value) return null + + const newHostsErrors = [] + const hosts = getNotEmptyHosts(control.value) + + for (const host of hosts) { + if (validateHost(host) === false) { + newHostsErrors.push($localize`${host} is not valid`) + } + } + + /* Is not valid. */ + if (newHostsErrors.length !== 0) { + return { + 'validDomains': { + reason: 'invalid', + value: newHostsErrors.join('. ') + '.' + } + } + } + + /* Is valid. */ + return null +} + +const isHostsUnique: ValidatorFn = (control: AbstractControl) => { + if (!control.value) return null + + const hosts = getNotEmptyHosts(control.value) + + if (hosts.every((host: string) => hosts.indexOf(host) === hosts.lastIndexOf(host))) { + return null + } else { + return { + 'uniqueDomains': { + reason: 'invalid' + } + } + } +} + +export const DOMAINS_VALIDATOR: BuildFormValidator = { + VALIDATORS: [Validators.required, validDomains, isHostsUnique], + MESSAGES: { + 'required': $localize`Domain is required.`, + 'validDomains': $localize`Domains entered are invalid.`, + 'uniqueDomains': $localize`Domains entered contain duplicates.` + } +} diff --git a/client/src/app/shared/form-validators/custom-config-validators.ts b/client/src/app/shared/form-validators/custom-config-validators.ts new file mode 100644 index 000000000..41b3cbba9 --- /dev/null +++ b/client/src/app/shared/form-validators/custom-config-validators.ts @@ -0,0 +1,80 @@ +import { Validators } from '@angular/forms' +import { BuildFormValidator } from './form-validator.model' + +export const INSTANCE_NAME_VALIDATOR: BuildFormValidator = { + VALIDATORS: [Validators.required], + MESSAGES: { + 'required': $localize`Instance name is required.` + } +} + +export const INSTANCE_SHORT_DESCRIPTION_VALIDATOR: BuildFormValidator = { + VALIDATORS: [Validators.max(250)], + MESSAGES: { + 'max': $localize`Short description should not be longer than 250 characters.` + } +} + +export const SERVICES_TWITTER_USERNAME_VALIDATOR: BuildFormValidator = { + VALIDATORS: [Validators.required], + MESSAGES: { + 'required': $localize`Twitter username is required.` + } +} + +export const CACHE_PREVIEWS_SIZE_VALIDATOR: BuildFormValidator = { + VALIDATORS: [Validators.required, Validators.min(1), Validators.pattern('[0-9]+')], + MESSAGES: { + 'required': $localize`Previews cache size is required.`, + 'min': $localize`Previews cache size must be greater than 1.`, + 'pattern': $localize`Previews cache size must be a number.` + } +} + +export const CACHE_CAPTIONS_SIZE_VALIDATOR: BuildFormValidator = { + VALIDATORS: [Validators.required, Validators.min(1), Validators.pattern('[0-9]+')], + MESSAGES: { + 'required': $localize`Captions cache size is required.`, + 'min': $localize`Captions cache size must be greater than 1.`, + 'pattern': $localize`Captions cache size must be a number.` + } +} + +export const SIGNUP_LIMIT_VALIDATOR: BuildFormValidator = { + VALIDATORS: [Validators.required, Validators.min(-1), Validators.pattern('-?[0-9]+')], + MESSAGES: { + 'required': $localize`Signup limit is required.`, + 'min': $localize`Signup limit must be greater than 1.`, + 'pattern': $localize`Signup limit must be a number.` + } +} + +export const ADMIN_EMAIL_VALIDATOR: BuildFormValidator = { + VALIDATORS: [Validators.required, Validators.email], + MESSAGES: { + 'required': $localize`Admin email is required.`, + 'email': $localize`Admin email must be valid.` + } +} + +export const TRANSCODING_THREADS_VALIDATOR: BuildFormValidator = { + VALIDATORS: [Validators.required, Validators.min(0)], + MESSAGES: { + 'required': $localize`Transcoding threads is required.`, + 'min': $localize`Transcoding threads must be greater or equal to 0.` + } +} + +export const INDEX_URL_VALIDATOR: BuildFormValidator = { + VALIDATORS: [Validators.pattern(/^https:\/\//)], + MESSAGES: { + 'pattern': $localize`Index URL should be a URL` + } +} + +export const SEARCH_INDEX_URL_VALIDATOR: BuildFormValidator = { + VALIDATORS: [Validators.pattern(/^https?:\/\//)], + MESSAGES: { + 'pattern': $localize`Search index URL should be a URL` + } +} diff --git a/client/src/app/shared/form-validators/form-validator.model.ts b/client/src/app/shared/form-validators/form-validator.model.ts new file mode 100644 index 000000000..248a3b1d3 --- /dev/null +++ b/client/src/app/shared/form-validators/form-validator.model.ts @@ -0,0 +1,14 @@ +import { ValidatorFn } from '@angular/forms' + +export type BuildFormValidator = { + VALIDATORS: ValidatorFn[], + MESSAGES: { [ name: string ]: string } +} + +export type BuildFormArgument = { + [ id: string ]: BuildFormValidator | BuildFormArgument +} + +export type BuildFormDefaultValues = { + [ name: string ]: string | string[] | BuildFormDefaultValues +} diff --git a/client/src/app/shared/form-validators/host.ts b/client/src/app/shared/form-validators/host.ts new file mode 100644 index 000000000..c18a35f9b --- /dev/null +++ b/client/src/app/shared/form-validators/host.ts @@ -0,0 +1,8 @@ +export function validateHost (value: string) { + // Thanks to http://stackoverflow.com/a/106223 + const HOST_REGEXP = new RegExp( + '^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$' + ) + + return HOST_REGEXP.test(value) +} diff --git a/client/src/app/shared/form-validators/index.ts b/client/src/app/shared/form-validators/index.ts new file mode 100644 index 000000000..f621f03a4 --- /dev/null +++ b/client/src/app/shared/form-validators/index.ts @@ -0,0 +1,17 @@ +export * from './form-validator.model' +export * from './host' + +// Don't re export const variables because webpack 4 cannot do tree shaking with them +// export * from './abuse-validators' +// export * from './batch-domains-validators' +// export * from './custom-config-validators' +// export * from './instance-validators' +// export * from './login-validators' +// export * from './reset-password-validators' +// export * from './user-validators' +// export * from './video-block-validators' +// export * from './video-captions-validators' +// export * from './video-channel-validators' +// export * from './video-comment-validators' +// export * from './video-playlist-validators' +// export * from './video-validators' diff --git a/client/src/app/shared/form-validators/instance-validators.ts b/client/src/app/shared/form-validators/instance-validators.ts new file mode 100644 index 000000000..a72e28ba0 --- /dev/null +++ b/client/src/app/shared/form-validators/instance-validators.ts @@ -0,0 +1,49 @@ +import { Validators } from '@angular/forms' +import { BuildFormValidator } from './form-validator.model' + +export const FROM_EMAIL_VALIDATOR: BuildFormValidator = { + VALIDATORS: [Validators.required, Validators.email], + MESSAGES: { + 'required': $localize`Email is required.`, + 'email': $localize`Email must be valid.` + } +} + +export const FROM_NAME_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.required, + Validators.minLength(1), + Validators.maxLength(120) + ], + MESSAGES: { + 'required': $localize`Your name is required.`, + 'minlength': $localize`Your name must be at least 1 character long.`, + 'maxlength': $localize`Your name cannot be more than 120 characters long.` + } +} + +export const SUBJECT_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.required, + Validators.minLength(1), + Validators.maxLength(120) + ], + MESSAGES: { + 'required': $localize`A subject is required.`, + 'minlength': $localize`The subject must be at least 1 character long.`, + 'maxlength': $localize`The subject cannot be more than 120 characters long.` + } +} + +export const BODY_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.required, + Validators.minLength(3), + Validators.maxLength(5000) + ], + MESSAGES: { + 'required': $localize`A message is required.`, + 'minlength': $localize`The message must be at least 3 characters long.`, + 'maxlength': $localize`The message cannot be more than 5000 characters long.` + } +} diff --git a/client/src/app/shared/form-validators/login-validators.ts b/client/src/app/shared/form-validators/login-validators.ts new file mode 100644 index 000000000..1ceae1be3 --- /dev/null +++ b/client/src/app/shared/form-validators/login-validators.ts @@ -0,0 +1,20 @@ +import { Validators } from '@angular/forms' +import { BuildFormValidator } from './form-validator.model' + +export const LOGIN_USERNAME_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.required + ], + MESSAGES: { + 'required': $localize`Username is required.` + } +} + +export const LOGIN_PASSWORD_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.required + ], + MESSAGES: { + 'required': $localize`Password is required.` + } +} diff --git a/client/src/app/shared/form-validators/reset-password-validators.ts b/client/src/app/shared/form-validators/reset-password-validators.ts new file mode 100644 index 000000000..b87f2eab9 --- /dev/null +++ b/client/src/app/shared/form-validators/reset-password-validators.ts @@ -0,0 +1,11 @@ +import { Validators } from '@angular/forms' +import { BuildFormValidator } from './form-validator.model' + +export const RESET_PASSWORD_CONFIRM_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.required + ], + MESSAGES: { + 'required': $localize`Confirmation of the password is required.` + } +} diff --git a/client/src/app/shared/form-validators/user-validators.ts b/client/src/app/shared/form-validators/user-validators.ts new file mode 100644 index 000000000..18199505c --- /dev/null +++ b/client/src/app/shared/form-validators/user-validators.ts @@ -0,0 +1,144 @@ +import { Validators } from '@angular/forms' +import { BuildFormValidator } from './form-validator.model' + +export const USER_USERNAME_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.required, + Validators.minLength(1), + Validators.maxLength(50), + Validators.pattern(/^[a-z0-9][a-z0-9._]*$/) + ], + MESSAGES: { + 'required': $localize`Username is required.`, + 'minlength': $localize`Username must be at least 1 character long.`, + 'maxlength': $localize`Username cannot be more than 50 characters long.`, + 'pattern': $localize`Username should be lowercase alphanumeric; dots and underscores are allowed.` + } +} + +export const USER_CHANNEL_NAME_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.required, + Validators.minLength(1), + Validators.maxLength(50), + Validators.pattern(/^[a-z0-9][a-z0-9._]*$/) + ], + MESSAGES: { + 'required': $localize`Channel name is required.`, + 'minlength': $localize`Channel name must be at least 1 character long.`, + 'maxlength': $localize`Channel name cannot be more than 50 characters long.`, + 'pattern': $localize`Channel name should be lowercase alphanumeric; dots and underscores are allowed.` + } +} + +export const USER_EMAIL_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.required, Validators.email ], + MESSAGES: { + 'required': $localize`Email is required.`, + 'email': $localize`Email must be valid.` + } +} + +export const USER_PASSWORD_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.required, + Validators.minLength(6), + Validators.maxLength(255) + ], + MESSAGES: { + 'required': $localize`Password is required.`, + 'minlength': $localize`Password must be at least 6 characters long.`, + 'maxlength': $localize`Password cannot be more than 255 characters long.` + } +} + +export const USER_PASSWORD_OPTIONAL_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.minLength(6), + Validators.maxLength(255) + ], + MESSAGES: { + 'minlength': $localize`Password must be at least 6 characters long.`, + 'maxlength': $localize`Password cannot be more than 255 characters long.` + } +} + +export const USER_CONFIRM_PASSWORD_VALIDATOR: BuildFormValidator = { + VALIDATORS: [], + MESSAGES: { + 'matchPassword': $localize`The new password and the confirmed password do not correspond.` + } +} + +export const USER_VIDEO_QUOTA_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.required, Validators.min(-1) ], + MESSAGES: { + 'required': $localize`Video quota is required.`, + 'min': $localize`Quota must be greater than -1.` + } +} +export const USER_VIDEO_QUOTA_DAILY_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.required, Validators.min(-1) ], + MESSAGES: { + 'required': $localize`Daily upload limit is required.`, + 'min': $localize`Daily upload limit must be greater than -1.` + } +} + +export const USER_ROLE_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.required ], + MESSAGES: { + 'required': $localize`User role is required.` + } +} + +export const USER_DISPLAY_NAME_REQUIRED_VALIDATOR = buildDisplayNameValidator(true) + +export const USER_DESCRIPTION_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.minLength(3), + Validators.maxLength(1000) + ], + MESSAGES: { + 'minlength': $localize`Description must be at least 3 characters long.`, + 'maxlength': $localize`Description cannot be more than 1000 characters long.` + } +} + +export const USER_TERMS_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.requiredTrue + ], + MESSAGES: { + 'required': $localize`You must agree with the instance terms in order to register on it.` + } +} + +export const USER_BAN_REASON_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.minLength(3), + Validators.maxLength(250) + ], + MESSAGES: { + 'minlength': $localize`Ban reason must be at least 3 characters long.`, + 'maxlength': $localize`Ban reason cannot be more than 250 characters long.` + } +} + +function buildDisplayNameValidator (required: boolean) { + const control = { + VALIDATORS: [ + Validators.minLength(1), + Validators.maxLength(120) + ], + MESSAGES: { + 'required': $localize`Display name is required.`, + 'minlength': $localize`Display name must be at least 1 character long.`, + 'maxlength': $localize`Display name cannot be more than 50 characters long.` + } + } + + if (required) control.VALIDATORS.push(Validators.required) + + return control +} diff --git a/client/src/app/shared/form-validators/video-block-validators.ts b/client/src/app/shared/form-validators/video-block-validators.ts new file mode 100644 index 000000000..d3974aefe --- /dev/null +++ b/client/src/app/shared/form-validators/video-block-validators.ts @@ -0,0 +1,10 @@ +import { Validators } from '@angular/forms' +import { BuildFormValidator } from './form-validator.model' + +export const VIDEO_BLOCK_REASON_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.minLength(2), Validators.maxLength(300) ], + MESSAGES: { + 'minlength': $localize`Block reason must be at least 2 characters long.`, + 'maxlength': $localize`Block reason cannot be more than 300 characters long.` + } +} diff --git a/client/src/app/shared/form-validators/video-captions-validators.ts b/client/src/app/shared/form-validators/video-captions-validators.ts new file mode 100644 index 000000000..9742d2925 --- /dev/null +++ b/client/src/app/shared/form-validators/video-captions-validators.ts @@ -0,0 +1,16 @@ +import { Validators } from '@angular/forms' +import { BuildFormValidator } from './form-validator.model' + +export const VIDEO_CAPTION_LANGUAGE_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.required ], + MESSAGES: { + 'required': $localize`Video caption language is required.` + } +} + +export const VIDEO_CAPTION_FILE_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.required ], + MESSAGES: { + 'required': $localize`Video caption file is required.` + } +} diff --git a/client/src/app/shared/form-validators/video-channel-validators.ts b/client/src/app/shared/form-validators/video-channel-validators.ts new file mode 100644 index 000000000..0daab22ce --- /dev/null +++ b/client/src/app/shared/form-validators/video-channel-validators.ts @@ -0,0 +1,52 @@ +import { Validators } from '@angular/forms' +import { BuildFormValidator } from './form-validator.model' + +export const VIDEO_CHANNEL_NAME_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.required, + Validators.minLength(1), + Validators.maxLength(50), + Validators.pattern(/^[a-z0-9][a-z0-9._]*$/) + ], + MESSAGES: { + 'required': $localize`Name is required.`, + 'minlength': $localize`Name must be at least 1 character long.`, + 'maxlength': $localize`Name cannot be more than 50 characters long.`, + 'pattern': $localize`Name should be lowercase alphanumeric; dots and underscores are allowed.` + } +} + +export const VIDEO_CHANNEL_DISPLAY_NAME_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.required, + Validators.minLength(1), + Validators.maxLength(50) + ], + MESSAGES: { + 'required': $localize`Display name is required.`, + 'minlength': $localize`Display name must be at least 1 character long.`, + 'maxlength': $localize`Display name cannot be more than 50 characters long.` + } +} + +export const VIDEO_CHANNEL_DESCRIPTION_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.minLength(3), + Validators.maxLength(1000) + ], + MESSAGES: { + 'minlength': $localize`Description must be at least 3 characters long.`, + 'maxlength': $localize`Description cannot be more than 1000 characters long.` + } +} + +export const VIDEO_CHANNEL_SUPPORT_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.minLength(3), + Validators.maxLength(1000) + ], + MESSAGES: { + 'minlength': $localize`Support text must be at least 3 characters long.`, + 'maxlength': $localize`Support text cannot be more than 1000 characters long` + } +} diff --git a/client/src/app/shared/form-validators/video-comment-validators.ts b/client/src/app/shared/form-validators/video-comment-validators.ts new file mode 100644 index 000000000..c56564d34 --- /dev/null +++ b/client/src/app/shared/form-validators/video-comment-validators.ts @@ -0,0 +1,11 @@ +import { Validators } from '@angular/forms' +import { BuildFormValidator } from './form-validator.model' + +export const VIDEO_COMMENT_TEXT_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.required, Validators.minLength(1), Validators.maxLength(3000) ], + MESSAGES: { + 'required': $localize`Comment is required.`, + 'minlength': $localize`Comment must be at least 2 characters long.`, + 'maxlength': $localize`Comment cannot be more than 3000 characters long.` + } +} diff --git a/client/src/app/shared/form-validators/video-ownership-change-validators.ts b/client/src/app/shared/form-validators/video-ownership-change-validators.ts new file mode 100644 index 000000000..e1a2df8a6 --- /dev/null +++ b/client/src/app/shared/form-validators/video-ownership-change-validators.ts @@ -0,0 +1,25 @@ +import { AbstractControl, ValidationErrors, Validators } from '@angular/forms' +import { BuildFormValidator } from './form-validator.model' + +export const OWNERSHIP_CHANGE_CHANNEL_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.required ], + MESSAGES: { + 'required': $localize`The channel is required.` + } +} + +export const OWNERSHIP_CHANGE_USERNAME_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.required, localAccountValidator ], + MESSAGES: { + 'required': $localize`The username is required.`, + 'localAccountOnly': $localize`You can only transfer ownership to a local account` + } +} + +function localAccountValidator (control: AbstractControl): ValidationErrors { + if (control.value.includes('@')) { + return { 'localAccountOnly': true } + } + + return null +} diff --git a/client/src/app/shared/form-validators/video-playlist-validators.ts b/client/src/app/shared/form-validators/video-playlist-validators.ts new file mode 100644 index 000000000..7e3d29458 --- /dev/null +++ b/client/src/app/shared/form-validators/video-playlist-validators.ts @@ -0,0 +1,54 @@ +import { Validators, AbstractControl } from '@angular/forms' +import { BuildFormValidator } from './form-validator.model' +import { VideoPlaylistPrivacy } from '@shared/models' + +export const VIDEO_PLAYLIST_DISPLAY_NAME_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.required, + Validators.minLength(1), + Validators.maxLength(120) + ], + MESSAGES: { + 'required': $localize`Display name is required.`, + 'minlength': $localize`Display name must be at least 1 character long.`, + 'maxlength': $localize`Display name cannot be more than 120 characters long.` + } +} + +export const VIDEO_PLAYLIST_PRIVACY_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.required + ], + MESSAGES: { + 'required': $localize`Privacy is required.` + } +} + +export const VIDEO_PLAYLIST_DESCRIPTION_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ + Validators.minLength(3), + Validators.maxLength(1000) + ], + MESSAGES: { + 'minlength': $localize`Description must be at least 3 characters long.`, + 'maxlength': $localize`Description cannot be more than 1000 characters long.` + } +} + +export const VIDEO_PLAYLIST_CHANNEL_ID_VALIDATOR: BuildFormValidator = { + VALIDATORS: [], + MESSAGES: { + 'required': $localize`The channel is required when the playlist is public.` + } +} + +export function setPlaylistChannelValidator (channelControl: AbstractControl, privacy: VideoPlaylistPrivacy) { + if (privacy.toString() === VideoPlaylistPrivacy.PUBLIC.toString()) { + channelControl.setValidators([Validators.required]) + } else { + channelControl.setValidators(null) + } + + channelControl.markAsDirty() + channelControl.updateValueAndValidity() +} diff --git a/client/src/app/shared/form-validators/video-validators.ts b/client/src/app/shared/form-validators/video-validators.ts new file mode 100644 index 000000000..23f2391b2 --- /dev/null +++ b/client/src/app/shared/form-validators/video-validators.ts @@ -0,0 +1,101 @@ +import { AbstractControl, ValidationErrors, ValidatorFn, Validators } from '@angular/forms' +import { BuildFormValidator } from './form-validator.model' + +export const VIDEO_NAME_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.required, Validators.minLength(3), Validators.maxLength(120) ], + MESSAGES: { + 'required': $localize`Video name is required.`, + 'minlength': $localize`Video name must be at least 3 characters long.`, + 'maxlength': $localize`Video name cannot be more than 120 characters long.` + } +} + +export const VIDEO_PRIVACY_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.required ], + MESSAGES: { + 'required': $localize`Video privacy is required.` + } +} + +export const VIDEO_CATEGORY_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ ], + MESSAGES: {} +} + +export const VIDEO_LICENCE_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ ], + MESSAGES: {} +} + +export const VIDEO_LANGUAGE_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ ], + MESSAGES: {} +} + +export const VIDEO_IMAGE_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ ], + MESSAGES: {} +} + +export const VIDEO_CHANNEL_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.required ], + MESSAGES: { + 'required': $localize`Video channel is required.` + } +} + +export const VIDEO_DESCRIPTION_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.minLength(3), Validators.maxLength(10000) ], + MESSAGES: { + 'minlength': $localize`Video description must be at least 3 characters long.`, + 'maxlength': $localize`Video description cannot be more than 10000 characters long.` + } +} + +export const VIDEO_TAG_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.minLength(2), Validators.maxLength(30) ], + MESSAGES: { + 'minlength': $localize`A tag should be more than 2 characters long.`, + 'maxlength': $localize`A tag should be less than 30 characters long.` + } +} + +export const VIDEO_TAGS_ARRAY_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.maxLength(5), arrayTagLengthValidator() ], + MESSAGES: { + 'maxlength': $localize`A maximum of 5 tags can be used on a video.`, + 'arrayTagLength': $localize`A tag should be more than 2, and less than 30 characters long.` + } +} + +export const VIDEO_SUPPORT_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ Validators.minLength(3), Validators.maxLength(1000) ], + MESSAGES: { + 'minlength': $localize`Video support must be at least 3 characters long.`, + 'maxlength': $localize`Video support cannot be more than 1000 characters long.` + } +} + +export const VIDEO_SCHEDULE_PUBLICATION_AT_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ ], + MESSAGES: { + 'required': $localize`A date is required to schedule video update.` + } +} + +export const VIDEO_ORIGINALLY_PUBLISHED_AT_VALIDATOR: BuildFormValidator = { + VALIDATORS: [ ], + MESSAGES: {} +} + +function arrayTagLengthValidator (min = 2, max = 30): ValidatorFn { + return (control: AbstractControl): ValidationErrors => { + const array = control.value as Array + + if (array.every(e => e.length > min && e.length < max)) { + return null + } + + return { 'arrayTagLength': true } + } +} diff --git a/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts b/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts index 0c3c8ff48..9abb4c094 100644 --- a/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts +++ b/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts @@ -1,9 +1,10 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' import { AuthService, HtmlRendererService, Notifier } from '@app/core' -import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' +import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' import { AbuseMessage, UserAbuse } from '@shared/models' +import { ABUSE_MESSAGE_VALIDATOR } from '../form-validators/abuse-validators' import { AbuseService } from '../shared-moderation' @Component({ @@ -28,7 +29,6 @@ export class AbuseMessageModalComponent extends FormReactive implements OnInit { constructor ( protected formValidatorService: FormValidatorService, - private abuseValidatorsService: AbuseValidatorsService, private modalService: NgbModal, private htmlRenderer: HtmlRendererService, private auth: AuthService, @@ -40,7 +40,7 @@ export class AbuseMessageModalComponent extends FormReactive implements OnInit { ngOnInit () { this.buildForm({ - message: this.abuseValidatorsService.ABUSE_MESSAGE + message: ABUSE_MESSAGE_VALIDATOR }) } diff --git a/client/src/app/shared/shared-abuse-list/moderation-comment-modal.component.ts b/client/src/app/shared/shared-abuse-list/moderation-comment-modal.component.ts index fad7f888d..876aeea8a 100644 --- a/client/src/app/shared/shared-abuse-list/moderation-comment-modal.component.ts +++ b/client/src/app/shared/shared-abuse-list/moderation-comment-modal.component.ts @@ -1,10 +1,11 @@ import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core' import { Notifier } from '@app/core' -import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' +import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { AbuseService } from '@app/shared/shared-moderation' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' import { AdminAbuse } from '@shared/models' +import { ABUSE_MODERATION_COMMENT_VALIDATOR } from '../form-validators/abuse-validators' @Component({ selector: 'my-moderation-comment-modal', @@ -22,15 +23,14 @@ export class ModerationCommentModalComponent extends FormReactive implements OnI protected formValidatorService: FormValidatorService, private modalService: NgbModal, private notifier: Notifier, - private abuseService: AbuseService, - private abuseValidatorsService: AbuseValidatorsService + private abuseService: AbuseService ) { super() } ngOnInit () { this.buildForm({ - moderationComment: this.abuseValidatorsService.ABUSE_MODERATION_COMMENT + moderationComment: ABUSE_MODERATION_COMMENT_VALIDATOR }) } diff --git a/client/src/app/shared/shared-forms/form-reactive.ts b/client/src/app/shared/shared-forms/form-reactive.ts index caa31d831..adf6cb894 100644 --- a/client/src/app/shared/shared-forms/form-reactive.ts +++ b/client/src/app/shared/shared-forms/form-reactive.ts @@ -1,5 +1,6 @@ import { FormGroup } from '@angular/forms' -import { BuildFormArgument, BuildFormDefaultValues, FormValidatorService } from './form-validators' +import { BuildFormArgument, BuildFormDefaultValues } from '../form-validators/form-validator.model' +import { FormValidatorService } from './form-validator.service' export type FormReactiveErrors = { [ id: string ]: string | FormReactiveErrors } export type FormReactiveValidationMessages = { diff --git a/client/src/app/shared/shared-forms/form-validator.service.ts b/client/src/app/shared/shared-forms/form-validator.service.ts new file mode 100644 index 000000000..41c8b76bd --- /dev/null +++ b/client/src/app/shared/shared-forms/form-validator.service.ts @@ -0,0 +1,77 @@ +import { Injectable } from '@angular/core' +import { FormBuilder, FormControl, FormGroup, ValidatorFn } from '@angular/forms' +import { BuildFormArgument, BuildFormDefaultValues } from '../form-validators/form-validator.model' +import { FormReactiveErrors, FormReactiveValidationMessages } from './form-reactive' + +@Injectable() +export class FormValidatorService { + + constructor ( + private formBuilder: FormBuilder + ) {} + + buildForm (obj: BuildFormArgument, defaultValues: BuildFormDefaultValues = {}) { + const formErrors: FormReactiveErrors = {} + const validationMessages: FormReactiveValidationMessages = {} + const group: { [key: string]: any } = {} + + for (const name of Object.keys(obj)) { + formErrors[name] = '' + + const field = obj[name] + if (this.isRecursiveField(field)) { + const result = this.buildForm(field as BuildFormArgument, defaultValues[name] as BuildFormDefaultValues) + group[name] = result.form + formErrors[name] = result.formErrors + validationMessages[name] = result.validationMessages + + continue + } + + if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES as { [ name: string ]: string } + + const defaultValue = defaultValues[name] || '' + + if (field && field.VALIDATORS) group[name] = [ defaultValue, field.VALIDATORS ] + else group[name] = [ defaultValue ] + } + + const form = this.formBuilder.group(group) + return { form, formErrors, validationMessages } + } + + updateForm ( + form: FormGroup, + formErrors: FormReactiveErrors, + validationMessages: FormReactiveValidationMessages, + obj: BuildFormArgument, + defaultValues: BuildFormDefaultValues = {} + ) { + for (const name of Object.keys(obj)) { + formErrors[name] = '' + + const field = obj[name] + if (this.isRecursiveField(field)) { + this.updateForm( + form[name], + formErrors[name] as FormReactiveErrors, + validationMessages[name] as FormReactiveValidationMessages, + obj[name] as BuildFormArgument, + defaultValues[name] as BuildFormDefaultValues + ) + continue + } + + if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES as { [ name: string ]: string } + + const defaultValue = defaultValues[name] || '' + + if (field && field.VALIDATORS) form.addControl(name, new FormControl(defaultValue, field.VALIDATORS as ValidatorFn[])) + else form.addControl(name, new FormControl(defaultValue)) + } + } + + private isRecursiveField (field: any) { + return field && typeof field === 'object' && !field.MESSAGES && !field.VALIDATORS + } +} diff --git a/client/src/app/shared/shared-forms/form-validators/abuse-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/abuse-validators.service.ts deleted file mode 100644 index 56d30d6f9..000000000 --- a/client/src/app/shared/shared-forms/form-validators/abuse-validators.service.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Injectable } from '@angular/core' -import { Validators } from '@angular/forms' -import { BuildFormValidator } from './form-validator.service' - -@Injectable() -export class AbuseValidatorsService { - readonly ABUSE_REASON: BuildFormValidator - readonly ABUSE_MODERATION_COMMENT: BuildFormValidator - readonly ABUSE_MESSAGE: BuildFormValidator - - constructor () { - this.ABUSE_REASON = { - VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ], - MESSAGES: { - 'required': $localize`Report reason is required.`, - 'minlength': $localize`Report reason must be at least 2 characters long.`, - 'maxlength': $localize`Report reason cannot be more than 3000 characters long.` - } - } - - this.ABUSE_MODERATION_COMMENT = { - VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ], - MESSAGES: { - 'required': $localize`Moderation comment is required.`, - 'minlength': $localize`Moderation comment must be at least 2 characters long.`, - 'maxlength': $localize`Moderation comment cannot be more than 3000 characters long.` - } - } - - this.ABUSE_MESSAGE = { - VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ], - MESSAGES: { - 'required': $localize`Abuse message is required.`, - 'minlength': $localize`Abuse message must be at least 2 characters long.`, - 'maxlength': $localize`Abuse message cannot be more than 3000 characters long.` - } - } - } -} diff --git a/client/src/app/shared/shared-forms/form-validators/batch-domains-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/batch-domains-validators.service.ts deleted file mode 100644 index 6c7da833f..000000000 --- a/client/src/app/shared/shared-forms/form-validators/batch-domains-validators.service.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Injectable } from '@angular/core' -import { ValidatorFn, Validators } from '@angular/forms' -import { BuildFormValidator } from './form-validator.service' -import { validateHost } from './host' - -@Injectable() -export class BatchDomainsValidatorsService { - readonly DOMAINS: BuildFormValidator - - constructor () { - this.DOMAINS = { - VALIDATORS: [ Validators.required, this.validDomains, this.isHostsUnique ], - MESSAGES: { - 'required': $localize`Domain is required.`, - 'validDomains': $localize`Domains entered are invalid.`, - 'uniqueDomains': $localize`Domains entered contain duplicates.` - } - } - } - - getNotEmptyHosts (hosts: string) { - return hosts - .split('\n') - .filter((host: string) => host && host.length !== 0) // Eject empty hosts - } - - private validDomains: ValidatorFn = (control) => { - if (!control.value) return null - - const newHostsErrors = [] - const hosts = this.getNotEmptyHosts(control.value) - - for (const host of hosts) { - if (validateHost(host) === false) { - newHostsErrors.push($localize`${host} is not valid`) - } - } - - /* Is not valid. */ - if (newHostsErrors.length !== 0) { - return { - 'validDomains': { - reason: 'invalid', - value: newHostsErrors.join('. ') + '.' - } - } - } - - /* Is valid. */ - return null - } - - private isHostsUnique: ValidatorFn = (control) => { - if (!control.value) return null - - const hosts = this.getNotEmptyHosts(control.value) - - if (hosts.every((host: string) => hosts.indexOf(host) === hosts.lastIndexOf(host))) { - return null - } else { - return { - 'uniqueDomains': { - reason: 'invalid' - } - } - } - } -} diff --git a/client/src/app/shared/shared-forms/form-validators/custom-config-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/custom-config-validators.service.ts deleted file mode 100644 index 862ff5470..000000000 --- a/client/src/app/shared/shared-forms/form-validators/custom-config-validators.service.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { Injectable } from '@angular/core' -import { Validators } from '@angular/forms' -import { BuildFormValidator } from './form-validator.service' - -@Injectable() -export class CustomConfigValidatorsService { - readonly INSTANCE_NAME: BuildFormValidator - readonly INSTANCE_SHORT_DESCRIPTION: BuildFormValidator - readonly SERVICES_TWITTER_USERNAME: BuildFormValidator - readonly CACHE_PREVIEWS_SIZE: BuildFormValidator - readonly CACHE_CAPTIONS_SIZE: BuildFormValidator - readonly SIGNUP_LIMIT: BuildFormValidator - readonly ADMIN_EMAIL: BuildFormValidator - readonly TRANSCODING_THREADS: BuildFormValidator - readonly INDEX_URL: BuildFormValidator - readonly SEARCH_INDEX_URL: BuildFormValidator - - constructor () { - this.INSTANCE_NAME = { - VALIDATORS: [ Validators.required ], - MESSAGES: { - 'required': $localize`Instance name is required.` - } - } - - this.INSTANCE_SHORT_DESCRIPTION = { - VALIDATORS: [ Validators.max(250) ], - MESSAGES: { - 'max': $localize`Short description should not be longer than 250 characters.` - } - } - - this.SERVICES_TWITTER_USERNAME = { - VALIDATORS: [ Validators.required ], - MESSAGES: { - 'required': $localize`Twitter username is required.` - } - } - - this.CACHE_PREVIEWS_SIZE = { - VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ], - MESSAGES: { - 'required': $localize`Previews cache size is required.`, - 'min': $localize`Previews cache size must be greater than 1.`, - 'pattern': $localize`Previews cache size must be a number.` - } - } - - this.CACHE_CAPTIONS_SIZE = { - VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ], - MESSAGES: { - 'required': $localize`Captions cache size is required.`, - 'min': $localize`Captions cache size must be greater than 1.`, - 'pattern': $localize`Captions cache size must be a number.` - } - } - - this.SIGNUP_LIMIT = { - VALIDATORS: [ Validators.required, Validators.min(-1), Validators.pattern('-?[0-9]+') ], - MESSAGES: { - 'required': $localize`Signup limit is required.`, - 'min': $localize`Signup limit must be greater than 1.`, - 'pattern': $localize`Signup limit must be a number.` - } - } - - this.ADMIN_EMAIL = { - VALIDATORS: [ Validators.required, Validators.email ], - MESSAGES: { - 'required': $localize`Admin email is required.`, - 'email': $localize`Admin email must be valid.` - } - } - - this.TRANSCODING_THREADS = { - VALIDATORS: [ Validators.required, Validators.min(0) ], - MESSAGES: { - 'required': $localize`Transcoding threads is required.`, - 'min': $localize`Transcoding threads must be greater or equal to 0.` - } - } - - this.INDEX_URL = { - VALIDATORS: [ Validators.pattern(/^https:\/\//) ], - MESSAGES: { - 'pattern': $localize`Index URL should be a URL` - } - } - - this.SEARCH_INDEX_URL = { - VALIDATORS: [ Validators.pattern(/^https?:\/\//) ], - MESSAGES: { - 'pattern': $localize`Search index URL should be a URL` - } - } - } -} diff --git a/client/src/app/shared/shared-forms/form-validators/form-validator.service.ts b/client/src/app/shared/shared-forms/form-validators/form-validator.service.ts deleted file mode 100644 index dec7d8d9a..000000000 --- a/client/src/app/shared/shared-forms/form-validators/form-validator.service.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { FormBuilder, FormControl, FormGroup, ValidatorFn } from '@angular/forms' -import { Injectable } from '@angular/core' -import { FormReactiveErrors, FormReactiveValidationMessages } from '../form-reactive' - -export type BuildFormValidator = { - VALIDATORS: ValidatorFn[], - MESSAGES: { [ name: string ]: string } -} -export type BuildFormArgument = { - [ id: string ]: BuildFormValidator | BuildFormArgument -} -export type BuildFormDefaultValues = { - [ name: string ]: string | string[] | BuildFormDefaultValues -} - -@Injectable() -export class FormValidatorService { - - constructor ( - private formBuilder: FormBuilder - ) {} - - buildForm (obj: BuildFormArgument, defaultValues: BuildFormDefaultValues = {}) { - const formErrors: FormReactiveErrors = {} - const validationMessages: FormReactiveValidationMessages = {} - const group: { [key: string]: any } = {} - - for (const name of Object.keys(obj)) { - formErrors[name] = '' - - const field = obj[name] - if (this.isRecursiveField(field)) { - const result = this.buildForm(field as BuildFormArgument, defaultValues[name] as BuildFormDefaultValues) - group[name] = result.form - formErrors[name] = result.formErrors - validationMessages[name] = result.validationMessages - - continue - } - - if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES as { [ name: string ]: string } - - const defaultValue = defaultValues[name] || '' - - if (field && field.VALIDATORS) group[name] = [ defaultValue, field.VALIDATORS ] - else group[name] = [ defaultValue ] - } - - const form = this.formBuilder.group(group) - return { form, formErrors, validationMessages } - } - - updateForm ( - form: FormGroup, - formErrors: FormReactiveErrors, - validationMessages: FormReactiveValidationMessages, - obj: BuildFormArgument, - defaultValues: BuildFormDefaultValues = {} - ) { - for (const name of Object.keys(obj)) { - formErrors[name] = '' - - const field = obj[name] - if (this.isRecursiveField(field)) { - this.updateForm( - form[name], - formErrors[name] as FormReactiveErrors, - validationMessages[name] as FormReactiveValidationMessages, - obj[name] as BuildFormArgument, - defaultValues[name] as BuildFormDefaultValues - ) - continue - } - - if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES as { [ name: string ]: string } - - const defaultValue = defaultValues[name] || '' - - if (field && field.VALIDATORS) form.addControl(name, new FormControl(defaultValue, field.VALIDATORS as ValidatorFn[])) - else form.addControl(name, new FormControl(defaultValue)) - } - } - - private isRecursiveField (field: any) { - return field && typeof field === 'object' && !field.MESSAGES && !field.VALIDATORS - } -} diff --git a/client/src/app/shared/shared-forms/form-validators/host.ts b/client/src/app/shared/shared-forms/form-validators/host.ts deleted file mode 100644 index c18a35f9b..000000000 --- a/client/src/app/shared/shared-forms/form-validators/host.ts +++ /dev/null @@ -1,8 +0,0 @@ -export function validateHost (value: string) { - // Thanks to http://stackoverflow.com/a/106223 - const HOST_REGEXP = new RegExp( - '^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$' - ) - - return HOST_REGEXP.test(value) -} diff --git a/client/src/app/shared/shared-forms/form-validators/index.ts b/client/src/app/shared/shared-forms/form-validators/index.ts deleted file mode 100644 index b06a326ff..000000000 --- a/client/src/app/shared/shared-forms/form-validators/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -export * from './abuse-validators.service' -export * from './batch-domains-validators.service' -export * from './custom-config-validators.service' -export * from './form-validator.service' -export * from './host' -export * from './instance-validators.service' -export * from './login-validators.service' -export * from './reset-password-validators.service' -export * from './user-validators.service' -export * from './video-accept-ownership-validators.service' -export * from './video-block-validators.service' -export * from './video-captions-validators.service' -export * from './video-change-ownership-validators.service' -export * from './video-channel-validators.service' -export * from './video-comment-validators.service' -export * from './video-playlist-validators.service' -export * from './video-validators.service' diff --git a/client/src/app/shared/shared-forms/form-validators/instance-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/instance-validators.service.ts deleted file mode 100644 index 3628f0b60..000000000 --- a/client/src/app/shared/shared-forms/form-validators/instance-validators.service.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Injectable } from '@angular/core' -import { Validators } from '@angular/forms' -import { BuildFormValidator } from './form-validator.service' - -@Injectable() -export class InstanceValidatorsService { - readonly FROM_EMAIL: BuildFormValidator - readonly FROM_NAME: BuildFormValidator - readonly SUBJECT: BuildFormValidator - readonly BODY: BuildFormValidator - - constructor () { - - this.FROM_EMAIL = { - VALIDATORS: [ Validators.required, Validators.email ], - MESSAGES: { - 'required': $localize`Email is required.`, - 'email': $localize`Email must be valid.` - } - } - - this.FROM_NAME = { - VALIDATORS: [ - Validators.required, - Validators.minLength(1), - Validators.maxLength(120) - ], - MESSAGES: { - 'required': $localize`Your name is required.`, - 'minlength': $localize`Your name must be at least 1 character long.`, - 'maxlength': $localize`Your name cannot be more than 120 characters long.` - } - } - - this.SUBJECT = { - VALIDATORS: [ - Validators.required, - Validators.minLength(1), - Validators.maxLength(120) - ], - MESSAGES: { - 'required': $localize`A subject is required.`, - 'minlength': $localize`The subject must be at least 1 character long.`, - 'maxlength': $localize`The subject cannot be more than 120 characters long.` - } - } - - this.BODY = { - VALIDATORS: [ - Validators.required, - Validators.minLength(3), - Validators.maxLength(5000) - ], - MESSAGES: { - 'required': $localize`A message is required.`, - 'minlength': $localize`The message must be at least 3 characters long.`, - 'maxlength': $localize`The message cannot be more than 5000 characters long.` - } - } - } -} diff --git a/client/src/app/shared/shared-forms/form-validators/login-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/login-validators.service.ts deleted file mode 100644 index 67ea11f20..000000000 --- a/client/src/app/shared/shared-forms/form-validators/login-validators.service.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Injectable } from '@angular/core' -import { Validators } from '@angular/forms' -import { BuildFormValidator } from './form-validator.service' - -@Injectable() -export class LoginValidatorsService { - readonly LOGIN_USERNAME: BuildFormValidator - readonly LOGIN_PASSWORD: BuildFormValidator - - constructor () { - this.LOGIN_USERNAME = { - VALIDATORS: [ - Validators.required - ], - MESSAGES: { - 'required': $localize`Username is required.` - } - } - - this.LOGIN_PASSWORD = { - VALIDATORS: [ - Validators.required - ], - MESSAGES: { - 'required': $localize`Password is required.` - } - } - } -} diff --git a/client/src/app/shared/shared-forms/form-validators/reset-password-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/reset-password-validators.service.ts deleted file mode 100644 index 3d0b4dd64..000000000 --- a/client/src/app/shared/shared-forms/form-validators/reset-password-validators.service.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Injectable } from '@angular/core' -import { Validators } from '@angular/forms' -import { BuildFormValidator } from './form-validator.service' - -@Injectable() -export class ResetPasswordValidatorsService { - readonly RESET_PASSWORD_CONFIRM: BuildFormValidator - - constructor () { - this.RESET_PASSWORD_CONFIRM = { - VALIDATORS: [ - Validators.required - ], - MESSAGES: { - 'required': $localize`Confirmation of the password is required.` - } - } - } -} diff --git a/client/src/app/shared/shared-forms/form-validators/user-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/user-validators.service.ts deleted file mode 100644 index 312fc9b1e..000000000 --- a/client/src/app/shared/shared-forms/form-validators/user-validators.service.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { Injectable } from '@angular/core' -import { Validators } from '@angular/forms' -import { BuildFormValidator } from './form-validator.service' - -@Injectable() -export class UserValidatorsService { - readonly USER_USERNAME: BuildFormValidator - readonly USER_CHANNEL_NAME: BuildFormValidator - readonly USER_EMAIL: BuildFormValidator - readonly USER_PASSWORD: BuildFormValidator - readonly USER_PASSWORD_OPTIONAL: BuildFormValidator - readonly USER_CONFIRM_PASSWORD: BuildFormValidator - readonly USER_VIDEO_QUOTA: BuildFormValidator - readonly USER_VIDEO_QUOTA_DAILY: BuildFormValidator - readonly USER_ROLE: BuildFormValidator - readonly USER_DISPLAY_NAME_REQUIRED: BuildFormValidator - readonly USER_DESCRIPTION: BuildFormValidator - readonly USER_TERMS: BuildFormValidator - - readonly USER_BAN_REASON: BuildFormValidator - - constructor () { - - this.USER_USERNAME = { - VALIDATORS: [ - Validators.required, - Validators.minLength(1), - Validators.maxLength(50), - Validators.pattern(/^[a-z0-9][a-z0-9._]*$/) - ], - MESSAGES: { - 'required': $localize`Username is required.`, - 'minlength': $localize`Username must be at least 1 character long.`, - 'maxlength': $localize`Username cannot be more than 50 characters long.`, - 'pattern': $localize`Username should be lowercase alphanumeric; dots and underscores are allowed.` - } - } - - this.USER_CHANNEL_NAME = { - VALIDATORS: [ - Validators.required, - Validators.minLength(1), - Validators.maxLength(50), - Validators.pattern(/^[a-z0-9][a-z0-9._]*$/) - ], - MESSAGES: { - 'required': $localize`Channel name is required.`, - 'minlength': $localize`Channel name must be at least 1 character long.`, - 'maxlength': $localize`Channel name cannot be more than 50 characters long.`, - 'pattern': $localize`Channel name should be lowercase alphanumeric; dots and underscores are allowed.` - } - } - - this.USER_EMAIL = { - VALIDATORS: [ Validators.required, Validators.email ], - MESSAGES: { - 'required': $localize`Email is required.`, - 'email': $localize`Email must be valid.` - } - } - - this.USER_PASSWORD = { - VALIDATORS: [ - Validators.required, - Validators.minLength(6), - Validators.maxLength(255) - ], - MESSAGES: { - 'required': $localize`Password is required.`, - 'minlength': $localize`Password must be at least 6 characters long.`, - 'maxlength': $localize`Password cannot be more than 255 characters long.` - } - } - - this.USER_PASSWORD_OPTIONAL = { - VALIDATORS: [ - Validators.minLength(6), - Validators.maxLength(255) - ], - MESSAGES: { - 'minlength': $localize`Password must be at least 6 characters long.`, - 'maxlength': $localize`Password cannot be more than 255 characters long.` - } - } - - this.USER_CONFIRM_PASSWORD = { - VALIDATORS: [], - MESSAGES: { - 'matchPassword': $localize`The new password and the confirmed password do not correspond.` - } - } - - this.USER_VIDEO_QUOTA = { - VALIDATORS: [ Validators.required, Validators.min(-1) ], - MESSAGES: { - 'required': $localize`Video quota is required.`, - 'min': $localize`Quota must be greater than -1.` - } - } - this.USER_VIDEO_QUOTA_DAILY = { - VALIDATORS: [ Validators.required, Validators.min(-1) ], - MESSAGES: { - 'required': $localize`Daily upload limit is required.`, - 'min': $localize`Daily upload limit must be greater than -1.` - } - } - - this.USER_ROLE = { - VALIDATORS: [ Validators.required ], - MESSAGES: { - 'required': $localize`User role is required.` - } - } - - this.USER_DISPLAY_NAME_REQUIRED = this.getDisplayName(true) - - this.USER_DESCRIPTION = { - VALIDATORS: [ - Validators.minLength(3), - Validators.maxLength(1000) - ], - MESSAGES: { - 'minlength': $localize`Description must be at least 3 characters long.`, - 'maxlength': $localize`Description cannot be more than 1000 characters long.` - } - } - - this.USER_TERMS = { - VALIDATORS: [ - Validators.requiredTrue - ], - MESSAGES: { - 'required': $localize`You must agree with the instance terms in order to register on it.` - } - } - - this.USER_BAN_REASON = { - VALIDATORS: [ - Validators.minLength(3), - Validators.maxLength(250) - ], - MESSAGES: { - 'minlength': $localize`Ban reason must be at least 3 characters long.`, - 'maxlength': $localize`Ban reason cannot be more than 250 characters long.` - } - } - } - - private getDisplayName (required: boolean) { - const control = { - VALIDATORS: [ - Validators.minLength(1), - Validators.maxLength(120) - ], - MESSAGES: { - 'required': $localize`Display name is required.`, - 'minlength': $localize`Display name must be at least 1 character long.`, - 'maxlength': $localize`Display name cannot be more than 50 characters long.` - } - } - - if (required) control.VALIDATORS.push(Validators.required) - - return control - } -} diff --git a/client/src/app/shared/shared-forms/form-validators/video-accept-ownership-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-accept-ownership-validators.service.ts deleted file mode 100644 index aed9e9cdd..000000000 --- a/client/src/app/shared/shared-forms/form-validators/video-accept-ownership-validators.service.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Injectable } from '@angular/core' -import { Validators } from '@angular/forms' -import { BuildFormValidator } from './form-validator.service' - -@Injectable() -export class VideoAcceptOwnershipValidatorsService { - readonly CHANNEL: BuildFormValidator - - constructor () { - this.CHANNEL = { - VALIDATORS: [ Validators.required ], - MESSAGES: { - 'required': $localize`The channel is required.` - } - } - } -} diff --git a/client/src/app/shared/shared-forms/form-validators/video-block-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-block-validators.service.ts deleted file mode 100644 index bce1880dc..000000000 --- a/client/src/app/shared/shared-forms/form-validators/video-block-validators.service.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Injectable } from '@angular/core' -import { Validators } from '@angular/forms' -import { BuildFormValidator } from './form-validator.service' - -@Injectable() -export class VideoBlockValidatorsService { - readonly VIDEO_BLOCK_REASON: BuildFormValidator - - constructor () { - this.VIDEO_BLOCK_REASON = { - VALIDATORS: [ Validators.minLength(2), Validators.maxLength(300) ], - MESSAGES: { - 'minlength': $localize`Block reason must be at least 2 characters long.`, - 'maxlength': $localize`Block reason cannot be more than 300 characters long.` - } - } - } -} diff --git a/client/src/app/shared/shared-forms/form-validators/video-captions-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-captions-validators.service.ts deleted file mode 100644 index 7e90264e5..000000000 --- a/client/src/app/shared/shared-forms/form-validators/video-captions-validators.service.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Injectable } from '@angular/core' -import { Validators } from '@angular/forms' -import { BuildFormValidator } from './form-validator.service' - -@Injectable() -export class VideoCaptionsValidatorsService { - readonly VIDEO_CAPTION_LANGUAGE: BuildFormValidator - readonly VIDEO_CAPTION_FILE: BuildFormValidator - - constructor () { - - this.VIDEO_CAPTION_LANGUAGE = { - VALIDATORS: [ Validators.required ], - MESSAGES: { - 'required': $localize`Video caption language is required.` - } - } - - this.VIDEO_CAPTION_FILE = { - VALIDATORS: [ Validators.required ], - MESSAGES: { - 'required': $localize`Video caption file is required.` - } - } - } -} diff --git a/client/src/app/shared/shared-forms/form-validators/video-change-ownership-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-change-ownership-validators.service.ts deleted file mode 100644 index 8c809a0d5..000000000 --- a/client/src/app/shared/shared-forms/form-validators/video-change-ownership-validators.service.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Injectable } from '@angular/core' -import { AbstractControl, ValidationErrors, Validators } from '@angular/forms' -import { BuildFormValidator } from './form-validator.service' - -@Injectable() -export class VideoChangeOwnershipValidatorsService { - readonly USERNAME: BuildFormValidator - - constructor () { - this.USERNAME = { - VALIDATORS: [ Validators.required, this.localAccountValidator ], - MESSAGES: { - 'required': $localize`The username is required.`, - 'localAccountOnly': $localize`You can only transfer ownership to a local account` - } - } - } - - localAccountValidator (control: AbstractControl): ValidationErrors { - if (control.value.includes('@')) { - return { 'localAccountOnly': true } - } - - return null - } -} diff --git a/client/src/app/shared/shared-forms/form-validators/video-channel-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-channel-validators.service.ts deleted file mode 100644 index 3e7444196..000000000 --- a/client/src/app/shared/shared-forms/form-validators/video-channel-validators.service.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { Injectable } from '@angular/core' -import { Validators } from '@angular/forms' -import { BuildFormValidator } from './form-validator.service' - -@Injectable() -export class VideoChannelValidatorsService { - readonly VIDEO_CHANNEL_NAME: BuildFormValidator - readonly VIDEO_CHANNEL_DISPLAY_NAME: BuildFormValidator - readonly VIDEO_CHANNEL_DESCRIPTION: BuildFormValidator - readonly VIDEO_CHANNEL_SUPPORT: BuildFormValidator - - constructor () { - this.VIDEO_CHANNEL_NAME = { - VALIDATORS: [ - Validators.required, - Validators.minLength(1), - Validators.maxLength(50), - Validators.pattern(/^[a-z0-9][a-z0-9._]*$/) - ], - MESSAGES: { - 'required': $localize`Name is required.`, - 'minlength': $localize`Name must be at least 1 character long.`, - 'maxlength': $localize`Name cannot be more than 50 characters long.`, - 'pattern': $localize`Name should be lowercase alphanumeric; dots and underscores are allowed.` - } - } - - this.VIDEO_CHANNEL_DISPLAY_NAME = { - VALIDATORS: [ - Validators.required, - Validators.minLength(1), - Validators.maxLength(50) - ], - MESSAGES: { - 'required': $localize`Display name is required.`, - 'minlength': $localize`Display name must be at least 1 character long.`, - 'maxlength': $localize`Display name cannot be more than 50 characters long.` - } - } - - this.VIDEO_CHANNEL_DESCRIPTION = { - VALIDATORS: [ - Validators.minLength(3), - Validators.maxLength(1000) - ], - MESSAGES: { - 'minlength': $localize`Description must be at least 3 characters long.`, - 'maxlength': $localize`Description cannot be more than 1000 characters long.` - } - } - - this.VIDEO_CHANNEL_SUPPORT = { - VALIDATORS: [ - Validators.minLength(3), - Validators.maxLength(1000) - ], - MESSAGES: { - 'minlength': $localize`Support text must be at least 3 characters long.`, - 'maxlength': $localize`Support text cannot be more than 1000 characters long` - } - } - } -} diff --git a/client/src/app/shared/shared-forms/form-validators/video-comment-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-comment-validators.service.ts deleted file mode 100644 index 18e7ae264..000000000 --- a/client/src/app/shared/shared-forms/form-validators/video-comment-validators.service.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Injectable } from '@angular/core' -import { Validators } from '@angular/forms' -import { BuildFormValidator } from './form-validator.service' - -@Injectable() -export class VideoCommentValidatorsService { - readonly VIDEO_COMMENT_TEXT: BuildFormValidator - - constructor () { - this.VIDEO_COMMENT_TEXT = { - VALIDATORS: [ Validators.required, Validators.minLength(1), Validators.maxLength(3000) ], - MESSAGES: { - 'required': $localize`Comment is required.`, - 'minlength': $localize`Comment must be at least 2 characters long.`, - 'maxlength': $localize`Comment cannot be more than 3000 characters long.` - } - } - } -} diff --git a/client/src/app/shared/shared-forms/form-validators/video-playlist-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-playlist-validators.service.ts deleted file mode 100644 index 3b45a40fd..000000000 --- a/client/src/app/shared/shared-forms/form-validators/video-playlist-validators.service.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Injectable } from '@angular/core' -import { AbstractControl, Validators } from '@angular/forms' -import { VideoPlaylistPrivacy } from '@shared/models' -import { BuildFormValidator } from './form-validator.service' - -@Injectable() -export class VideoPlaylistValidatorsService { - readonly VIDEO_PLAYLIST_DISPLAY_NAME: BuildFormValidator - readonly VIDEO_PLAYLIST_PRIVACY: BuildFormValidator - readonly VIDEO_PLAYLIST_DESCRIPTION: BuildFormValidator - readonly VIDEO_PLAYLIST_CHANNEL_ID: BuildFormValidator - - constructor () { - this.VIDEO_PLAYLIST_DISPLAY_NAME = { - VALIDATORS: [ - Validators.required, - Validators.minLength(1), - Validators.maxLength(120) - ], - MESSAGES: { - 'required': $localize`Display name is required.`, - 'minlength': $localize`Display name must be at least 1 character long.`, - 'maxlength': $localize`Display name cannot be more than 120 characters long.` - } - } - - this.VIDEO_PLAYLIST_PRIVACY = { - VALIDATORS: [ - Validators.required - ], - MESSAGES: { - 'required': $localize`Privacy is required.` - } - } - - this.VIDEO_PLAYLIST_DESCRIPTION = { - VALIDATORS: [ - Validators.minLength(3), - Validators.maxLength(1000) - ], - MESSAGES: { - 'minlength': $localize`Description must be at least 3 characters long.`, - 'maxlength': $localize`Description cannot be more than 1000 characters long.` - } - } - - this.VIDEO_PLAYLIST_CHANNEL_ID = { - VALIDATORS: [ ], - MESSAGES: { - 'required': $localize`The channel is required when the playlist is public.` - } - } - } - - setChannelValidator (channelControl: AbstractControl, privacy: VideoPlaylistPrivacy) { - if (privacy.toString() === VideoPlaylistPrivacy.PUBLIC.toString()) { - channelControl.setValidators([ Validators.required ]) - } else { - channelControl.setValidators(null) - } - - channelControl.markAsDirty() - channelControl.updateValueAndValidity() - } -} diff --git a/client/src/app/shared/shared-forms/form-validators/video-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-validators.service.ts deleted file mode 100644 index 8119c1ae7..000000000 --- a/client/src/app/shared/shared-forms/form-validators/video-validators.service.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { Injectable } from '@angular/core' -import { AbstractControl, ValidationErrors, ValidatorFn, Validators } from '@angular/forms' -import { BuildFormValidator } from './form-validator.service' - -@Injectable() -export class VideoValidatorsService { - readonly VIDEO_NAME: BuildFormValidator - readonly VIDEO_PRIVACY: BuildFormValidator - readonly VIDEO_CATEGORY: BuildFormValidator - readonly VIDEO_LICENCE: BuildFormValidator - readonly VIDEO_LANGUAGE: BuildFormValidator - readonly VIDEO_IMAGE: BuildFormValidator - readonly VIDEO_CHANNEL: BuildFormValidator - readonly VIDEO_DESCRIPTION: BuildFormValidator - readonly VIDEO_TAGS_ARRAY: BuildFormValidator - readonly VIDEO_TAG: BuildFormValidator - readonly VIDEO_SUPPORT: BuildFormValidator - readonly VIDEO_SCHEDULE_PUBLICATION_AT: BuildFormValidator - readonly VIDEO_ORIGINALLY_PUBLISHED_AT: BuildFormValidator - - constructor () { - - this.VIDEO_NAME = { - VALIDATORS: [ Validators.required, Validators.minLength(3), Validators.maxLength(120) ], - MESSAGES: { - 'required': $localize`Video name is required.`, - 'minlength': $localize`Video name must be at least 3 characters long.`, - 'maxlength': $localize`Video name cannot be more than 120 characters long.` - } - } - - this.VIDEO_PRIVACY = { - VALIDATORS: [ Validators.required ], - MESSAGES: { - 'required': $localize`Video privacy is required.` - } - } - - this.VIDEO_CATEGORY = { - VALIDATORS: [ ], - MESSAGES: {} - } - - this.VIDEO_LICENCE = { - VALIDATORS: [ ], - MESSAGES: {} - } - - this.VIDEO_LANGUAGE = { - VALIDATORS: [ ], - MESSAGES: {} - } - - this.VIDEO_IMAGE = { - VALIDATORS: [ ], - MESSAGES: {} - } - - this.VIDEO_CHANNEL = { - VALIDATORS: [ Validators.required ], - MESSAGES: { - 'required': $localize`Video channel is required.` - } - } - - this.VIDEO_DESCRIPTION = { - VALIDATORS: [ Validators.minLength(3), Validators.maxLength(10000) ], - MESSAGES: { - 'minlength': $localize`Video description must be at least 3 characters long.`, - 'maxlength': $localize`Video description cannot be more than 10000 characters long.` - } - } - - this.VIDEO_TAG = { - VALIDATORS: [ Validators.minLength(2), Validators.maxLength(30) ], - MESSAGES: { - 'minlength': $localize`A tag should be more than 2 characters long.`, - 'maxlength': $localize`A tag should be less than 30 characters long.` - } - } - - this.VIDEO_TAGS_ARRAY = { - VALIDATORS: [ Validators.maxLength(5), this.arrayTagLengthValidator() ], - MESSAGES: { - 'maxlength': $localize`A maximum of 5 tags can be used on a video.`, - 'arrayTagLength': $localize`A tag should be more than 2, and less than 30 characters long.` - } - } - - this.VIDEO_SUPPORT = { - VALIDATORS: [ Validators.minLength(3), Validators.maxLength(1000) ], - MESSAGES: { - 'minlength': $localize`Video support must be at least 3 characters long.`, - 'maxlength': $localize`Video support cannot be more than 1000 characters long.` - } - } - - this.VIDEO_SCHEDULE_PUBLICATION_AT = { - VALIDATORS: [ ], - MESSAGES: { - 'required': $localize`A date is required to schedule video update.` - } - } - - this.VIDEO_ORIGINALLY_PUBLISHED_AT = { - VALIDATORS: [ ], - MESSAGES: {} - } - } - - arrayTagLengthValidator (min = 2, max = 30): ValidatorFn { - return (control: AbstractControl): ValidationErrors => { - const array = control.value as Array - - if (array.every(e => e.length > min && e.length < max)) { - return null - } - - return { 'arrayTagLength': true } - } - } -} diff --git a/client/src/app/shared/shared-forms/index.ts b/client/src/app/shared/shared-forms/index.ts index 747df65cf..b2c7fa9ba 100644 --- a/client/src/app/shared/shared-forms/index.ts +++ b/client/src/app/shared/shared-forms/index.ts @@ -1,4 +1,4 @@ -export * from './form-validators' +export * from './form-validator.service' export * from './form-reactive' export * from './select' export * from './input-readonly-copy.component' diff --git a/client/src/app/shared/shared-forms/shared-form.module.ts b/client/src/app/shared/shared-forms/shared-form.module.ts index 0e0ed5bab..1946ac21f 100644 --- a/client/src/app/shared/shared-forms/shared-form.module.ts +++ b/client/src/app/shared/shared-forms/shared-form.module.ts @@ -1,37 +1,20 @@ -import { NgModule } from '@angular/core' -import { FormsModule, ReactiveFormsModule } from '@angular/forms' import { InputMaskModule } from 'primeng/inputmask' import { InputSwitchModule } from 'primeng/inputswitch' +import { NgModule } from '@angular/core' +import { FormsModule, ReactiveFormsModule } from '@angular/forms' import { NgSelectModule } from '@ng-select/ng-select' -import { BatchDomainsValidatorsService } from '@app/shared/shared-forms/form-validators/batch-domains-validators.service' import { SharedGlobalIconModule } from '../shared-icons' import { SharedMainModule } from '../shared-main/shared-main.module' -import { - CustomConfigValidatorsService, - FormValidatorService, - InstanceValidatorsService, - LoginValidatorsService, - ResetPasswordValidatorsService, - UserValidatorsService, - AbuseValidatorsService, - VideoAcceptOwnershipValidatorsService, - VideoBlockValidatorsService, - VideoCaptionsValidatorsService, - VideoChangeOwnershipValidatorsService, - VideoChannelValidatorsService, - VideoCommentValidatorsService, - VideoPlaylistValidatorsService, - VideoValidatorsService -} from './form-validators' +import { FormValidatorService } from './form-validator.service' import { InputReadonlyCopyComponent } from './input-readonly-copy.component' import { MarkdownTextareaComponent } from './markdown-textarea.component' import { PeertubeCheckboxComponent } from './peertube-checkbox.component' import { PreviewUploadComponent } from './preview-upload.component' import { ReactiveFileComponent } from './reactive-file.component' +import { SelectChannelComponent, SelectCheckboxComponent, SelectOptionsComponent, SelectTagsComponent } from './select' import { TextareaAutoResizeDirective } from './textarea-autoresize.directive' import { TimestampInputComponent } from './timestamp-input.component' -import { SelectChannelComponent, SelectCheckboxComponent, SelectOptionsComponent, SelectTagsComponent } from './select' @NgModule({ imports: [ @@ -84,23 +67,7 @@ import { SelectChannelComponent, SelectCheckboxComponent, SelectOptionsComponent ], providers: [ - CustomConfigValidatorsService, - FormValidatorService, - LoginValidatorsService, - InstanceValidatorsService, - LoginValidatorsService, - ResetPasswordValidatorsService, - UserValidatorsService, - AbuseValidatorsService, - VideoAcceptOwnershipValidatorsService, - VideoBlockValidatorsService, - VideoCaptionsValidatorsService, - VideoChangeOwnershipValidatorsService, - VideoChannelValidatorsService, - VideoCommentValidatorsService, - VideoPlaylistValidatorsService, - VideoValidatorsService, - BatchDomainsValidatorsService + FormValidatorService ] }) export class SharedFormModule { } diff --git a/client/src/app/shared/shared-moderation/batch-domains-modal.component.ts b/client/src/app/shared/shared-moderation/batch-domains-modal.component.ts index 7193ccb1b..6edbb6023 100644 --- a/client/src/app/shared/shared-moderation/batch-domains-modal.component.ts +++ b/client/src/app/shared/shared-moderation/batch-domains-modal.component.ts @@ -1,7 +1,8 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' -import { BatchDomainsValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' +import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' +import { DOMAINS_VALIDATOR, getNotEmptyHosts } from '../form-validators/batch-domains-validators' @Component({ selector: 'my-batch-domains-modal', @@ -18,8 +19,7 @@ export class BatchDomainsModalComponent extends FormReactive implements OnInit { constructor ( protected formValidatorService: FormValidatorService, - private modalService: NgbModal, - private batchDomainsValidatorsService: BatchDomainsValidatorsService + private modalService: NgbModal ) { super() } @@ -28,7 +28,7 @@ export class BatchDomainsModalComponent extends FormReactive implements OnInit { if (!this.action) this.action = $localize`Process domains` this.buildForm({ - domains: this.batchDomainsValidatorsService.DOMAINS + domains: DOMAINS_VALIDATOR }) } @@ -42,7 +42,7 @@ export class BatchDomainsModalComponent extends FormReactive implements OnInit { submit () { this.domains.emit( - this.batchDomainsValidatorsService.getNotEmptyHosts(this.form.controls['domains'].value) + getNotEmptyHosts(this.form.controls['domains'].value) ) this.form.reset() this.hide() diff --git a/client/src/app/shared/shared-moderation/report-modals/account-report.component.ts b/client/src/app/shared/shared-moderation/report-modals/account-report.component.ts index 8ab2fe940..cc8875f77 100644 --- a/client/src/app/shared/shared-moderation/report-modals/account-report.component.ts +++ b/client/src/app/shared/shared-moderation/report-modals/account-report.component.ts @@ -1,7 +1,8 @@ import { mapValues, pickBy } from 'lodash-es' import { Component, Input, OnInit, ViewChild } from '@angular/core' import { Notifier } from '@app/core' -import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' +import { ABUSE_REASON_VALIDATOR } from '@app/shared/form-validators/abuse-validators' +import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { Account } from '@app/shared/shared-main' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' @@ -28,7 +29,6 @@ export class AccountReportComponent extends FormReactive implements OnInit { constructor ( protected formValidatorService: FormValidatorService, private modalService: NgbModal, - private abuseValidatorsService: AbuseValidatorsService, private abuseService: AbuseService, private notifier: Notifier ) { @@ -51,7 +51,7 @@ export class AccountReportComponent extends FormReactive implements OnInit { this.modalTitle = $localize`Report ${this.account.displayName}` this.buildForm({ - reason: this.abuseValidatorsService.ABUSE_REASON, + reason: ABUSE_REASON_VALIDATOR, predefinedReasons: mapValues(abusePredefinedReasonsMap, r => null) }) diff --git a/client/src/app/shared/shared-moderation/report-modals/comment-report.component.ts b/client/src/app/shared/shared-moderation/report-modals/comment-report.component.ts index d75f4d717..c7395c7b7 100644 --- a/client/src/app/shared/shared-moderation/report-modals/comment-report.component.ts +++ b/client/src/app/shared/shared-moderation/report-modals/comment-report.component.ts @@ -1,7 +1,8 @@ import { mapValues, pickBy } from 'lodash-es' import { Component, Input, OnInit, ViewChild } from '@angular/core' import { Notifier } from '@app/core' -import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' +import { ABUSE_REASON_VALIDATOR } from '@app/shared/form-validators/abuse-validators' +import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { VideoComment } from '@app/shared/shared-video-comment' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' @@ -28,7 +29,6 @@ export class CommentReportComponent extends FormReactive implements OnInit { constructor ( protected formValidatorService: FormValidatorService, private modalService: NgbModal, - private abuseValidatorsService: AbuseValidatorsService, private abuseService: AbuseService, private notifier: Notifier ) { @@ -51,7 +51,7 @@ export class CommentReportComponent extends FormReactive implements OnInit { this.modalTitle = $localize`Report comment` this.buildForm({ - reason: this.abuseValidatorsService.ABUSE_REASON, + reason: ABUSE_REASON_VALIDATOR, predefinedReasons: mapValues(abusePredefinedReasonsMap, r => null) }) diff --git a/client/src/app/shared/shared-moderation/report-modals/video-report.component.ts b/client/src/app/shared/shared-moderation/report-modals/video-report.component.ts index edff6d325..5b06c0bc7 100644 --- a/client/src/app/shared/shared-moderation/report-modals/video-report.component.ts +++ b/client/src/app/shared/shared-moderation/report-modals/video-report.component.ts @@ -3,7 +3,8 @@ import { buildVideoLink, buildVideoOrPlaylistEmbed } from 'src/assets/player/uti import { Component, Input, OnInit, ViewChild } from '@angular/core' import { DomSanitizer, SafeHtml } from '@angular/platform-browser' import { Notifier } from '@app/core' -import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' +import { ABUSE_REASON_VALIDATOR } from '@app/shared/form-validators/abuse-validators' +import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' import { abusePredefinedReasonsMap } from '@shared/core-utils/abuse' @@ -30,7 +31,6 @@ export class VideoReportComponent extends FormReactive implements OnInit { constructor ( protected formValidatorService: FormValidatorService, private modalService: NgbModal, - private abuseValidatorsService: AbuseValidatorsService, private abuseService: AbuseService, private notifier: Notifier, private sanitizer: DomSanitizer @@ -68,7 +68,7 @@ export class VideoReportComponent extends FormReactive implements OnInit { ngOnInit () { this.buildForm({ - reason: this.abuseValidatorsService.ABUSE_REASON, + reason: ABUSE_REASON_VALIDATOR, predefinedReasons: mapValues(abusePredefinedReasonsMap, r => null), timestamp: { hasStart: null, diff --git a/client/src/app/shared/shared-moderation/user-ban-modal.component.ts b/client/src/app/shared/shared-moderation/user-ban-modal.component.ts index f9a0381c5..afc69a1b8 100644 --- a/client/src/app/shared/shared-moderation/user-ban-modal.component.ts +++ b/client/src/app/shared/shared-moderation/user-ban-modal.component.ts @@ -1,9 +1,10 @@ import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core' import { Notifier, UserService } from '@app/core' -import { FormReactive, FormValidatorService, UserValidatorsService } from '@app/shared/shared-forms' +import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' import { User } from '@shared/models' +import { USER_BAN_REASON_VALIDATOR } from '../form-validators/user-validators' @Component({ selector: 'my-user-ban-modal', @@ -21,15 +22,14 @@ export class UserBanModalComponent extends FormReactive implements OnInit { protected formValidatorService: FormValidatorService, private modalService: NgbModal, private notifier: Notifier, - private userService: UserService, - private userValidatorsService: UserValidatorsService + private userService: UserService ) { super() } ngOnInit () { this.buildForm({ - reason: this.userValidatorsService.USER_BAN_REASON + reason: USER_BAN_REASON_VALIDATOR }) } diff --git a/client/src/app/shared/shared-moderation/video-block.component.ts b/client/src/app/shared/shared-moderation/video-block.component.ts index 2bef9efdd..fb47989dc 100644 --- a/client/src/app/shared/shared-moderation/video-block.component.ts +++ b/client/src/app/shared/shared-moderation/video-block.component.ts @@ -1,9 +1,10 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' import { Notifier } from '@app/core' -import { FormReactive, FormValidatorService, VideoBlockValidatorsService } from '@app/shared/shared-forms' +import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { Video } from '@app/shared/shared-main' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' +import { VIDEO_BLOCK_REASON_VALIDATOR } from '../form-validators/video-block-validators' import { VideoBlockService } from './video-block.service' @Component({ @@ -25,7 +26,6 @@ export class VideoBlockComponent extends FormReactive implements OnInit { constructor ( protected formValidatorService: FormValidatorService, private modalService: NgbModal, - private videoBlockValidatorsService: VideoBlockValidatorsService, private videoBlocklistService: VideoBlockService, private notifier: Notifier ) { @@ -36,7 +36,7 @@ export class VideoBlockComponent extends FormReactive implements OnInit { const defaultValues = { unfederate: 'true' } this.buildForm({ - reason: this.videoBlockValidatorsService.VIDEO_BLOCK_REASON, + reason: VIDEO_BLOCK_REASON_VALIDATOR, unfederate: null }, defaultValues) } diff --git a/client/src/app/shared/shared-user-subscription/remote-subscribe.component.ts b/client/src/app/shared/shared-user-subscription/remote-subscribe.component.ts index 286ecac02..b46c91bf8 100644 --- a/client/src/app/shared/shared-user-subscription/remote-subscribe.component.ts +++ b/client/src/app/shared/shared-user-subscription/remote-subscribe.component.ts @@ -1,5 +1,6 @@ import { Component, Input, OnInit } from '@angular/core' -import { FormReactive, FormValidatorService, UserValidatorsService } from '@app/shared/shared-forms' +import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' +import { USER_EMAIL_VALIDATOR } from '../form-validators/user-validators' @Component({ selector: 'my-remote-subscribe', @@ -12,15 +13,14 @@ export class RemoteSubscribeComponent extends FormReactive implements OnInit { @Input() showHelp = false constructor ( - protected formValidatorService: FormValidatorService, - private userValidatorsService: UserValidatorsService + protected formValidatorService: FormValidatorService ) { super() } ngOnInit () { this.buildForm({ - text: this.userValidatorsService.USER_EMAIL + text: USER_EMAIL_VALIDATOR }) } diff --git a/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts b/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts index 757ffa099..41f16e0bf 100644 --- a/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts +++ b/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts @@ -3,9 +3,10 @@ import { Subject, Subscription } from 'rxjs' import { debounceTime, filter } from 'rxjs/operators' import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core' import { AuthService, DisableForReuseHook, Notifier } from '@app/core' -import { FormReactive, FormValidatorService, VideoPlaylistValidatorsService } from '@app/shared/shared-forms' +import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { Video, VideoExistInPlaylist, VideoPlaylistCreate, VideoPlaylistElementCreate, VideoPlaylistPrivacy } from '@shared/models' import { secondsToTime } from '../../../assets/player/utils' +import { VIDEO_PLAYLIST_DISPLAY_NAME_VALIDATOR } from '../form-validators/video-playlist-validators' import { CachedPlaylist, VideoPlaylistService } from './video-playlist.service' const logger = debug('peertube:playlists:VideoAddToPlaylistComponent') @@ -53,7 +54,6 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, private authService: AuthService, private notifier: Notifier, private videoPlaylistService: VideoPlaylistService, - private videoPlaylistValidatorsService: VideoPlaylistValidatorsService, private cd: ChangeDetectorRef ) { super() @@ -65,7 +65,7 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, ngOnInit () { this.buildForm({ - displayName: this.videoPlaylistValidatorsService.VIDEO_PLAYLIST_DISPLAY_NAME + displayName: VIDEO_PLAYLIST_DISPLAY_NAME_VALIDATOR }) this.videoPlaylistService.listenToMyAccountPlaylistsChange() -- cgit v1.2.3