Skip to content

Commit c454cf9

Browse files
Kiliandecavlapo
authored andcommittedOct 28, 2019
feat: add isHash validator (#445)
1 parent 874861b commit c454cf9

File tree

5 files changed

+203
-0
lines changed

5 files changed

+203
-0
lines changed
 

‎README.md

+2
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,7 @@ validator.minLength(str, min); // Checks if the string's length is not less than
859859
validator.maxLength(str, max); // Checks if the string's length is not more than given number.
860860
validator.matches(str, pattern, modifiers); // Checks if string matches the pattern. Either matches('foo', /foo/i) or matches('foo', 'foo', 'i').
861861
validator.isMilitaryTime(str); // Checks if the string is a valid representation of military time in the format HH:MM.
862+
validator.isHash(algorithm: string); // Checks if the string is a hash of type algorithm.
862863
863864
// array validation methods
864865
validator.arrayContains(array, values); // Checks if array contains all values from the given array of values.
@@ -953,6 +954,7 @@ validator.isInstance(value, target); // Checks value is an instance of the targe
953954
| `@MaxLength(max: number)` | Checks if the string's length is not more than given number. |
954955
| `@Matches(pattern: RegExp, modifiers?: string)` | Checks if string matches the pattern. Either matches('foo', /foo/i) or matches('foo', 'foo', 'i').
955956
| `@IsMilitaryTime()` | Checks if the string is a valid representation of military time in the format HH:MM. |
957+
| `@IsHash(algorithm: string)` | Checkq if the string is a hash of type algorithm. <br/><br/>Algorithm is one of `['md4', 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128', 'tiger160', 'tiger192', 'crc32', 'crc32b']` |
956958
| **Array validation decorators** |
957959
| `@ArrayContains(values: any[])` | Checks if array contains all values from the given array of values. |
958960
| `@ArrayNotContains(values: any[])` | Checks if array does not contain any of the given values. |

‎src/decorator/decorators.ts

+17
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,23 @@ export function IsMilitaryTime(validationOptions?: ValidationOptions) {
12331233
};
12341234
}
12351235

1236+
/**
1237+
* Checks if the string is a mobile phone number (locale is one of ['zh-CN', 'zh-TW', 'en-ZA', 'en-AU', 'en-HK',
1238+
* 'pt-PT', 'fr-FR', 'el-GR', 'en-GB', 'en-US', 'en-ZM', 'ru-RU', 'nb-NO', 'nn-NO', 'vi-VN', 'en-NZ']).
1239+
*/
1240+
export function IsHash(algorithm: string, validationOptions?: ValidationOptions) {
1241+
return function (object: Object, propertyName: string) {
1242+
const args: ValidationMetadataArgs = {
1243+
type: ValidationTypes.IS_HASH,
1244+
target: object.constructor,
1245+
propertyName: propertyName,
1246+
constraints: [algorithm],
1247+
validationOptions: validationOptions
1248+
};
1249+
getFromContainer(MetadataStorage).addValidationMetadata(new ValidationMetadata(args));
1250+
};
1251+
}
1252+
12361253
// -------------------------------------------------------------------------
12371254
// Array checkers
12381255
// -------------------------------------------------------------------------

‎src/validation/ValidationTypes.ts

