diff --git a/README.md b/README.md index 91bd88d..a8c06f6 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,13 @@ const isValid = validationUtil.checkEmail("user@example.com"); // true const isHttpUrl = validationUtil.checkHttpUrl("https://example.com"); // true const isDomain = validationUtil.checkDomain("example.com"); // true const isBase64 = validationUtil.checkBase64("U29tZSB2YWxpZCBiYXNlNjQgc3RyaW5n"); // true +const isPasswordValid = validationUtil.checkPassword("Abc123!@#", { + minLength: 8, + requireUppercase: true, + requireLowercase: true, + requireNumber: true, + requireSpecialChar: true, +}); // true // Common utilities const empty = commonUtil.isEmpty(""); // true @@ -87,6 +94,7 @@ const theme = cookieUtil.getCookie("theme"); - `checkHttpUrl(url: string): boolean` - Validates HTTP/HTTPS URL format - `checkDomain(domain: string): boolean` - Validates domain name format - `checkBase64(value: string): boolean` - Validates whether a string is a valid base64 encoded value +- `checkPassword(password: string, options?: { minLength?: number; maxLength?: number; requireUppercase?: boolean; requireLowercase?: boolean; requireNumber?: boolean; requireSpecialChar?: boolean }): boolean` - Validates password strength and requirements ### CommonUtil diff --git a/package/validationUtil/checkPassword/index.test.ts b/package/validationUtil/checkPassword/index.test.ts new file mode 100644 index 0000000..2e6cd25 --- /dev/null +++ b/package/validationUtil/checkPassword/index.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, test } from "vitest"; +import checkPassword from "."; + +describe("checkPassword 유틸 함수 테스트", () => { + describe("유효한 비밀번호에 대해 true를 반환해야 합니다.", () => { + test("기본 상태는 아무 옵션도 설정되어있지 않기 때문에 true를 반환해야 합니다.", () => { + expect(checkPassword("Valid123!", {})).toBe(true); + }); + test("특수 문자가 필요한 경우 true를 반환해야 합니다.", () => { + expect(checkPassword("vsdvdsvsdvs1!", { requireSpecialChar: true })).toBe( + true + ); + }); + test("대문자가 필요한 경우 true를 반환해야 합니다.", () => { + expect(checkPassword("Vsdvd", { requireUppercase: true })).toBe(true); + }); + test("최소 3자, 최대 5자의 길이를 가져야 하는 경우 true를 반환해야 합니다.", () => { + expect(checkPassword("Vsd", { minLength: 3, maxLength: 5 })).toBe(true); + }); + }); + + describe("유효하지 않은 비밀번호에 대해 false를 반환해야 합니다.", () => { + test("길이가 유효하지 않은 경우 false를 반환해야 합니다.", () => { + expect(checkPassword("invalid", { minLength: 3, maxLength: 5 })).toBe( + false + ); + }); + test("특수 문자가 없는 경우 false를 반환해야 합니다.", () => { + expect(checkPassword("dffadsfas", { requireSpecialChar: true })).toBe( + false + ); + }); + }); +}); diff --git a/package/validationUtil/checkPassword/index.ts b/package/validationUtil/checkPassword/index.ts new file mode 100644 index 0000000..d137c65 --- /dev/null +++ b/package/validationUtil/checkPassword/index.ts @@ -0,0 +1,31 @@ +export default function checkPassword( + password: string, + options?: { + minLength?: number; + maxLength?: number; + requireUppercase?: boolean; + requireLowercase?: boolean; + requireNumber?: boolean; + requireSpecialChar?: boolean; + } +): boolean { + const { + minLength, + maxLength, + requireUppercase = false, + requireLowercase = false, + requireNumber = false, + requireSpecialChar = false, + } = options || {}; + + if (minLength !== undefined && password.length < minLength) return false; + if (maxLength !== undefined && password.length > maxLength) return false; + const hasUpperCase = requireUppercase ? /[A-Z]/.test(password) : true; + const hasLowerCase = requireLowercase ? /[a-z]/.test(password) : true; + const hasNumber = requireNumber ? /\d/.test(password) : true; + const hasSpecialChar = requireSpecialChar + ? /[!@#$%^&*(),.?":{}|<>]/.test(password) + : true; + + return hasUpperCase && hasLowerCase && hasNumber && hasSpecialChar; +} diff --git a/package/validationUtil/index.ts b/package/validationUtil/index.ts index e49429b..f530838 100644 --- a/package/validationUtil/index.ts +++ b/package/validationUtil/index.ts @@ -2,3 +2,4 @@ export { default as checkEmail } from "./checkEmail"; export { default as checkHttpUrl } from "./checkHttpUrl"; export { default as checkDomain } from "./checkDomain"; export { default as checkBase64 } from "./checkBase64"; +export { default as checkPassword } from "./checkPassword";