From b76d131fb7f9b0aca6a2556461179997cfce543c Mon Sep 17 00:00:00 2001 From: Edilson da Silva Date: Wed, 14 Jun 2023 17:32:35 -0300 Subject: [PATCH 1/4] add white and blacklist options to the isIBAN validator --- README.md | 2 +- src/lib/isIBAN.js | 50 +++++++++++++++++++++++++++++++--- test/validators.test.js | 59 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2a34bc719..e8f5b195e 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ Validator | Description **isHexadecimal(str)** | check if the string is a hexadecimal number. **isHexColor(str)** | check if the string is a hexadecimal color. **isHSL(str)** | check if the string is an HSL (hue, saturation, lightness, optional alpha) color based on [CSS Colors Level 4 specification][CSS Colors Level 4 Specification].

Comma-separated format supported. Space-separated format supported with the exception of a few edge cases (ex: `hsl(200grad+.1%62%/1)`). -**isIBAN(str)** | check if the string is an IBAN (International Bank Account Number). +**isIBAN(str)** | check if the string is an IBAN (International Bank Account Number).

Also allows you to define a whitelist, when you only want to recieve IBAN codes from certain countries or a blacklist, removing some of them from the current list. **isIdentityCard(str [, locale])** | check if the string is a valid identity card code.

`locale` is one of `['LK', 'PL', 'ES', 'FI', 'IN', 'IT', 'IR', 'MZ', 'NO', 'TH', 'zh-TW', 'he-IL', 'ar-LY', 'ar-TN', 'zh-CN', 'zh-HK']` OR `'any'`. If 'any' is used, function will check if any of the locales match.

Defaults to 'any'. **isIMEI(str [, options]))** | check if the string is a valid [IMEI number][IMEI]. IMEI should be of format `###############` or `##-######-######-#`.

