diff --git a/app/(auth)/reset-password/ResetPasswordForm.tsx b/app/(auth)/reset-password/ResetPasswordForm.tsx index 8cb0979..e8a7741 100644 --- a/app/(auth)/reset-password/ResetPasswordForm.tsx +++ b/app/(auth)/reset-password/ResetPasswordForm.tsx @@ -7,9 +7,11 @@ import { toast } from 'sonner'; import FooterLink from '@/components/forms/FooterLink'; import InputField from '@/components/forms/InputField'; +import PasswordRequirements from '@/components/forms/PasswordRequirements'; import OpenDevSocietyBranding from '@/components/OpenDevSocietyBranding'; import { Button } from '@/components/ui/button'; import { resetPasswordWithToken } from '@/lib/actions/auth.actions'; +import { PASSWORD_VALIDATION } from '@/lib/constants'; type ResetPasswordFormData = { newPassword: string; @@ -86,8 +88,9 @@ const ResetPasswordForm = () => { type="password" register={register} error={errors.newPassword} - validation={{ required: 'New password is required', minLength: 8 }} + validation={PASSWORD_VALIDATION} /> + { register, handleSubmit, control, + watch, formState: { errors, isSubmitting }, } = useForm({ defaultValues: { @@ -33,6 +35,8 @@ const SignUp = () => { mode: 'onBlur' },); + const passwordValue = watch('password'); + const onSubmit = async (data: SignUpFormData) => { try { const result = await signUpWithEmail(data); @@ -87,8 +91,9 @@ const SignUp = () => { type="password" register={register} error={errors.password} - validation={{ required: 'Password is required', minLength: 8 }} + validation={PASSWORD_VALIDATION} /> + { + return ( +
    + {PASSWORD_RULES.map((rule) => { + const passed = rule.test(password); + return ( +
  • + {password.length === 0 ? ( + + ) : passed ? ( + + ) : ( + + )} + 0 && 'text-red-500', + )} + > + {rule.label} + +
  • + ); + })} +
+ ); +}; + +export default PasswordRequirements; diff --git a/lib/constants.ts b/lib/constants.ts index db73c24..6f41a45 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -338,3 +338,19 @@ export const WATCHLIST_TABLE_HEADER = [ 'Alert', 'Action', ]; + +export const PASSWORD_RULES = [ + { label: 'At least 8 characters', test: (pw: string) => pw.length >= 8 }, + { label: 'At least 1 uppercase letter', test: (pw: string) => /[A-Z]/.test(pw) }, + { label: 'At least 1 lowercase letter', test: (pw: string) => /[a-z]/.test(pw) }, + { label: 'At least 1 number', test: (pw: string) => /[0-9]/.test(pw) }, +] as const; + +export const PASSWORD_VALIDATION = { + required: 'Password is required', + minLength: { value: 8, message: 'Password must be at least 8 characters' }, + pattern: { + value: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/, + message: 'Password must include uppercase, lowercase, and a number', + }, +};