removed captacha

This commit is contained in:
Malini 2025-11-21 13:14:45 +05:30
parent 9745092a33
commit de3a72ca35
3 changed files with 129 additions and 277 deletions

View File

@ -1782,7 +1782,7 @@ const CompanyProfile = () => {
try { try {
const countResponse = await fetchEstablishments({ params: countParams, signal: controller.signal }); const countResponse = await fetchEstablishments({ params: countParams, signal: controller.signal });
const countPayload = countResponse?.data ?? countResponse; const countPayload = countResponse?.data ?? countResponse;
const totalRecords = countPayload?.pagination?.total_records || 0; const totalRecords = countResponse?.pagination?.total_records || 0;
const params = { const params = {
search: debouncedSearch || undefined, search: debouncedSearch || undefined,

View File

@ -1,12 +1,11 @@
import React from 'react'; import React from 'react';
import { useNavigate, useLocation } from 'react-router-dom'; import { useNavigate, useLocation } from 'react-router-dom';
import { login } from '@/services/auth/authService.js'; import { login } from '@/services/auth/authService.js';
import { RefreshCw, AlertCircle, Clock } from "lucide-react"; import { AlertCircle, Clock } from "lucide-react";
const logoSrc = '/assets/images/FCSCLogo.svg'; const logoSrc = '/assets/images/FCSCLogo.svg';
const MAX_FAILED_ATTEMPTS = 3; const MAX_FAILED_ATTEMPTS = 3;
const SHOW_CAPTCHA_AFTER = 0;
const LOCK_DURATION_MINUTES = 2; const LOCK_DURATION_MINUTES = 2;
const Login = () => { const Login = () => {
@ -23,10 +22,6 @@ const Login = () => {
const [emailError, setEmailError] = React.useState(''); const [emailError, setEmailError] = React.useState('');
const [passwordError, setPasswordError] = React.useState(''); const [passwordError, setPasswordError] = React.useState('');
const [captcha, setCaptcha] = React.useState('');
const [userCaptcha, setUserCaptcha] = React.useState('');
const [captchaError, setCaptchaError] = React.useState('');
const [isLocked, setIsLocked] = React.useState(false); const [isLocked, setIsLocked] = React.useState(false);
const [lockExpiry, setLockExpiry] = React.useState(null); const [lockExpiry, setLockExpiry] = React.useState(null);
const [failedAttempts, setFailedAttempts] = React.useState(0); const [failedAttempts, setFailedAttempts] = React.useState(0);
@ -36,15 +31,6 @@ const Login = () => {
const navigateTimeoutRef = React.useRef(null); const navigateTimeoutRef = React.useRef(null);
const countdownIntervalRef = React.useRef(null); const countdownIntervalRef = React.useRef(null);
const generateCaptcha = React.useCallback(() => {
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
let code = '';
for (let i = 0; i < 6; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length));
}
setCaptcha(code);
}, []);
const closeToast = React.useCallback(() => { const closeToast = React.useCallback(() => {
if (toastTimeoutRef.current) { if (toastTimeoutRef.current) {
clearTimeout(toastTimeoutRef.current); clearTimeout(toastTimeoutRef.current);
@ -106,8 +92,9 @@ const Login = () => {
countdownIntervalRef.current = setInterval(updateTimer, 1000); countdownIntervalRef.current = setInterval(updateTimer, 1000);
}, [showToast]); }, [showToast]);
// Check lock status when email changes
React.useEffect(() => { React.useEffect(() => {
generateCaptcha(); if (!email) return;
// Get the stored attempts and lock status for the current email // Get the stored attempts and lock status for the current email
const storedAttempts = JSON.parse(localStorage.getItem('login_attempts') || '{}'); const storedAttempts = JSON.parse(localStorage.getItem('login_attempts') || '{}');
@ -128,7 +115,7 @@ const Login = () => {
} else { } else {
setIsLocked(false); setIsLocked(false);
} }
}, [generateCaptcha, startCountdown, email]); }, [email, startCountdown]);
React.useEffect( React.useEffect(
() => () => { () => () => {
@ -139,24 +126,12 @@ const Login = () => {
[] []
); );
const handleCaptchaChange = (e) => {
setUserCaptcha(e.target.value.toUpperCase());
if (captchaError) setCaptchaError('');
};
const refreshCaptcha = () => {
generateCaptcha();
setUserCaptcha('');
setCaptchaError('');
};
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const validateForm = () => { const validateForm = () => {
let valid = true; let valid = true;
setEmailError(''); setEmailError('');
setPasswordError(''); setPasswordError('');
setCaptchaError('');
const trimmedEmail = email.trim(); const trimmedEmail = email.trim();
const trimmedPassword = password.trim(); const trimmedPassword = password.trim();
@ -174,14 +149,6 @@ const Login = () => {
valid = false; valid = false;
} }
if (!userCaptcha.trim()) {
setCaptchaError('Please enter the CAPTCHA.');
valid = false;
} else if (userCaptcha !== captcha) {
setCaptchaError('Invalid CAPTCHA. Try again or refresh for a new code.');
valid = false;
}
return valid; return valid;
}; };
@ -291,8 +258,6 @@ const Login = () => {
localStorage.setItem('login_attempts', JSON.stringify(updatedAttempts)); localStorage.setItem('login_attempts', JSON.stringify(updatedAttempts));
setFailedAttempts(attempts); setFailedAttempts(attempts);
refreshCaptcha();
if (attempts >= MAX_FAILED_ATTEMPTS) { if (attempts >= MAX_FAILED_ATTEMPTS) {
const lockUntil = Date.now() + LOCK_DURATION_MINUTES * 60 * 1000; const lockUntil = Date.now() + LOCK_DURATION_MINUTES * 60 * 1000;
setIsLocked(true); setIsLocked(true);
@ -457,55 +422,6 @@ const Login = () => {
{passwordError && <p className="text-xs text-red-600 mt-1">{passwordError}</p>} {passwordError && <p className="text-xs text-red-600 mt-1">{passwordError}</p>}
</div> </div>
<div className="mt-4">
<label className="block text-sm font-medium text-gray-700 mb-1">
CAPTCHA Verification <span className="text-red-500">*</span>
</label>
<div className="flex items-center gap-2">
<div className="flex justify-center items-center font-mono text-lg tracking-widest bg-gray-100 border-2 border-[#92722A] rounded-md px-4 py-2 select-none h-10">
{captcha}
</div>
<button
type="button"
onClick={refreshCaptcha}
disabled={isLocked}
className={`flex items-center gap-1 ${
isLocked
? 'text-gray-400 cursor-not-allowed'
: 'text-[#92722A] hover:text-[#7b5c1f]'
}`}
title="Refresh CAPTCHA"
>
<RefreshCw className="h-4 w-4" />
<span className="text-sm leading-none">Refresh</span>
</button>
</div>
<p className="text-xs text-gray-500 mt-1">
Enter the characters shown above. Can't read it? Click refresh for a new code.
</p>
<input
type="text"
id="captcha"
value={userCaptcha}
onChange={handleCaptchaChange}
placeholder="Type the characters"
disabled={isLocked}
className={`mt-2 block w-full h-10 rounded-md border-2 px-4 text-sm focus:ring-0 ${
captchaError
? 'border-red-500 bg-red-50'
: isLocked
? 'border-gray-300 bg-gray-100 cursor-not-allowed'
: 'border-[#92722A] bg-white'
}`}
/>
{captchaError && <p className="text-xs text-red-600 mt-1">{captchaError}</p>}
</div>
<div className="flex items-center justify-between text-sm"> <div className="flex items-center justify-between text-sm">
<label className="inline-flex items-center gap-2 cursor-pointer"> <label className="inline-flex items-center gap-2 cursor-pointer">
<input <input
@ -532,8 +448,7 @@ const Login = () => {
type="submit" type="submit"
disabled={ disabled={
loading || loading ||
isLocked || isLocked
!userCaptcha.trim()
} }
className={`inline-flex items-center justify-center w-full h-12 rounded-lg text-white font-medium ${ className={`inline-flex items-center justify-center w-full h-12 rounded-lg text-white font-medium ${
isLocked isLocked
@ -557,3 +472,4 @@ const Login = () => {
}; };
export default Login; export default Login;

View File

@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import apiClient from '@/services/api/apiClient'; import apiClient from '@/services/api/apiClient';
import { RefreshCw } from "lucide-react";
const logoSrc = '/assets/images/FCSCLogo.svg'; const logoSrc = '/assets/images/FCSCLogo.svg';
const PublicContactForm = () => { const PublicContactForm = () => {
@ -16,9 +16,6 @@ const PublicContactForm = () => {
const [errors, setErrors] = useState({}); const [errors, setErrors] = useState({});
const [isValid, setIsValid] = useState(false); const [isValid, setIsValid] = useState(false);
const [captcha, setCaptcha] = useState("");
const [userCaptcha, setUserCaptcha] = useState("");
const [captchaError, setCaptchaError] = useState("");
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [success, setSuccess] = useState(""); const [success, setSuccess] = useState("");
const [errorMsg, setErrorMsg] = useState(""); const [errorMsg, setErrorMsg] = useState("");
@ -30,19 +27,6 @@ const PublicContactForm = () => {
const toastTimeoutRef = React.useRef(null); const toastTimeoutRef = React.useRef(null);
const generateCaptcha = () => {
const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
let code = "";
for (let i = 0; i < 6; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length));
}
setCaptcha(code);
};
useEffect(() => {
generateCaptcha();
}, []);
useEffect(() => { useEffect(() => {
return () => { return () => {
if (toastTimeoutRef.current) { if (toastTimeoutRef.current) {
@ -98,11 +82,6 @@ const PublicContactForm = () => {
validate(updated); validate(updated);
}; };
const handleCaptchaChange = (e) => {
setUserCaptcha(e.target.value.toUpperCase());
setCaptchaError("");
};
const handleSubmit = async (e) => { const handleSubmit = async (e) => {
e.preventDefault(); e.preventDefault();
setErrorMsg(""); setErrorMsg("");
@ -111,12 +90,6 @@ const PublicContactForm = () => {
const validationErrors = validate(); const validationErrors = validate();
if (Object.keys(validationErrors).length > 0) return; if (Object.keys(validationErrors).length > 0) return;
if (userCaptcha !== captcha) {
setCaptchaError("Incorrect CAPTCHA. Please try again.");
generateCaptcha();
return;
}
setLoading(true); setLoading(true);
try { try {
const payload = { const payload = {
@ -335,48 +308,11 @@ const PublicContactForm = () => {
error={errors.email} error={errors.email}
/> />
<div className="mt-4">
<label className="block text-sm font-medium text-gray-700 mb-1">
CAPTCHA Verification <span className="text-red-500">*</span>
</label>
<div className="flex items-center gap-3">
<div
className="flex justify-center items-center font-mono text-lg tracking-widest bg-gray-100 border-2 border-[#92722A] rounded-md px-4 py-2 select-none"
aria-hidden="true"
>
{captcha}
</div>
<button
type="button"
onClick={generateCaptcha}
className="flex items-center gap-1 text-sm text-[#92722A] hover:underline"
>
<RefreshCw size={14} className="text-[#92722A]" />
Refresh
</button>
</div>
<p className="text-xs text-gray-500 mt-1">
Enter the characters in the image. Can't read it? Refresh for a new code.
<span className="font-mono"></span>
</p>
<input
type="text"
name="captcha"
value={userCaptcha}
onChange={handleCaptchaChange}
placeholder="Type the characters"
className={`mt-2 block w-full h-10 rounded-md border-2 ${
captchaError ? "border-red-500" : "border-[#92722A]"
} focus:border-[#92722A] focus:ring-0 px-4 text-sm bg-white`}
/>
{captchaError && <p className="text-xs text-red-600 mt-1">{captchaError}</p>}
</div>
<button <button
type="submit" type="submit"
disabled={!isValid || loading || !userCaptcha} disabled={!isValid || loading}
className={`inline-flex items-center justify-center w-full h-12 rounded-lg text-white ${ className={`inline-flex items-center justify-center w-full h-12 rounded-lg text-white ${
!isValid || loading || !userCaptcha !isValid || loading
? "bg-[#bfa06a] cursor-not-allowed" ? "bg-[#bfa06a] cursor-not-allowed"
: "bg-[#92722A] hover:bg-[#7b5c1f]" : "bg-[#92722A] hover:bg-[#7b5c1f]"
} transition-colors`} } transition-colors`}