From d95972cb548ca52067f5ad76912d772118a5ce6b Mon Sep 17 00:00:00 2001 From: Donghyeok Shin Date: Thu, 1 May 2025 00:38:51 +0900 Subject: [PATCH 1/6] feat: add KR(South Korea) locale in isIdentityCard validators --- src/lib/isIdentityCard.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/lib/isIdentityCard.js b/src/lib/isIdentityCard.js index fc37d4a29..e0286a6af 100644 --- a/src/lib/isIdentityCard.js +++ b/src/lib/isIdentityCard.js @@ -3,6 +3,35 @@ import includes from './util/includesArray'; import isInt from './isInt'; const validators = { + KR: function KR(str) { + // {birthday 6 digits} + '-' + {gender 1 digit} + {random 6 digits} + const birthdayRegex = /([0-9][0-9])(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])/; + const genderRegex = /([1-4])/; + const randomRegex = /(\d{6})/; + const totalRegex = new RegExp(`^${birthdayRegex.source}-${genderRegex.source}${randomRegex.source}$`); + + if (!totalRegex.test(str)) { + return false; + } + + // Before 2000 gender digit should be 1,2 + // After 2000 gender digit should be 3,4 + // ex) current time: 2025-01-01 --> 990101-3 can't be exist because it means born in 2099-01-01. + const now = new Date().toLocaleString('ko-KR', { timeZone: 'Asia/Seoul' }); + const currentYearDigits = Number(now.slice(2, 4)); + const yearDigits = Number(str.slice(0, 2)); + const genderDigit = Number(str.slice(7, 8)); + + if (currentYearDigits < yearDigits) { + if (genderDigit === 3 || genderDigit === 4) { + return false; + } + } else if (genderDigit === 1 || genderDigit === 2) { + return false; + } + + return true; + }, PL: (str) => { assertString(str); From 1192d42aa24ed0cd3552f4f7fe4b972694e7d953 Mon Sep 17 00:00:00 2001 From: Donghyeok Shin Date: Thu, 1 May 2025 00:40:08 +0900 Subject: [PATCH 2/6] chore: edit isIdentityCard README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4974b6104..d409997fa 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ Validator | Description **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, [, 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', 'PK']` OR `'any'`. If 'any' is used, function will check if any of the locales match.

Defaults to 'any'. +**isIdentityCard(str [, locale])** | check if the string is a valid identity card code.

`locale` is one of `['KR', 'LK', 'PL', 'ES', 'FI', 'IN', 'IT', 'IR', 'MZ', 'NO', 'TH', 'zh-TW', 'he-IL', 'ar-LY', 'ar-TN', 'zh-CN', 'zh-HK', 'PK']` 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. **isInt(str [, options])** | check if the string is an integer.

`options` is an object which can contain the keys `min` and/or `max` to check the integer is within boundaries (e.g. `{ min: 10, max: 99 }`). `options` can also contain the key `allow_leading_zeroes`, which when set to false will disallow integer values with leading zeroes (e.g. `{ allow_leading_zeroes: false }`). Finally, `options` can contain the keys `gt` and/or `lt` which will enforce integers being greater than or less than, respectively, the value provided (e.g. `{gt: 1, lt: 4}` for a number between 1 and 4). From 94585604d59c197a0331fbed852ff7029b0e70b7 Mon Sep 17 00:00:00 2001 From: Donghyeok Shin Date: Thu, 1 May 2025 00:40:42 +0900 Subject: [PATCH 3/6] test: add test case for KR(South Korea) identity card validation --- test/validators.test.js | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/test/validators.test.js b/test/validators.test.js index 734a2a22b..3609b2fc7 100644 --- a/test/validators.test.js +++ b/test/validators.test.js @@ -6304,8 +6304,29 @@ describe('Validators', () => { }); - it('should validate identity cards', () => { + it.only('should validate identity cards', () => { const fixtures = [ + { + locale: 'KR', + valid: [ + '731127-2121311', + '900115-1234567', + '851230-2234567', + '020509-3234567', + '101121-4234567', + '770308-1034567', + ], + invalid: [ + '991331-1234567', + '900115-5234567', + '020509-2234567', + '851230-3', + 'abcd12-1234567', + '901215_1234567', + '850230-123456', + '990101-3111111', + ], + }, { locale: 'PK', valid: [ From 7b6369d6b1dcb2ee768703945f532afbbdac6572 Mon Sep 17 00:00:00 2001 From: Donghyeok Shin Date: Thu, 1 May 2025 01:05:52 +0900 Subject: [PATCH 4/6] test: remove 'only' option( i added 'only' option for my test case to minimize test) --- test/validators.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/validators.test.js b/test/validators.test.js index 3609b2fc7..a90ea9871 100644 --- a/test/validators.test.js +++ b/test/validators.test.js @@ -6304,7 +6304,7 @@ describe('Validators', () => { }); - it.only('should validate identity cards', () => { + it('should validate identity cards', () => { const fixtures = [ { locale: 'KR', From 0ae803ddcac609c30502253da3c7382a9e9fd750 Mon Sep 17 00:00:00 2001 From: Donghyeok Shin Date: Thu, 1 May 2025 01:17:26 +0900 Subject: [PATCH 5/6] feat: remove time check for KR(South Korea) identity card validation --- src/lib/isIdentityCard.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/lib/isIdentityCard.js b/src/lib/isIdentityCard.js index e0286a6af..f4379c948 100644 --- a/src/lib/isIdentityCard.js +++ b/src/lib/isIdentityCard.js @@ -17,18 +17,18 @@ const validators = { // Before 2000 gender digit should be 1,2 // After 2000 gender digit should be 3,4 // ex) current time: 2025-01-01 --> 990101-3 can't be exist because it means born in 2099-01-01. - const now = new Date().toLocaleString('ko-KR', { timeZone: 'Asia/Seoul' }); - const currentYearDigits = Number(now.slice(2, 4)); - const yearDigits = Number(str.slice(0, 2)); - const genderDigit = Number(str.slice(7, 8)); - - if (currentYearDigits < yearDigits) { - if (genderDigit === 3 || genderDigit === 4) { - return false; - } - } else if (genderDigit === 1 || genderDigit === 2) { - return false; - } + // const now = new Date().toLocaleString('ko-KR', { timeZone: 'Asia/Seoul' }); + // const currentYearDigits = Number(now.slice(2, 4)); + // const yearDigits = Number(str.slice(0, 2)); + // const genderDigit = Number(str.slice(7, 8)); + + // if (currentYearDigits < yearDigits) { + // if (genderDigit === 3 || genderDigit === 4) { + // return false; + // } + // } else if (genderDigit === 1 || genderDigit === 2) { + // return false; + // } return true; }, From 9f91515ba1595e6261dd455d251d41b34f019b16 Mon Sep 17 00:00:00 2001 From: Donghyeok Shin Date: Thu, 1 May 2025 01:26:39 +0900 Subject: [PATCH 6/6] test: remove test case for KR(South Korea) identity card validation related to time checking --- test/validators.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/validators.test.js b/test/validators.test.js index a90ea9871..b216af054 100644 --- a/test/validators.test.js +++ b/test/validators.test.js @@ -6319,12 +6319,12 @@ describe('Validators', () => { invalid: [ '991331-1234567', '900115-5234567', - '020509-2234567', + // '020509-2234567', '851230-3', 'abcd12-1234567', '901215_1234567', '850230-123456', - '990101-3111111', + // '990101-3111111', ], }, {