`options` is an object which can contain the keys `allow_hyphens`. Defaults to first format. If `allow_hyphens` is set to true, the validator will validate the second format. **isIn(str, values)** | check if the string is in an array of allowed values. diff --git a/src/lib/isIBAN.js b/src/lib/isIBAN.js index 535a95772..7f6d63238 100644 --- a/src/lib/isIBAN.js +++ b/src/lib/isIBAN.js @@ -86,6 +86,25 @@ const ibanRegexThroughCountryCode = { XK: /^(XK[0-9]{2})\d{16}$/, }; +/** + * Check if the country codes passed are valid using the + * ibanRegexThroughCountryCode as a reference + * + * @param {array} countryCodeArray + * @return {boolean} + */ + +function hasOnlyValidCountryCodes(countryCodeArray) { + const countryCodeArrayFilteredWithObjectIbanCode = countryCodeArray + .filter(countryCode => !(countryCode in ibanRegexThroughCountryCode)); + + if (countryCodeArrayFilteredWithObjectIbanCode.length > 0) { + return false; + } + + return true; +} + /** * Check whether string has correct universal IBAN format * The IBAN consists of up to 34 alphanumeric characters, as follows: @@ -95,14 +114,37 @@ const ibanRegexThroughCountryCode = { * NOTE: Permitted IBAN characters are: digits [0-9] and the 26 latin alphabetic [A-Z] * * @param {string} str - string under validation + * @param {object} options - object to pass the countries to be either whitelisted or blacklisted * @return {boolean} */ -function hasValidIbanFormat(str) { +function hasValidIbanFormat(str, options) { // Strip white spaces and hyphens const strippedStr = str.replace(/[\s\-]+/gi, '').toUpperCase(); const isoCountryCode = strippedStr.slice(0, 2).toUpperCase(); - return (isoCountryCode in ibanRegexThroughCountryCode) && + const isoCountryCodeInIbanRegexCodeObject = isoCountryCode in ibanRegexThroughCountryCode; + + if (options.whitelist) { + if (!hasOnlyValidCountryCodes(options.whitelist)) { + throw new Error('One of the codes passed is invalid'); + } + + const isoCountryCodeInWhiteList = options.whitelist.includes(isoCountryCode); + + if (!isoCountryCodeInWhiteList) { + throw new Error('IBAN code does not belong to one of the countries listed on whitelist!'); + } + } + + if (options.blacklist) { + const isoCountryCodeInBlackList = options.blacklist.includes(isoCountryCode); + + if (isoCountryCodeInBlackList) { + throw new Error('IBAN code belongs to one of the countries listed on blacklist!'); + } + } + + return (isoCountryCodeInIbanRegexCodeObject) && ibanRegexThroughCountryCode[isoCountryCode].test(strippedStr); } @@ -130,10 +172,10 @@ function hasValidIbanChecksum(str) { return remainder === 1; } -export default function isIBAN(str) { +export default function isIBAN(str, options = {}) { assertString(str); - return hasValidIbanFormat(str) && hasValidIbanChecksum(str); + return hasValidIbanFormat(str, options) && hasValidIbanChecksum(str); } export const locales = Object.keys(ibanRegexThroughCountryCode); diff --git a/test/validators.test.js b/test/validators.test.js index d0753def8..ad4735b12 100644 --- a/test/validators.test.js +++ b/test/validators.test.js @@ -5250,6 +5250,65 @@ describe('Validators', () => { 'FR763000600001123456!!๐Ÿคจ7890189@', ], }); + test({ + validator: 'isIBAN', + args: [{ whitelist: ['DK', 'GB'] }], + valid: [ + 'DK5000400440116243', + 'GB29NWBK60161331926819', + ], + error: [ + 'BE71 0961 2345 6769', + 'FR76 3000 6000 0112 3456 7890 189', + 'DE91 1000 0000 0123 4567 89', + 'GR96 0810 0010 0000 0123 4567 890', + 'RO09 BCYP 0000 0012 3456 7890', + 'SA44 2000 0001 2345 6789 1234', + 'ES79 2100 0813 6101 2345 6789', + 'XX22YYY1234567890123', + 'FR14 2004 1010 0505 0001 3', + 'FR7630006000011234567890189@', + 'FR7630006000011234567890189๐Ÿ˜…', + 'FR763000600001123456!!๐Ÿคจ7890189@', + ], + }); + test({ + validator: 'isIBAN', + args: [{ blacklist: ['IT'] }], + valid: [ + 'SC52BAHL01031234567890123456USD', + 'LC14BOSL123456789012345678901234', + 'MT31MALT01100000000000000000123', + 'SV43ACAT00000000000000123123', + 'EG800002000156789012345180002', + 'BE71 0961 2345 6769', + 'FR76 3000 6000 0112 3456 7890 189', + 'DE91 1000 0000 0123 4567 89', + 'GR96 0810 0010 0000 0123 4567 890', + 'RO09 BCYP 0000 0012 3456 7890', + 'SA44 2000 0001 2345 6789 1234', + 'ES79 2100 0813 6101 2345 6789', + 'CH56 0483 5012 3456 7800 9', + 'GB98 MIDL 0700 9312 3456 78', + 'IL170108000000012612345', + 'JO71CBJO0000000000001234567890', + 'TR320010009999901234567890', + 'BR1500000000000010932840814P2', + 'LB92000700000000123123456123', + 'IR200170000000339545727003', + 'MZ97123412341234123412341', + ], + error: [ + 'IT60X0542811101000000123456', + ], + invalid: [ + 'XX22YYY1234567890123', + 'FR14 2004 1010 0505 0001 3', + 'FR7630006000011234567890189@', + 'FR7630006000011234567890189๐Ÿ˜…', + 'FR763000600001123456!!๐Ÿคจ7890189@', + ], + }); }); it('should validate BIC codes', () => { From 53ecf0be6094c8d5fc40c15270b480718ff6025c Mon Sep 17 00:00:00 2001 From: Edilson da Silva Date: Wed, 14 Jun 2023 18:14:32 -0300 Subject: [PATCH 2/4] improve coverage for isIBAN validator --- test/validators.test.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/validators.test.js b/test/validators.test.js index ad4735b12..0e31914a0 100644 --- a/test/validators.test.js +++ b/test/validators.test.js @@ -5272,6 +5272,26 @@ describe('Validators', () => { 'FR763000600001123456!!๐Ÿคจ7890189@', ], }); + test({ + validator: 'isIBAN', + args: [{ whitelist: ['XX', 'AA'] }], + error: [ + 'DK5000400440116243', + 'GB29NWBK60161331926819', + 'BE71 0961 2345 6769', + 'FR76 3000 6000 0112 3456 7890 189', + 'DE91 1000 0000 0123 4567 89', + 'GR96 0810 0010 0000 0123 4567 890', + 'RO09 BCYP 0000 0012 3456 7890', + 'SA44 2000 0001 2345 6789 1234', + 'ES79 2100 0813 6101 2345 6789', + 'XX22YYY1234567890123', + 'FR14 2004 1010 0505 0001 3', + 'FR7630006000011234567890189@', + 'FR7630006000011234567890189๐Ÿ˜…', + 'FR763000600001123456!!๐Ÿคจ7890189@', + ], + }); test({ validator: 'isIBAN', args: [{ blacklist: ['IT'] }], From e81e6d7c446484756b19a00aa7f298c7c751fd03 Mon Sep 17 00:00:00 2001 From: edilson Date: Wed, 21 Jun 2023 12:08:19 -0300 Subject: [PATCH 3/4] docs: add an explanation for the options object in the isIBAN validator without formatting it --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e8f5b195e..bb3163099 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ Validator | Description **isHexadecimal(str)** | check if the string is a hexadecimal number. **isHexColor(str)** | check if the string is a hexadecimal color. **isHSL(str)** | check if the string is an HSL (hue, saturation, lightness, optional alpha) color based on [CSS Colors Level 4 specification][CSS Colors Level 4 Specification].

Comma-separated format supported. Space-separated format supported with the exception of a few edge cases (ex: `hsl(200grad+.1%62%/1)`). -**isIBAN(str)** | check if the string is an IBAN (International Bank Account Number).

Also allows you to define a whitelist, when you only want to recieve IBAN codes from certain countries or a blacklist, removing some of them from the current list. +**isIBAN(str, [, options])** | check if the string is an IBAN (International Bank Account Number).

`options` is an object which accepts two attributes: `whitelist`: where you can restrict IBAN codes you want to receive data from and `blacklist`: where you can remove some of the countries from the current list. For both you can use an array with the following values `['AD','AE','AL','AT','AZ','BA','BE','BG','BH','BR','BY','CH','CR','CY','CZ','DE','DK','DO','EE','EG','ES','FI','FO','FR','GB','GE','GI','GL','GR','GT','HR','HU','IE','IL','IQ','IR','IS','IT','JO','KW','KZ','LB','LC','LI','LT','LU','LV','MC','MD','ME','MK','MR','MT','MU','MZ','NL','NO','PK','PL','PS','PT','QA','RO','RS','SA','SC','SE','SI','SK','SM','SV','TL','TN','TR','UA','VA','VG','XK']`. **isIdentityCard(str [, locale])** | check if the string is a valid identity card code.

`locale` is one of `['LK', 'PL', 'ES', 'FI', 'IN', 'IT', 'IR', 'MZ', 'NO', 'TH', 'zh-TW', 'he-IL', 'ar-LY', 'ar-TN', 'zh-CN', 'zh-HK']` OR `'any'`. If 'any' is used, function will check if any of the locales match.

Defaults to 'any'. **isIMEI(str [, options]))** | check if the string is a valid [IMEI number][IMEI]. IMEI should be of format `###############` or `##-######-######-#`.

`options` is an object which can contain the keys `allow_hyphens`. Defaults to first format. If `allow_hyphens` is set to true, the validator will validate the second format. **isIn(str, values)** | check if the string is in an array of allowed values. From bd34c0b6ddf0801597ab3dc91e4163a5c283714d Mon Sep 17 00:00:00 2001 From: Edilson da Silva Date: Mon, 24 Jul 2023 14:30:15 -0300 Subject: [PATCH 4/4] fix: remove errors from the isIBAN validator --- src/lib/isIBAN.js | 6 +++--- test/validators.test.js | 8 +++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/lib/isIBAN.js b/src/lib/isIBAN.js index 7f6d63238..6d7fc22af 100644 --- a/src/lib/isIBAN.js +++ b/src/lib/isIBAN.js @@ -126,13 +126,13 @@ function hasValidIbanFormat(str, options) { if (options.whitelist) { if (!hasOnlyValidCountryCodes(options.whitelist)) { - throw new Error('One of the codes passed is invalid'); + return false; } const isoCountryCodeInWhiteList = options.whitelist.includes(isoCountryCode); if (!isoCountryCodeInWhiteList) { - throw new Error('IBAN code does not belong to one of the countries listed on whitelist!'); + return false; } } @@ -140,7 +140,7 @@ function hasValidIbanFormat(str, options) { const isoCountryCodeInBlackList = options.blacklist.includes(isoCountryCode); if (isoCountryCodeInBlackList) { - throw new Error('IBAN code belongs to one of the countries listed on blacklist!'); + return false; } } diff --git a/test/validators.test.js b/test/validators.test.js index 0e31914a0..2da2f1ac4 100644 --- a/test/validators.test.js +++ b/test/validators.test.js @@ -5257,7 +5257,7 @@ describe('Validators', () => { 'DK5000400440116243', 'GB29NWBK60161331926819', ], - error: [ + invalid: [ 'BE71 0961 2345 6769', 'FR76 3000 6000 0112 3456 7890 189', 'DE91 1000 0000 0123 4567 89', @@ -5275,7 +5275,7 @@ describe('Validators', () => { test({ validator: 'isIBAN', args: [{ whitelist: ['XX', 'AA'] }], - error: [ + invalid: [ 'DK5000400440116243', 'GB29NWBK60161331926819', 'BE71 0961 2345 6769', @@ -5318,15 +5318,13 @@ describe('Validators', () => { 'IR200170000000339545727003', 'MZ97123412341234123412341', ], - error: [ - 'IT60X0542811101000000123456', - ], invalid: [ 'XX22YYY1234567890123', 'FR14 2004 1010 0505 0001 3', 'FR7630006000011234567890189@', 'FR7630006000011234567890189๐Ÿ˜…', 'FR763000600001123456!!๐Ÿคจ7890189@', + 'IT60X0542811101000000123456', ], }); });