Merged PR 376: [Sp17完了MISO]バリデータをクラスを使用した記述に統一する
## 概要 [Task2502: [Sp17完了MISO]バリデータをクラスを使用した記述に統一する](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2502) バリデータの記述方法をクラスで外だしする形に統一しました。 また、未使用の引数を削除しました。 ## レビューポイント 期待通りの修正内容であるか。 未使用の引数を削除してしまったが、問題ないか。 ## UIの変更 なし ## 動作確認状況 ローカルで該当バリデーションを使用しているAPIを実行し、動作を確認済み ## 補足 なし
This commit is contained in:
parent
7a453c80f8
commit
f56f95123b
@ -8,8 +8,7 @@ import {
|
||||
|
||||
@ValidatorConstraint()
|
||||
export class IsUniqueArray implements ValidatorConstraintInterface {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
validate(arr: any[], args: ValidationArguments) {
|
||||
validate(arr: any[]) {
|
||||
return arr.length === new Set(arr).size;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,30 @@
|
||||
import { registerDecorator, ValidationOptions } from 'class-validator';
|
||||
import {
|
||||
registerDecorator,
|
||||
ValidationOptions,
|
||||
ValidatorConstraint,
|
||||
ValidatorConstraintInterface,
|
||||
} from 'class-validator';
|
||||
|
||||
@ValidatorConstraint()
|
||||
export class IsAdminPassword implements ValidatorConstraintInterface {
|
||||
validate(value: string): boolean {
|
||||
// 8文字~64文字でなければ早期に不合格
|
||||
const minLength = 8;
|
||||
const maxLength = 64;
|
||||
if (value.length < minLength || value.length > maxLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 英字の大文字、英字の小文字、アラビア数字、記号(@#$%^&*\-_+=[]{}|\:',.?/`~"();!)から2種類以上組み合わせ
|
||||
const charaTypePattern =
|
||||
/^((?=.*[a-z])(?=.*[A-Z])|(?=.*[a-z])(?=.*[\d])|(?=.*[a-z])(?=.*[@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!])|(?=.*[A-Z])(?=.*[\d])|(?=.*[A-Z])(?=.*[@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!])|(?=.*[\d])(?=.*[@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!]))[a-zA-Z\d@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!]/;
|
||||
return new RegExp(charaTypePattern).test(value);
|
||||
}
|
||||
defaultMessage(): string {
|
||||
return 'Admin password rule not satisfied';
|
||||
}
|
||||
}
|
||||
|
||||
// TODO タスク 2502: バリデータをクラスを使用した記述に統一するで修正する
|
||||
export const IsAdminPasswordvalid = (validationOptions?: ValidationOptions) => {
|
||||
return (object: any, propertyName: string) => {
|
||||
registerDecorator({
|
||||
@ -9,24 +33,7 @@ export const IsAdminPasswordvalid = (validationOptions?: ValidationOptions) => {
|
||||
propertyName: propertyName,
|
||||
constraints: [],
|
||||
options: validationOptions,
|
||||
validator: {
|
||||
validate: (value: string) => {
|
||||
// 8文字~64文字でなければ早期に不合格
|
||||
const minLength = 8;
|
||||
const maxLength = 64;
|
||||
if (value.length < minLength || value.length > maxLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 英字の大文字、英字の小文字、アラビア数字、記号(@#$%^&*\-_+=[]{}|\:',.?/`~"();!)から2種類以上組み合わせ
|
||||
const charaTypePattern =
|
||||
/^((?=.*[a-z])(?=.*[A-Z])|(?=.*[a-z])(?=.*[\d])|(?=.*[a-z])(?=.*[@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!])|(?=.*[A-Z])(?=.*[\d])|(?=.*[A-Z])(?=.*[@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!])|(?=.*[\d])(?=.*[@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!]))[a-zA-Z\d@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!]/;
|
||||
return new RegExp(charaTypePattern).test(value);
|
||||
},
|
||||
defaultMessage: () => {
|
||||
return 'Admin password rule not satisfied';
|
||||
},
|
||||
},
|
||||
validator: IsAdminPassword,
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,10 +1,33 @@
|
||||
import {
|
||||
registerDecorator,
|
||||
ValidationOptions,
|
||||
ValidationArguments,
|
||||
ValidatorConstraint,
|
||||
ValidatorConstraintInterface,
|
||||
} from 'class-validator';
|
||||
import { Assignee } from '../../features/tasks/types/types';
|
||||
// TODO タスク 2502: バリデータをクラスを使用した記述に統一するで修正する
|
||||
|
||||
@ValidatorConstraint()
|
||||
export class IsTypist implements ValidatorConstraintInterface {
|
||||
validate(values: Assignee[]): boolean {
|
||||
return values.every((value) => {
|
||||
const { typistUserId, typistGroupId, typistName } = value;
|
||||
if (typistUserId === undefined && typistGroupId === undefined) {
|
||||
return false;
|
||||
}
|
||||
if (typistUserId !== undefined && typistGroupId !== undefined) {
|
||||
return false;
|
||||
}
|
||||
if (!typistName) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
defaultMessage(): string {
|
||||
return 'Request body is invalid format';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validations options
|
||||
* @param [validationOptions]
|
||||
@ -17,28 +40,7 @@ export const IsAssignees = (validationOptions?: ValidationOptions) => {
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
options: validationOptions,
|
||||
validator: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
validate: (values: Assignee[], args: ValidationArguments) => {
|
||||
return values.every((value) => {
|
||||
const { typistUserId, typistGroupId, typistName } = value;
|
||||
if (typistUserId === undefined && typistGroupId === undefined) {
|
||||
return false;
|
||||
}
|
||||
if (typistUserId !== undefined && typistGroupId !== undefined) {
|
||||
return false;
|
||||
}
|
||||
if (!typistName) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
defaultMessage: (args?: ValidationArguments): string => {
|
||||
return 'Request body is invalid format';
|
||||
},
|
||||
},
|
||||
validator: IsTypist,
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,9 +2,46 @@ import {
|
||||
registerDecorator,
|
||||
ValidationArguments,
|
||||
ValidationOptions,
|
||||
ValidatorConstraint,
|
||||
ValidatorConstraintInterface,
|
||||
} from 'class-validator';
|
||||
import { SignupRequest } from '../../features/users/types/types';
|
||||
// TODO タスク 2502: バリデータをクラスを使用した記述に統一するで修正する
|
||||
|
||||
@ValidatorConstraint()
|
||||
export class IsPassword implements ValidatorConstraintInterface {
|
||||
validate(value: string | undefined): boolean {
|
||||
// passwordが設定されていない場合はチェックしない
|
||||
if (value === undefined) {
|
||||
return true;
|
||||
}
|
||||
// 正規表現でパスワードのチェックを行う
|
||||
// 4~16文字の半角英数字と記号のみ
|
||||
const regex = /^[!-~]{4,16}$/;
|
||||
if (!regex.test(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
defaultMessage(): string {
|
||||
return 'EncryptionPassword rule not satisfied';
|
||||
}
|
||||
}
|
||||
|
||||
@ValidatorConstraint()
|
||||
export class IsEncryptionPassword implements ValidatorConstraintInterface {
|
||||
validate(value: string | undefined, args: ValidationArguments): boolean {
|
||||
const { encryption } = args.object as SignupRequest;
|
||||
if (encryption === true && !value) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
defaultMessage(): string {
|
||||
return 'Encryption password is required when encryption is enabled';
|
||||
}
|
||||
}
|
||||
|
||||
export const IsPasswordvalid = (validationOptions?: ValidationOptions) => {
|
||||
return (object: any, propertyName: string) => {
|
||||
registerDecorator({
|
||||
@ -13,29 +50,10 @@ export const IsPasswordvalid = (validationOptions?: ValidationOptions) => {
|
||||
propertyName: propertyName,
|
||||
constraints: [],
|
||||
options: validationOptions,
|
||||
validator: {
|
||||
validate: (value: string | undefined) => {
|
||||
// passwordが設定されていない場合はチェックしない
|
||||
if (value === undefined) {
|
||||
return true;
|
||||
}
|
||||
// 正規表現でパスワードのチェックを行う
|
||||
// 4~16文字の半角英数字と記号のみ
|
||||
const regex = /^[!-~]{4,16}$/;
|
||||
if (!regex.test(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
defaultMessage: () => {
|
||||
return 'EncryptionPassword rule not satisfied';
|
||||
},
|
||||
},
|
||||
validator: IsPassword,
|
||||
});
|
||||
};
|
||||
};
|
||||
// TODO タスク 2502: バリデータをクラスを使用した記述に統一するで修正する
|
||||
export const IsEncryptionPasswordPresent = (
|
||||
validationOptions?: ValidationOptions,
|
||||
) => {
|
||||
@ -46,18 +64,7 @@ export const IsEncryptionPasswordPresent = (
|
||||
propertyName: propertyName,
|
||||
constraints: [],
|
||||
options: validationOptions,
|
||||
validator: {
|
||||
validate: (value: string | undefined, args: ValidationArguments) => {
|
||||
const { encryption } = args.object as SignupRequest;
|
||||
if (encryption === true && !value) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
defaultMessage: () => {
|
||||
return 'Encryption password is required when encryption is enabled';
|
||||
},
|
||||
},
|
||||
validator: IsEncryptionPassword,
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,6 +2,8 @@ import {
|
||||
registerDecorator,
|
||||
ValidationArguments,
|
||||
ValidationOptions,
|
||||
ValidatorConstraint,
|
||||
ValidatorConstraintInterface,
|
||||
} from 'class-validator';
|
||||
import {
|
||||
PostUpdateUserRequest,
|
||||
@ -9,7 +11,26 @@ import {
|
||||
} from '../../features/users/types/types';
|
||||
import { USER_ROLES } from '../../constants';
|
||||
|
||||
// TODO タスク 2502: バリデータをクラスを使用した記述に統一するで修正する
|
||||
@ValidatorConstraint()
|
||||
export class IsRoleAuthorData implements ValidatorConstraintInterface {
|
||||
propertyName: string;
|
||||
constructor(propertyName: string) {
|
||||
this.propertyName = propertyName;
|
||||
}
|
||||
|
||||
validate(value: any, args: ValidationArguments): boolean {
|
||||
const request = args.object as SignupRequest | PostUpdateUserRequest;
|
||||
const { role } = request;
|
||||
if (role === USER_ROLES.AUTHOR && value === undefined) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
defaultMessage(): string {
|
||||
return `When role is author, ${this.propertyName} cannot be undefined`;
|
||||
}
|
||||
}
|
||||
|
||||
export const IsRoleAuthorDataValid = <
|
||||
T extends SignupRequest | PostUpdateUserRequest,
|
||||
>(
|
||||
@ -22,19 +43,7 @@ export const IsRoleAuthorDataValid = <
|
||||
propertyName: propertyName,
|
||||
constraints: [],
|
||||
options: validationOptions,
|
||||
validator: {
|
||||
validate: (value: any, args: ValidationArguments) => {
|
||||
const request = args.object as T;
|
||||
const { role } = request;
|
||||
if (role === USER_ROLES.AUTHOR && value === undefined) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
defaultMessage: () => {
|
||||
return `When role is author, ${propertyName} cannot be undefined`;
|
||||
},
|
||||
},
|
||||
validator: new IsRoleAuthorData(propertyName),
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
@ -10,8 +10,7 @@ import { TASK_STATUS } from '../../constants';
|
||||
@ValidatorConstraint()
|
||||
export class IsStatusConstraint implements ValidatorConstraintInterface {
|
||||
private readonly STATUS: string[] = Object.values(TASK_STATUS);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
validate(value: string, args: ValidationArguments): boolean {
|
||||
validate(value: string): boolean {
|
||||
if (value) {
|
||||
// ,で分割した文字列のすべてがTASK_STATUSのプロパティに存在する値であった場合のみtrue
|
||||
return value.split(',').every((state) => this.STATUS.includes(state));
|
||||
@ -20,8 +19,7 @@ export class IsStatusConstraint implements ValidatorConstraintInterface {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
defaultMessage(validationArguments?: ValidationArguments): string {
|
||||
defaultMessage(): string {
|
||||
return `invalid status string`;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user