Skip to content

Commit

Permalink
feat(isIBAN): add white and blacklist options to the isIBAN validator (
Browse files Browse the repository at this point in the history
…#2235)

* add white and blacklist options to the isIBAN validator

* improve coverage for isIBAN validator

* docs: add an explanation for the options object in the isIBAN validator without formatting it

* fix: remove errors from the isIBAN validator
  • Loading branch information
edilson committed Aug 3, 2023
1 parent 2ef9a83 commit f303d39
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 5 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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].<br/><br/>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, [, options])** | check if the string is an IBAN (International Bank Account Number).<br/><br/>`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.<br/><br/>`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.<br/><br/>Defaults to 'any'.
**isIMEI(str [, options]))** | check if the string is a valid [IMEI number][IMEI]. IMEI should be of format `###############` or `##-######-######-#`.<br/><br/>`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.
Expand Down
50 changes: 46 additions & 4 deletions src/lib/isIBAN.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,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:
Expand All @@ -96,14 +115,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)) {
return false;
}

const isoCountryCodeInWhiteList = options.whitelist.includes(isoCountryCode);

if (!isoCountryCodeInWhiteList) {
return false;
}
}

if (options.blacklist) {
const isoCountryCodeInBlackList = options.blacklist.includes(isoCountryCode);

if (isoCountryCodeInBlackList) {
return false;
}
}

return (isoCountryCodeInIbanRegexCodeObject) &&
ibanRegexThroughCountryCode[isoCountryCode].test(strippedStr);
}

Expand Down Expand Up @@ -131,10 +173,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);
77 changes: 77 additions & 0 deletions test/validators.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5256,6 +5256,83 @@ describe('Validators', () => {
'FR763000600001123456!!🤨7890189@',
],
});
test({
validator: 'isIBAN',
args: [{ whitelist: ['DK', 'GB'] }],
valid: [
'DK5000400440116243',
'GB29NWBK60161331926819',
],
invalid: [
'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: [{ whitelist: ['XX', 'AA'] }],
invalid: [
'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'] }],
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',
],
invalid: [
'XX22YYY1234567890123',
'FR14 2004 1010 0505 0001 3',
'FR7630006000011234567890189@',
'FR7630006000011234567890189😅',
'FR763000600001123456!!🤨7890189@',
'IT60X0542811101000000123456',
],
});
});

it('should validate BIC codes', () => {
Expand Down

0 comments on commit f303d39

Please sign in to comment.