- Updated application version from 2.21.4 to 2.21.6 in package.json. - Added "verifyingCaptcha" message to auth.json for improved user feedback during captcha verification. - Enhanced captcha handling in various authentication components, including MagicLinkAuthContainer, PasswordResetRequestContainer, and SignUpContainer, to reflect loading states and improve user experience.
87 lines
2.1 KiB
TypeScript
87 lines
2.1 KiB
TypeScript
'use client';
|
|
|
|
import { useCallback, useMemo, useRef, useState } from 'react';
|
|
|
|
import type { TurnstileInstance } from '@marsidev/react-turnstile';
|
|
|
|
import { CaptchaField } from './captcha-field';
|
|
|
|
/**
|
|
* @name useCaptcha
|
|
* @description Zero-boilerplate hook for captcha integration.
|
|
* Manages token state and instance internally, exposing a clean API.
|
|
*
|
|
* @example
|
|
* ```tsx
|
|
* function SignInForm({ captchaSiteKey }) {
|
|
* const captcha = useCaptcha({ siteKey: captchaSiteKey });
|
|
*
|
|
* const handleSubmit = async (data) => {
|
|
* await signIn({ ...data, captchaToken: captcha.token });
|
|
* captcha.reset();
|
|
* };
|
|
*
|
|
* return (
|
|
* <form onSubmit={handleSubmit}>
|
|
* {captcha.field}
|
|
* <button>Submit</button>
|
|
* </form>
|
|
* );
|
|
* }
|
|
* ```
|
|
*/
|
|
export function useCaptcha(
|
|
{ siteKey, nonce }: { siteKey?: string; nonce?: string } = {
|
|
siteKey: undefined,
|
|
nonce: undefined,
|
|
},
|
|
) {
|
|
const [token, setToken] = useState('');
|
|
const instanceRef = useRef<TurnstileInstance | null>(null);
|
|
|
|
const reset = useCallback(() => {
|
|
instanceRef.current?.reset();
|
|
setToken('');
|
|
}, []);
|
|
|
|
const handleTokenChange = useCallback((newToken: string) => {
|
|
setToken(newToken);
|
|
}, []);
|
|
|
|
const handleInstanceChange = useCallback(
|
|
(instance: TurnstileInstance | null) => {
|
|
instanceRef.current = instance;
|
|
},
|
|
[],
|
|
);
|
|
|
|
const field = useMemo(
|
|
() => (
|
|
<CaptchaField
|
|
siteKey={siteKey}
|
|
onTokenChange={handleTokenChange}
|
|
onInstanceChange={handleInstanceChange}
|
|
nonce={nonce}
|
|
/>
|
|
),
|
|
[siteKey, nonce, handleTokenChange, handleInstanceChange],
|
|
);
|
|
|
|
// Ready when captcha is not configured (no siteKey) or token is available
|
|
const isReady = !siteKey || token !== '';
|
|
|
|
return useMemo(
|
|
() => ({
|
|
/** The current captcha token */
|
|
token,
|
|
/** Whether the captcha is ready (not configured or token available) */
|
|
isReady,
|
|
/** Reset the captcha (clears token and resets widget) */
|
|
reset,
|
|
/** The captcha field component to render */
|
|
field,
|
|
}),
|
|
[token, isReady, reset, field],
|
|
);
|
|
}
|