From c257cf356cdd8de24db048a6f2c3be01e1235bda Mon Sep 17 00:00:00 2001 From: Senthamilselvi Date: Tue, 4 Nov 2025 20:11:19 +0530 Subject: [PATCH] login, forgot/change password bug fixed --- .../pages/ChangePassword/ChangePassword.jsx | 179 +++++++++--------- ipi-survey-platform/src/pages/Login/Login.jsx | 39 ++-- .../src/pages/PublicContactForm.jsx | 30 ++- 3 files changed, 128 insertions(+), 120 deletions(-) diff --git a/ipi-survey-platform/src/pages/ChangePassword/ChangePassword.jsx b/ipi-survey-platform/src/pages/ChangePassword/ChangePassword.jsx index 9d6a0f2..a6952f5 100644 --- a/ipi-survey-platform/src/pages/ChangePassword/ChangePassword.jsx +++ b/ipi-survey-platform/src/pages/ChangePassword/ChangePassword.jsx @@ -13,6 +13,7 @@ const ToggleableInput = ({ toggleShow, placeholder, required = false, + error, }) => (
+ {error &&

{error}

} ); - const ChangePassword = () => { const navigate = useNavigate(); const location = useLocation(); @@ -71,88 +69,95 @@ const ChangePassword = () => { const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(""); const [success, setSuccess] = React.useState(""); + const [otpError, setOtpError] = React.useState(""); + const [newPasswordError, setNewPasswordError] = React.useState(""); + const [confirmPasswordError, setConfirmPasswordError] = React.useState(""); +const validatePassword = (password) => { + const isStrong = + /.{8,}/.test(password) && + /[A-Z]/.test(password) && + /[a-z]/.test(password) && + /[0-9]/.test(password) && + /[!@#$%^&*(),.?":{}|<>]/.test(password); - const validatePassword = (password) => { - const minLength = /.{8,}/; - const uppercase = /[A-Z]/; - const lowercase = /[a-z]/; - const number = /[0-9]/; - const specialChar = /[!@#$%^&*(),.?":{}|<>]/; + if (!isStrong) { + return "Password must meet complexity requirements."; + } + return ""; +}; - if (!minLength.test(password)) - return "Password must be at least 8 characters long."; - if (!uppercase.test(password)) - return "Password must contain at least one uppercase letter."; - if (!lowercase.test(password)) - return "Password must contain at least one lowercase letter."; - if (!number.test(password)) - return "Password must contain at least one number."; - if (!specialChar.test(password)) - return "Password must contain at least one special character."; +const handleSubmit = async (e) => { + e.preventDefault(); - return ""; - }; + setError(""); + setSuccess(""); - const handleSubmit = async (e) => { - e.preventDefault(); - setError(""); - setSuccess(""); + setOtpError(""); + setNewPasswordError(""); + setConfirmPasswordError(""); - if (!registeredEmail) { - setError("Missing registered email. Please restart the process."); - return; + let hasError = false; + + if (!otp.trim()) { + setOtpError("Verification code is required."); + hasError = true; + } + if (!newPassword.trim()) { + setNewPasswordError("New password is required."); + hasError = true; + } + if (!confirmPassword.trim()) { + setConfirmPasswordError("Confirm password is required."); + hasError = true; + } + + if (hasError) return; + + const passwordError = validatePassword(newPassword); + if (passwordError) { + setNewPasswordError(passwordError); + } + + if (newPassword !== confirmPassword) { + setConfirmPasswordError("Passwords do not match."); + return; + } + + setLoading(true); + try { + const payload = { + registered_email: registeredEmail, + otp: otp.trim(), + password: newPassword, + confirm_password: confirmPassword, + }; + + const response = await apiClient.post("/forgot-password/verify-otp", payload); + + if (response?.data) { + setSuccess("Password changed successfully. Redirecting to login..."); + setTimeout(() => { + navigate("/login", { + state: { + showSuccessToast: true, + successMessage: + "Password reset successful. Please login with your new password.", + }, + }); + }, 1500); + } else { + setError("Something went wrong. Please try again."); } - - if (!otp || !newPassword || !confirmPassword) { - setError("Please fill in all fields."); - return; - } - - const passwordError = validatePassword(newPassword); - if (passwordError) { - setError(passwordError); - return; - } - - if (newPassword !== confirmPassword) { - setError("Passwords do not match."); - return; - } - - setLoading(true); - try { - const payload = { - registered_email: registeredEmail, - otp: otp.trim(), - password: newPassword, - confirm_password: confirmPassword, - }; - - const response = await apiClient.post("/forgot-password/verify-otp", payload); - - if (response?.data) { - setSuccess("Password changed successfully. Redirecting to login..."); - setTimeout(() => { - navigate("/login", { - state: { - showSuccessToast: true, - successMessage: "Password reset successful. Please login with your new password." - } - }); - }, 1500); - } else { - setError("Something went wrong. Please try again."); - } - } catch (err) { - const msg = - err.response?.data?.message || - err.message || - "Password change failed. Please verify the details."; - setError(msg); - } finally { - setLoading(false); - } - }; + } catch (err) { + const msg = + err.response?.data?.message || + err.message || + "Password change failed. Please verify the details."; + setError(msg); + } finally { + setLoading(false); + } +}; return (
@@ -193,12 +198,12 @@ const ChangePassword = () => { setOtp(e.target.value)} show={showOtp} toggleShow={() => setShowOtp((v) => !v)} placeholder="Enter 6-digit code" + error={otpError} /> { show={showNewPassword} toggleShow={() => setShowNewPassword((v) => !v)} placeholder="Enter new password" + error={newPasswordError} /> { show={showConfirmPassword} toggleShow={() => setShowConfirmPassword((v) => !v)} placeholder="Re-enter new password" + error={confirmPasswordError} /> {newPassword && (
    diff --git a/ipi-survey-platform/src/pages/Login/Login.jsx b/ipi-survey-platform/src/pages/Login/Login.jsx index a5381eb..32624ab 100644 --- a/ipi-survey-platform/src/pages/Login/Login.jsx +++ b/ipi-survey-platform/src/pages/Login/Login.jsx @@ -26,7 +26,6 @@ const Login = () => { const toastTimeoutRef = React.useRef(null); const navigateTimeoutRef = React.useRef(null); - // Generate CAPTCHA const generateCaptcha = React.useCallback(() => { const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; let code = ''; @@ -37,7 +36,6 @@ const Login = () => { }, []); - // Toast helpers const closeToast = React.useCallback(() => { if (toastTimeoutRef.current) { clearTimeout(toastTimeoutRef.current); @@ -59,7 +57,6 @@ const Login = () => { }, 4000); }, []); - // Navigate delay const scheduleNavigate = React.useCallback( (path) => { if (!path) return; @@ -105,7 +102,6 @@ const Login = () => { setCaptchaError(''); }; - // Email format check const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; const validateForm = () => { @@ -113,20 +109,23 @@ const Login = () => { setEmailError(''); setPasswordError(''); setCaptchaError(''); - - if (!email.trim()) { - setEmailError('Enter your email address.'); + + const trimmedEmail = email.trim(); + const trimmedPassword = password.trim(); + + if (!trimmedEmail) { + setEmailError('Email is required'); valid = false; - } else if (!emailRegex.test(email)) { + } else if (!emailRegex.test(trimmedEmail)) { setEmailError('Enter a valid email address.'); valid = false; } - - if (!password.trim()) { - setPasswordError('Enter your password.'); + + if (!trimmedPassword) { + setPasswordError('Password is required'); valid = false; } - + if (!userCaptcha.trim()) { setCaptchaError('Please enter the CAPTCHA.'); valid = false; @@ -134,9 +133,9 @@ const Login = () => { setCaptchaError('Invalid. Try again or refresh for a new code.'); valid = false; } - + return valid; - }; + }; const submit = async (e) => { e.preventDefault(); @@ -260,7 +259,6 @@ const Login = () => {
    - {/* Email */}
    { value={email} onChange={(e) => { setEmail(e.target.value); - if (emailError) setEmailError(''); // 👈 clears error while typing + if (emailError) setEmailError(''); }} placeholder="name@company.com" className={`block w-full h-10 rounded-md border-2 px-4 text-sm focus:ring-0 ${ @@ -278,7 +276,6 @@ const Login = () => { {emailError &&

    {emailError}

    }
    - {/* Password */}
    @@ -312,19 +309,16 @@ const Login = () => { {passwordError &&

    {passwordError}

    }
    - {/* CAPTCHA */}
    - {/* CAPTCHA text box */}
    {captcha}
    - {/* Refresh icon + text */}
    - {/* Info text */}

    Enter the characters in the image. Can't read it? Refresh for a new code.

    - {/*
    */} - { {captchaError &&

    {captchaError}

    }
    - {/* Remember me */}
    - {/* Submit */}