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',
+ },
+};