UNPKG

react-grecaptcha-v3

Version:

Google Recaptcha V3 for React.js based application. Keep website performance high while prioritizing security.

85 lines (84 loc) 3.11 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { createContext, useCallback, useEffect, useMemo, useRef, } from 'react'; import subscribeEvent from './subscribeEvent'; import unsubscribeEvent from './unsubscribeEvent'; import useHandleNextInQueue from './useHandleNextInQueue'; import useQueueRef from './useQueueRef'; import { getScriptSrc, maybeInjectScript, maybeRemoveScript } from './utils'; export const Context = createContext(null); export const defaultScriptId = 'rusted_labs_react_recaptcha_v3'; const ReCaptchaProvider = ({ siteKey, children, scriptProps = {}, useRecaptchaNet = false, enterprise = false, injectionDelay = null, }) => { const injectCallbackRef = useRef(null); const queueRef = useQueueRef(); const handleNextInQueue = useHandleNextInQueue(siteKey, queueRef); useEffect(() => { subscribeEvent(handleNextInQueue); return () => { unsubscribeEvent(handleNextInQueue); }; }, [handleNextInQueue]); useEffect(() => { const reCaptchaScriptId = scriptProps.id || defaultScriptId; if (null === siteKey) { maybeRemoveScript(reCaptchaScriptId); } else { const inject = () => { maybeInjectScript({ src: getScriptSrc({ enterprise, useRecaptchaNet, siteKey, }), appendTo: scriptProps.appendTo ?? 'head', id: reCaptchaScriptId, async: scriptProps.async ?? true, defer: scriptProps.defer ?? true, nonce: scriptProps.nonce, }); }; injectCallbackRef.current = inject; if (injectionDelay === null) { inject(); } else { const timeout = setTimeout(inject, injectionDelay); return () => { injectCallbackRef.current = null; maybeRemoveScript(reCaptchaScriptId); clearTimeout(timeout); }; } } return () => { maybeRemoveScript(reCaptchaScriptId); }; }, [ enterprise, handleNextInQueue, injectionDelay, scriptProps.appendTo, scriptProps.async, scriptProps.defer, scriptProps.id, scriptProps.nonce, siteKey, useRecaptchaNet, ]); const executeRecaptcha = useCallback(async (action) => { return new Promise((resolve, reject) => { queueRef.current.push({ action, onComplete: resolve, onError: reject, }); handleNextInQueue(); }); }, [handleNextInQueue, queueRef]); const contextValue = useMemo(() => ({ executeRecaptcha, injectScript: injectCallbackRef, }), [executeRecaptcha]); return _jsx(Context.Provider, { value: contextValue, children: children }); }; export default ReCaptchaProvider;