+3
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ export class ValidationTypes {
9292
static MAX_LENGTH = "maxLength";
9393
static MATCHES = "matches";
9494
static IS_MILITARY_TIME = "isMilitaryTime";
95+
static IS_HASH = "isHash";
9596

9697
/* array checkers */
9798
static ARRAY_CONTAINS = "arrayContains";
@@ -281,6 +282,8 @@ export class ValidationTypes {
281282
return eachPrefix + "$property must match $constraint1 regular expression";
282283
case this.IS_MILITARY_TIME:
283284
return eachPrefix + "$property must be a valid representation of military time in the format HH:MM";
285+
case this.IS_HASH:
286+
return eachPrefix + "$property must be a hash of type $constraint1";
284287

285288
/* array checkers */
286289
case this.ARRAY_CONTAINS:

‎src/validation/Validator.ts

+11
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@ export class Validator {
268268
return this.matches(value, metadata.constraints[0], metadata.constraints[1]);
269269
case ValidationTypes.IS_MILITARY_TIME:
270270
return this.isMilitaryTime(value);
271+
case ValidationTypes.IS_HASH:
272+
return this.isHash(value, metadata.constraints[0]);
271273

272274
/* array checkers */
273275
case ValidationTypes.ARRAY_CONTAINS:
@@ -866,6 +868,15 @@ export class Validator {
866868
return this.matches(value, /^([01]\d|2[0-3]):?([0-5]\d)$/);
867869
}
868870

871+
/**
872+
* check if the string is a hash of type algorithm.
873+
* Algorithm is one of ['md4', 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128',
874+
* 'tiger160', 'tiger192', 'crc32', 'crc32b']
875+
*/
876+
isHash(value: unknown, algorithm: ValidatorJS.HashAlgorithm): boolean {
877+
return typeof value === "string" && this.validatorJs.isHash(value, algorithm);
878+
}
879+
869880
// -------------------------------------------------------------------------
870881
// Validation Methods: array checkers
871882
// -------------------------------------------------------------------------

‎test/functional/validation-functions-and-decorators.spec.ts

+170
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ import {
7474
IsPhoneNumber,
7575
IsISO31661Alpha2,
7676
IsISO31661Alpha3,
77+
IsHash,
7778
} from "../../src/decorator/decorators";
7879
import {Validator} from "../../src/validation/Validator";
7980
import {ValidatorOptions} from "../../src/validation/ValidatorOptions";
@@ -3204,6 +3205,175 @@ describe("IsISO31661Alpha3", function() {
32043205

32053206
});
32063207

3208+
describe("isHash", function() {
3209+
3210+
function testHash(algorithm: ValidatorJS.HashAlgorithm, validValues: any[], invalidValues: any[]) {
3211+
3212+
class MyClass {
3213+
@IsHash(algorithm)
3214+
someProperty: string;
3215+
}
3216+
3217+
it("should not fail if validator.validate said that its valid", function(done) {
3218+
checkValidValues(new MyClass(), validValues, done);
3219+
});
3220+
3221+
it("should fail if validator.validate said that its invalid", function(done) {
3222+
checkInvalidValues(new MyClass(), invalidValues, done);
3223+
});
3224+
3225+
it("should not fail if method in validator said that its valid", function() {
3226+
validValues.forEach(value => validator.isHash(value, algorithm).should.be.true);
3227+
});
3228+
3229+
it("should fail if method in validator said that its invalid", function() {
3230+
invalidValues.forEach(value => validator.isHash(value, algorithm).should.be.false);
3231+
});
3232+
3233+
it("should return error object with proper data", function(done) {
3234+
const validationType = "isHash";
3235+
const message = `someProperty must be a hash of type ${algorithm}`;
3236+
checkReturnedError(new MyClass(), invalidValues, validationType, message, done);
3237+
});
3238+
}
3239+
3240+
["md5", "md4", "ripemd128", "tiger128"].forEach((algorithm: ValidatorJS.HashAlgorithm) => {
3241+
const validValues = [
3242+
"d94f3f016ae679c3008de268209132f2",
3243+
"751adbc511ccbe8edf23d486fa4581cd",
3244+
"88dae00e614d8f24cfd5a8b3f8002e93",
3245+
"0bf1c35032a71a14c2f719e5a14c1e96"
3246+
];
3247+
const invalidValues = [
3248+
undefined, null,
3249+
"q94375dj93458w34",
3250+
"39485729348",
3251+
"%&FHKJFvk",
3252+
"KYT0bf1c35032a71a14c2f719e5a1"
3253+
];
3254+
3255+
testHash(algorithm, validValues, invalidValues);
3256+
3257+
});
3258+
3259+
["crc32", "crc32b"].forEach((algorithm: ValidatorJS.HashAlgorithm) => {
3260+
const validValues = [
3261+
"d94f3f01",
3262+
"751adbc5",
3263+
"88dae00e",
3264+
"0bf1c350",
3265+
];
3266+
const invalidValues = [
3267+
undefined, null,
3268+
"KYT0bf1c35032a71a14c2f719e5a14c1",
3269+
"q94375dj93458w34",
3270+
"q943",
3271+
"39485729348",
3272+
"%&FHKJFvk",
3273+
];
3274+
3275+
testHash(algorithm, validValues, invalidValues);
3276+
});
3277+
3278+
["sha1", "tiger160", "ripemd160"].forEach((algorithm: ValidatorJS.HashAlgorithm) => {
3279+
const validValues = [
3280+
"3ca25ae354e192b26879f651a51d92aa8a34d8d3",
3281+
"aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d",
3282+
"beb8c3f30da46be179b8df5f5ecb5e4b10508230",
3283+
"efd5d3b190e893ed317f38da2420d63b7ae0d5ed",
3284+
];
3285+
const invalidValues = [
3286+
undefined, null,
3287+
"KYT0bf1c35032a71a14c2f719e5a14c1",
3288+
"KYT0bf1c35032a71a14c2f719e5a14c1dsjkjkjkjkkjk",
3289+
"q94375dj93458w34",
3290+
"39485729348",
3291+
"%&FHKJFvk",
3292+
];
3293+
3294+
testHash(algorithm, validValues, invalidValues);
3295+
});
3296+
3297+
["sha256"].forEach((algorithm: ValidatorJS.HashAlgorithm) => {
3298+
const validValues = [
3299+
"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824",
3300+
"1d996e033d612d9af2b44b70061ee0e868bfd14c2dd90b129e1edeb7953e7985",
3301+
"80f70bfeaed5886e33536bcfa8c05c60afef5a0e48f699a7912d5e399cdcc441",
3302+
"579282cfb65ca1f109b78536effaf621b853c9f7079664a3fbe2b519f435898c",
3303+
];
3304+
const invalidValues = [
3305+
undefined, null,
3306+
"KYT0bf1c35032a71a14c2f719e5a14c1",
3307+
"KYT0bf1c35032a71a14c2f719e5a14c1dsjkjkjkjkkjk",
3308+
"q94375dj93458w34",
3309+
"39485729348",
3310+
"%&FHKJFvk",
3311+
];
3312+
3313+
testHash(algorithm, validValues, invalidValues);
3314+
});
3315+
3316+
["sha384"].forEach((algorithm: ValidatorJS.HashAlgorithm) => {
3317+
const validValues = [
3318+
"3fed1f814d28dc5d63e313f8a601ecc4836d1662a19365cbdcf6870f6b56388850b58043f7ebf2418abb8f39c3a42e31",
3319+
"b330f4e575db6e73500bd3b805db1a84b5a034e5d21f0041d91eec85af1dfcb13e40bb1c4d36a72487e048ac6af74b58",
3320+
"bf547c3fc5841a377eb1519c2890344dbab15c40ae4150b4b34443d2212e5b04aa9d58865bf03d8ae27840fef430b891",
3321+
"fc09a3d11368386530f985dacddd026ae1e44e0e297c805c3429d50744e6237eb4417c20ffca8807b071823af13a3f65",
3322+
];
3323+
const invalidValues = [
3324+
undefined, null,
3325+
"KYT0bf1c35032a71a14c2f719e5a14c1",
3326+
"KYT0bf1c35032a71a14c2f719e5a14c1dsjkjkjkjkkjk",
3327+
"q94375dj93458w34",
3328+
"39485729348",
3329+
"%&FHKJFvk",
3330+
];
3331+
3332+
testHash(algorithm, validValues, invalidValues);
3333+
});
3334+
3335+
["sha512"].forEach((algorithm: ValidatorJS.HashAlgorithm) => {
3336+
const validValues = [
3337+
"9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043",
3338+
"83c586381bf5ba94c8d9ba8b6b92beb0997d76c257708742a6c26d1b7cbb9269af92d527419d5b8475f2bb6686d2f92a6649b7f174c1d8306eb335e585ab5049",
3339+
"45bc5fa8cb45ee408c04b6269e9f1e1c17090c5ce26ffeeda2af097735b29953ce547e40ff3ad0d120e5361cc5f9cee35ea91ecd4077f3f589b4d439168f91b9",
3340+
"432ac3d29e4f18c7f604f7c3c96369a6c5c61fc09bf77880548239baffd61636d42ed374f41c261e424d20d98e320e812a6d52865be059745fdb2cb20acff0ab",
3341+
];
3342+
const invalidValues = [
3343+
undefined, null,
3344+
"KYT0bf1c35032a71a14c2f719e5a14c1",
3345+
"KYT0bf1c35032a71a14c2f719e5a14c1dsjkjkjkjkkjk",
3346+
"q94375dj93458w34",
3347+
"39485729348",
3348+
"%&FHKJFvk",
3349+
];
3350+
3351+
testHash(algorithm, validValues, invalidValues);
3352+
});
3353+
3354+
["tiger192"].forEach((algorithm: ValidatorJS.HashAlgorithm) => {
3355+
const validValues = [
3356+
"6281a1f098c5e7290927ed09150d43ff3990a0fe1a48267c",
3357+
"56268f7bc269cf1bc83d3ce42e07a85632394737918f4760",
3358+
"46fc0125a148788a3ac1d649566fc04eb84a746f1a6e4fa7",
3359+
"7731ea1621ae99ea3197b94583d034fdbaa4dce31a67404a",
3360+
];
3361+
const invalidValues = [
3362+
undefined, null,
3363+
"KYT0bf1c35032a71a14c2f719e5a14c1",
3364+
"KYT0bf1c35032a71a14c2f719e5a14c1dsjkjkjkjkkjk",
3365+
"q94375dj93458w34",
3366+
"39485729348",
3367+
"%&FHKJFvk",
3368+
];
3369+
3370+
testHash(algorithm, validValues, invalidValues);
3371+
});
3372+
});
3373+
3374+
3375+
3376+
32073377

32083378
// -------------------------------------------------------------------------
32093379
// Specifications: array check

0 commit comments

Comments
 (0)