70 lines
1.8 KiB
JavaScript
70 lines
1.8 KiB
JavaScript
|
import { randomString } from "matrix-js-sdk/src/randomstring";
|
||
|
import { useEffect, useCallback, useRef, useState } from "react";
|
||
|
|
||
|
const RECAPTCHA_SCRIPT_URL =
|
||
|
"https://www.recaptcha.net/recaptcha/api.js?onload=mxOnRecaptchaLoaded&render=explicit";
|
||
|
|
||
|
export function useRecaptcha(sitekey) {
|
||
|
const [recaptchaId] = useState(() => randomString(16));
|
||
|
const resolvePromiseRef = useRef();
|
||
|
|
||
|
useEffect(() => {
|
||
|
if (!sitekey) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const onRecaptchaLoaded = () => {
|
||
|
if (!document.getElementById(recaptchaId)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
window.grecaptcha.render(recaptchaId, {
|
||
|
sitekey,
|
||
|
size: "invisible",
|
||
|
callback: (response) => {
|
||
|
if (resolvePromiseRef.current) {
|
||
|
resolvePromiseRef.current(response);
|
||
|
}
|
||
|
},
|
||
|
});
|
||
|
};
|
||
|
|
||
|
if (
|
||
|
typeof window.grecaptcha !== "undefined" &&
|
||
|
typeof window.grecaptcha.render === "function"
|
||
|
) {
|
||
|
onRecaptchaLoaded();
|
||
|
} else {
|
||
|
window.mxOnRecaptchaLoaded = onRecaptchaLoaded;
|
||
|
|
||
|
if (!document.querySelector(`script[src="${RECAPTCHA_SCRIPT_URL}"]`)) {
|
||
|
const scriptTag = document.createElement("script");
|
||
|
scriptTag.src = RECAPTCHA_SCRIPT_URL;
|
||
|
scriptTag.async = true;
|
||
|
document.body.appendChild(scriptTag);
|
||
|
}
|
||
|
}
|
||
|
}, [recaptchaId, sitekey]);
|
||
|
|
||
|
const execute = useCallback(() => {
|
||
|
if (!window.grecaptcha) {
|
||
|
return Promise.reject(new Error("Recaptcha not loaded"));
|
||
|
}
|
||
|
|
||
|
return new Promise((resolve) => {
|
||
|
resolvePromiseRef.current = resolve;
|
||
|
window.grecaptcha.execute();
|
||
|
});
|
||
|
}, [recaptchaId]);
|
||
|
|
||
|
const reset = useCallback(() => {
|
||
|
if (window.grecaptcha) {
|
||
|
window.grecaptcha.reset();
|
||
|
}
|
||
|
}, [recaptchaId]);
|
||
|
|
||
|
console.log(recaptchaId);
|
||
|
|
||
|
return { execute, reset, recaptchaId };
|
||
|
}
|