Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add isHash validator #445

Merged
merged 1 commit into from Oct 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -858,6 +858,7 @@ validator.minLength(str, min); // Checks if the string's length is not less than
validator.maxLength(str, max); // Checks if the string's length is not more than given number.
validator.matches(str, pattern, modifiers); // Checks if string matches the pattern. Either matches('foo', /foo/i) or matches('foo', 'foo', 'i').
validator.isMilitaryTime(str); // Checks if the string is a valid representation of military time in the format HH:MM.
validator.isHash(algorithm: string); // Checks if the string is a hash of type algorithm.

// array validation methods
validator.arrayContains(array, values); // Checks if array contains all values from the given array of values.
Expand Down Expand Up @@ -951,6 +952,7 @@ validator.isInstance(value, target); // Checks value is an instance of the targe
| `@MaxLength(max: number)` | Checks if the string's length is not more than given number. |
| `@Matches(pattern: RegExp, modifiers?: string)` | Checks if string matches the pattern. Either matches('foo', /foo/i) or matches('foo', 'foo', 'i').
| `@IsMilitaryTime()` | Checks if the string is a valid representation of military time in the format HH:MM. |
| `@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']` |
| **Array validation decorators** |
| `@ArrayContains(values: any[])` | Checks if array contains all values from the given array of values. |
| `@ArrayNotContains(values: any[])` | Checks if array does not contain any of the given values. |
Expand Down
17 changes: 17 additions & 0 deletions src/decorator/decorators.ts
Expand Up @@ -1218,6 +1218,23 @@ export function IsMilitaryTime(validationOptions?: ValidationOptions) {
};
}

/**
* Checks if the string is a mobile phone number (locale is one of ['zh-CN', 'zh-TW', 'en-ZA', 'en-AU', 'en-HK',
* 'pt-PT', 'fr-FR', 'el-GR', 'en-GB', 'en-US', 'en-ZM', 'ru-RU', 'nb-NO', 'nn-NO', 'vi-VN', 'en-NZ']).
*/
export function IsHash(algorithm: string, validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
const args: ValidationMetadataArgs = {
type: ValidationTypes.IS_HASH,
target: object.constructor,
propertyName: propertyName,
constraints: [algorithm],
validationOptions: validationOptions
};
getFromContainer(MetadataStorage).addValidationMetadata(new ValidationMetadata(args));
};
}

