Files
myeasycms-v2/packages/features/auth/src/captcha/client/use-captcha.tsx
Giancarlo Buomprisco f6c635aac3 chore: bump version to 2.21.6 in package.json and enhance captcha integration across auth components (#418)
- 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.
2025-12-02 21:40:56 +08:00

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],
);
}