diff --git a/package.json b/package.json index d9a8d9e..a94b082 100644 --- a/package.json +++ b/package.json @@ -45,10 +45,6 @@ "@trpc/server": "^10.45.2", "@uidotdev/usehooks": "^2.4.1", "@uploadthing/react": "^6.7.2", - "@zxcvbn-ts/core": "^3.0.4", - "@zxcvbn-ts/language-common": "^3.0.4", - "@zxcvbn-ts/language-en": "^3.0.2", - "@zxcvbn-ts/language-id": "^3.0.2", "argon2": "^0.40.3", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 98850d6..733727d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -200,6 +200,9 @@ importers: zustand: specifier: ^4.5.4 version: 4.5.4(@types/react@18.3.3)(react@18.2.0) + zxcvbn: + specifier: ^4.4.2 + version: 4.4.2 devDependencies: '@types/node': specifier: ^18.19.39 @@ -216,6 +219,9 @@ importers: '@types/remove-markdown': specifier: ^0.3.4 version: 0.3.4 + '@types/zxcvbn': + specifier: ^4.4.4 + version: 4.4.4 '@typescript-eslint/eslint-plugin': specifier: ^7.15.0 version: 7.15.0(@typescript-eslint/parser@7.15.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3) @@ -2371,6 +2377,9 @@ packages: '@types/unist@3.0.2': resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + '@types/zxcvbn@4.4.4': + resolution: {integrity: sha512-Tuk4q7q0DnpzyJDI4aMeghGuFu2iS1QAdKpabn8JfbtfGmVDUgvZv1I7mEjP61Bvnp3ljKCC8BE6YYSTNxmvRQ==} + '@typescript-eslint/eslint-plugin@7.15.0': resolution: {integrity: sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==} engines: {node: ^18.18.0 || >=20.0.0} @@ -5261,6 +5270,9 @@ packages: zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + zxcvbn@4.4.2: + resolution: {integrity: sha512-Bq0B+ixT/DMyG8kgX2xWcI5jUvCwqrMxSFam7m0lAf78nf04hv6lNCsyLYdyYTrCVMqNDY/206K7eExYCeSyUQ==} + snapshots: '@alloc/quick-lru@5.2.0': {} @@ -7291,6 +7303,8 @@ snapshots: '@types/unist@3.0.2': {} + '@types/zxcvbn@4.4.4': {} + '@typescript-eslint/eslint-plugin@7.15.0(@typescript-eslint/parser@7.15.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3)': dependencies: '@eslint-community/regexpp': 4.11.0 @@ -10680,3 +10694,5 @@ snapshots: react: 18.2.0 zwitch@2.0.4: {} + + zxcvbn@4.4.2: {} diff --git a/src/app/auth/sign-up/signup-form.tsx b/src/app/auth/sign-up/signup-form.tsx index 4c650b1..d6fb58b 100644 --- a/src/app/auth/sign-up/signup-form.tsx +++ b/src/app/auth/sign-up/signup-form.tsx @@ -7,14 +7,10 @@ import { signIn } from 'next-auth/react'; import Image from 'next/image'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; -import { useEffect, useMemo, useRef, useState } from 'react'; -import { useForm, useWatch } from 'react-hook-form'; +import { useRef, useState } from 'react'; +import { useForm } from 'react-hook-form'; import toast from 'react-hot-toast'; import { match } from 'ts-pattern'; -import { zxcvbnOptions, zxcvbnAsync, type ZxcvbnResult } from '@zxcvbn-ts/core'; -import * as zxcvbnCommonPackage from '@zxcvbn-ts/language-common'; -import * as zxcvbnEnPackage from '@zxcvbn-ts/language-en'; -import * as zxcvbnIdPackage from '@zxcvbn-ts/language-id'; import { Button } from '@/components/ui/button'; import { @@ -29,34 +25,6 @@ import { Input } from '@/components/ui/input'; import { environment } from '@/environment.mjs'; import { type SignupSchema, signupSchema } from '@/schema/signup-schema'; import { api } from '@/trpc/react'; -import { Progress } from '@/components/ui/progress'; -import { cn } from '@/lib/utils'; -import { useDebounce } from '@uidotdev/usehooks'; - -const options = { - dictionary: { - ...zxcvbnCommonPackage.dictionary, - ...zxcvbnEnPackage.dictionary, - ...zxcvbnIdPackage.dictionary, - }, - graphs: zxcvbnCommonPackage.adjacencyGraphs, - useLevenshteinDistance: true, - translations: zxcvbnEnPackage.translations, -}; -zxcvbnOptions.setOptions(options); - -const usePasswordStrength = (password: string) => { - const [result, setResult] = useState(); - const deferredPassword = useDebounce(password, 500); - - useEffect(() => { - if (deferredPassword) { - zxcvbnAsync(deferredPassword).then((response) => setResult(response)); - } - }, [deferredPassword]); - - return result; -}; export function SignupForm() { const [isPasswordShowed, setIsPasswordShowed] = useState(false); @@ -65,13 +33,6 @@ export function SignupForm() { const form = useForm({ resolver: zodResolver(signupSchema), }); - const password = useWatch({ control: form.control, name: 'password' }); - const passwordStrength = usePasswordStrength(password); - const pwdStrengthValue = useMemo( - () => - passwordStrength?.score ? ((passwordStrength.score + 1) / 5) * 100 : 20, - [passwordStrength], - ); const router = useRouter(); @@ -185,55 +146,29 @@ export function SignupForm() { Password -
- - - - -
- '[&>*]:bg-red-500') - .with(1, () => '[&>*]:bg-orange-500') - .with(2, () => '[&>*]:bg-yellow-500') - .with(3, () => '[&>*]:bg-green-500') - .with(4, () => '[&>*]:bg-blue-500') - .otherwise(() => ''), - 'grow', - )} - /> - - {match(passwordStrength?.score ?? 0) - .with(0, () => 'Very weak') - .with(1, () => 'Weak') - .with(2, () => 'Fair') - .with(3, () => 'Good') - .with(4, () => 'Strong') - .otherwise(() => 'Empty')} - -
-
+ + + +