Implement ALTCHA captcha service with challenge generation and solution verification
- Added AltchaService class for managing ALTCHA captcha challenges and solutions. - Created CaptchaController to handle API requests for generating challenges. - Introduced CaptchaGuard for validating captcha solutions on public endpoints. - Developed unit tests for AltchaService to ensure challenge creation and solution verification functionality. - Implemented integration tests for the Captcha API endpoint and captcha bypass behavior when disabled. - Added documentation for the Captcha API in the corresponding markdown file.
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import 'altcha';
|
||||
|
||||
// ALTCHA خودمیزبان: widget با گرفتن challenge از بکاند، proof-of-work را در
|
||||
// پسزمینهی مرورگر حل میکند و مقدار base64 حلشده را در event `verified` میدهد.
|
||||
// این مقدار باید در بدنهی درخواستِ endpoint عمومی با کلید `altcha` ارسال شود.
|
||||
|
||||
interface AltchaProps {
|
||||
onVerified: (payload: string) => void;
|
||||
challengeUrl?: string;
|
||||
}
|
||||
|
||||
// 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;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default function Altcha({ onVerified, challengeUrl = '/api/v1/altcha/challenge' }: AltchaProps) {
|
||||
const ref = useRef<HTMLElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const el = ref.current;
|
||||
if (!el) return;
|
||||
|
||||
const onStateChange = (e: Event) => {
|
||||
const detail = (e as CustomEvent).detail as { state?: string; payload?: string };
|
||||
if (detail?.state === 'verified' && detail.payload) {
|
||||
onVerified(detail.payload);
|
||||
}
|
||||
};
|
||||
|
||||
el.addEventListener('statechange', onStateChange);
|
||||
return () => el.removeEventListener('statechange', onStateChange);
|
||||
}, [onVerified]);
|
||||
|
||||
return <altcha-widget ref={ref as React.Ref<HTMLElement>} challengeurl={challengeUrl} />;
|
||||
}
|
||||
Reference in New Issue
Block a user