feat(auth): integrate Captcha validation in PasswordAuthenticator
- Added CaptchaGuard dependency to PasswordAuthenticator. - Implemented Captcha validation in the authenticate method to enhance security. - Updated the login modal in home.html.twig to redirect to the admin panel instead of opening a modal. - Enhanced the Altcha widget with localized strings for better user experience. - Removed the login modal implementation from home.html.twig to streamline the login process. - Updated manifest.json and AST cache files to reflect changes in the codebase.
This commit is contained in:
@@ -10,12 +10,23 @@ interface AltchaProps {
|
||||
challengeUrl?: string;
|
||||
}
|
||||
|
||||
// برچسبهای فارسی widget (ترجمهی رسمی locale fa).
|
||||
const FA_STRINGS = JSON.stringify({
|
||||
label: 'من ربات نیستم',
|
||||
verifying: 'در حال بررسی...',
|
||||
verified: 'تأیید شد',
|
||||
waitAlert: 'در حال بررسی... لطفاً منتظر بمانید.',
|
||||
error: 'احراز هویت ناموفق بود. کمی بعد دوباره تلاش کنید.',
|
||||
expired: 'احراز هویت منقضی شد. دوباره تلاش کنید.',
|
||||
});
|
||||
|
||||
// altcha-widget یک custom element است؛ به JSX معرفی میشود (React 19: namespace زیر React.JSX).
|
||||
declare module 'react' {
|
||||
namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
'altcha-widget': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
|
||||
challengeurl?: string;
|
||||
strings?: string;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -39,5 +50,5 @@ export default function Altcha({ onVerified, challengeUrl = '/api/v1/altcha/chal
|
||||
return () => el.removeEventListener('statechange', onStateChange);
|
||||
}, [onVerified]);
|
||||
|
||||
return <altcha-widget ref={ref as React.Ref<HTMLElement>} challengeurl={challengeUrl} />;
|
||||
return <altcha-widget ref={ref as React.Ref<HTMLElement>} challengeurl={challengeUrl} strings={FA_STRINGS} />;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ export default function LoginPage() {
|
||||
const [cooldown, setCooldown] = useState(0);
|
||||
// آخرین payload حلشدهی ALTCHA برای مرحلهی جاری (یکبارمصرف؛ بین مراحل ریست میشود).
|
||||
const [altcha, setAltcha] = useState('');
|
||||
// با تغییر key، widget رمزِ فرمِ ورود پس از هر تلاش ناموفق دوباره challenge تازه میگیرد.
|
||||
const [pwCaptchaKey, setPwCaptchaKey] = useState(0);
|
||||
const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
||||
|
||||
useEffect(() => () => { if (timerRef.current) clearInterval(timerRef.current); }, []);
|
||||
@@ -72,13 +74,20 @@ export default function LoginPage() {
|
||||
const res = await fetch('/api/v1/user/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ mobile_number: pwMobile, password: pwPass }),
|
||||
body: JSON.stringify({ mobile_number: pwMobile, password: pwPass, altcha }),
|
||||
});
|
||||
const json = await res.json();
|
||||
if (!res.ok) { toast.error(json?.errors?.[0]?.message ?? 'خطا در ورود'); return; }
|
||||
if (!res.ok) {
|
||||
toast.error(json?.errors?.[0]?.message ?? 'خطا در ورود');
|
||||
setAltcha(''); setPwCaptchaKey((k) => k + 1); // challenge یکبارمصرف؛ تازه بگیر
|
||||
return;
|
||||
}
|
||||
login(json.access_token, json.refresh_token);
|
||||
toast.success('خوش آمدید');
|
||||
} catch { toast.error('خطا در اتصال به سرور'); }
|
||||
} catch {
|
||||
toast.error('خطا در اتصال به سرور');
|
||||
setAltcha(''); setPwCaptchaKey((k) => k + 1);
|
||||
}
|
||||
finally { setPwLoading(false); }
|
||||
};
|
||||
|
||||
@@ -248,8 +257,9 @@ export default function LoginPage() {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ marginTop: 12 }}><Altcha key={`pw-login-${pwCaptchaKey}`} onVerified={setAltcha} /></div>
|
||||
<button type="submit" className="btn primary block" disabled={pwLoading}
|
||||
style={{ marginTop: 8, height: 46, fontSize: 15 }}>
|
||||
style={{ marginTop: 12, height: 46, fontSize: 15 }}>
|
||||
{pwLoading ? 'در حال ورود...' : 'ورود به سیستم'}
|
||||
</button>
|
||||
<div style={{ textAlign: 'center', marginTop: 16 }}>
|
||||
|
||||
Reference in New Issue
Block a user