// -------------------------------------------------------------------------
// Array checkers
// -------------------------------------------------------------------------
Expand Down
3 changes: 3 additions & 0 deletions src/validation/ValidationTypes.ts
Expand Up @@ -91,6 +91,7 @@ export class ValidationTypes {
static MAX_LENGTH = "maxLength";
static MATCHES = "matches";
static IS_MILITARY_TIME = "isMilitaryTime";
static IS_HASH = "isHash";

/* array checkers */
static ARRAY_CONTAINS = "arrayContains";
Expand Down Expand Up @@ -278,6 +279,8 @@ export class ValidationTypes {
return eachPrefix + "$property must match $constraint1 regular expression";
case this.IS_MILITARY_TIME:
return eachPrefix + "$property must be a valid representation of military time in the format HH:MM";
case this.IS_HASH:
return eachPrefix + "$property must be a hash of type $constraint1";

/* array checkers */
case this.ARRAY_CONTAINS:
Expand Down
11 changes: 11 additions & 0 deletions src/validation/Validator.ts
Expand Up @@ -266,6 +266,8 @@ export class Validator {
return this.matches(value, metadata.constraints[0], metadata.constraints[1]);
case ValidationTypes.IS_MILITARY_TIME:
return this.isMilitaryTime(value);
case ValidationTypes.IS_HASH:
return this.isHash(value, metadata.constraints[0]);

/* array checkers */
case ValidationTypes.ARRAY_CONTAINS:
Expand Down Expand Up @@ -856,6 +858,15 @@ export class Validator {
return this.matches(value, /^([01]\d|2[0-3]):?([0-5]\d)$/);
}

/**
* check if the string is a hash of type algorithm.
* Algorithm is one of ['md4', 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128',
* 'tiger160', 'tiger192', 'crc32', 'crc32b']
*/
isHash(value: unknown, algorithm: ValidatorJS.HashAlgorithm): boolean {
return typeof value === "string" && this.validatorJs.isHash(value, algorithm);
}

// -------------------------------------------------------------------------
// Validation Methods: array checkers
// -------------------------------------------------------------------------
Expand Down
170 changes: 170 additions & 0 deletions test/functional/validation-functions-and-decorators.spec.ts
Expand Up @@ -73,6 +73,7 @@ import {
IsPhoneNumber,
IsISO31661Alpha2,
IsISO31661Alpha3,
IsHash,
} from "../../src/decorator/decorators";
import {Validator} from "../../src/validation/Validator";
import {ValidatorOptions} from "../../src/validation/ValidatorOptions";
Expand Down Expand Up @@ -3159,6 +3160,175 @@ describe("IsISO31661Alpha3", function() {

});

describe("isHash", function() {

function testHash(algorithm: ValidatorJS.HashAlgorithm, validValues: any[], invalidValues: any[]) {

class MyClass {
@IsHash(algorithm)
someProperty: string;
}

it("should not fail if validator.validate said that its valid", function(done) {
checkValidValues(new MyClass(), validValues, done);
});

it("should fail if validator.validate said that its invalid", function(done) {
checkInvalidValues(new MyClass(), invalidValues, done);
});

it("should not fail if method in validator said that its valid", function() {
validValues.forEach(value => validator.isHash(value, algorithm).should.be.true);
});

it("should fail if method in validator said that its invalid", function() {
invalidValues.forEach(value => validator.isHash(value, algorithm).should.be.false);
});

it("should return error object with proper data", function(done) {
const validationType = "isHash";
const message = `someProperty must be a hash of type ${algorithm}`;
checkReturnedError(new MyClass(), invalidValues, validationType, message, done);
});
}

["md5", "md4", "ripemd128", "tiger128"].forEach((algorithm: ValidatorJS.HashAlgorithm) => {
const validValues = [
"d94f3f016ae679c3008de268209132f2",
"751adbc511ccbe8edf23d486fa4581cd",
"88dae00e614d8f24cfd5a8b3f8002e93",
"0bf1c35032a71a14c2f719e5a14c1e96"
];
const invalidValues = [
undefined, null,
"q94375dj93458w34",
"39485729348",
"%&FHKJFvk",
"KYT0bf1c35032a71a14c2f719e5a1"
];

testHash(algorithm, validValues, invalidValues);

});

["crc32", "crc32b"].forEach((algorithm: ValidatorJS.HashAlgorithm) => {
const validValues = [
"d94f3f01",
"751adbc5",
"88dae00e",
"0bf1c350",
];
const invalidValues = [
undefined, null,
"KYT0bf1c35032a71a14c2f719e5a14c1",
"q94375dj93458w34",
"q943",
"39485729348",
"%&FHKJFvk",
];

testHash(algorithm, validValues, invalidValues);
});

["sha1", "tiger160", "ripemd160"].forEach((algorithm: ValidatorJS.HashAlgorithm) => {
const validValues = [
"3ca25ae354e192b26879f651a51d92aa8a34d8d3",
"aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d",
"beb8c3f30da46be179b8df5f5ecb5e4b10508230",
"efd5d3b190e893ed317f38da2420d63b7ae0d5ed",
];
const invalidValues = [
undefined, null,
"KYT0bf1c35032a71a14c2f719e5a14c1",
"KYT0bf1c35032a71a14c2f719e5a14c1dsjkjkjkjkkjk",
"q94375dj93458w34",
"39485729348",
"%&FHKJFvk",
];

testHash(algorithm, validValues, invalidValues);
});

["sha256"].forEach((algorithm: ValidatorJS.HashAlgorithm) => {
const validValues = [
"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824",
"1d996e033d612d9af2b44b70061ee0e868bfd14c2dd90b129e1edeb7953e7985",
"80f70bfeaed5886e33536bcfa8c05c60afef5a0e48f699a7912d5e399cdcc441",
"579282cfb65ca1f109b78536effaf621b853c9f7079664a3fbe2b519f435898c",
];
const invalidValues = [
undefined, null,
"KYT0bf1c35032a71a14c2f719e5a14c1",
"KYT0bf1c35032a71a14c2f719e5a14c1dsjkjkjkjkkjk",
"q94375dj93458w34",
"39485729348",
"%&FHKJFvk",
];

testHash(algorithm, validValues, invalidValues);
});

["sha384"].forEach((algorithm: ValidatorJS.HashAlgorithm) => {
const validValues = [
"3fed1f814d28dc5d63e313f8a601ecc4836d1662a19365cbdcf6870f6b56388850b58043f7ebf2418abb8f39c3a42e31",
"b330f4e575db6e73500bd3b805db1a84b5a034e5d21f0041d91eec85af1dfcb13e40bb1c4d36a72487e048ac6af74b58",
"bf547c3fc5841a377eb1519c2890344dbab15c40ae4150b4b34443d2212e5b04aa9d58865bf03d8ae27840fef430b891",
"fc09a3d11368386530f985dacddd026ae1e44e0e297c805c3429d50744e6237eb4417c20ffca8807b071823af13a3f65",
];
const invalidValues = [
undefined, null,
"KYT0bf1c35032a71a14c2f719e5a14c1",
"KYT0bf1c35032a71a14c2f719e5a14c1dsjkjkjkjkkjk",
"q94375dj93458w34",
"39485729348",
"%&FHKJFvk",
];

testHash(algorithm, validValues, invalidValues);
});

["sha512"].forEach((algorithm: ValidatorJS.HashAlgorithm) => {
const validValues = [
"9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043",
"83c586381bf5ba94c8d9ba8b6b92beb0997d76c257708742a6c26d1b7cbb9269af92d527419d5b8475f2bb6686d2f92a6649b7f174c1d8306eb335e585ab5049",
"45bc5fa8cb45ee408c04b6269e9f1e1c17090c5ce26ffeeda2af097735b29953ce547e40ff3ad0d120e5361cc5f9cee35ea91ecd4077f3f589b4d439168f91b9",
"432ac3d29e4f18c7f604f7c3c96369a6c5c61fc09bf77880548239baffd61636d42ed374f41c261e424d20d98e320e812a6d52865be059745fdb2cb20acff0ab",
];
const invalidValues = [
undefined, null,
"KYT0bf1c35032a71a14c2f719e5a14c1",
"KYT0bf1c35032a71a14c2f719e5a14c1dsjkjkjkjkkjk",
"q94375dj93458w34",
"39485729348",
"%&FHKJFvk",
];

testHash(algorithm, validValues, invalidValues);
});

["tiger192"].forEach((algorithm: ValidatorJS.HashAlgorithm) => {
const validValues = [
"6281a1f098c5e7290927ed09150d43ff3990a0fe1a48267c",
"56268f7bc269cf1bc83d3ce42e07a85632394737918f4760",
"46fc0125a148788a3ac1d649566fc04eb84a746f1a6e4fa7",
"7731ea1621ae99ea3197b94583d034fdbaa4dce31a67404a",
];
const invalidValues = [
undefined, null,
"KYT0bf1c35032a71a14c2f719e5a14c1",
"KYT0bf1c35032a71a14c2f719e5a14c1dsjkjkjkjkkjk",
"q94375dj93458w34",
"39485729348",
"%&FHKJFvk",
];

testHash(algorithm, validValues, invalidValues);
});
});





// -------------------------------------------------------------------------
// Specifications: array check
Expand Down