diff --git a/captcha/provider.go b/captcha/provider.go index fe652d42..d7901cd0 100644 --- a/captcha/provider.go +++ b/captcha/provider.go @@ -26,6 +26,10 @@ func GetCaptchaProvider(captchaType string) CaptchaProvider { return NewDefaultCaptchaProvider() case "reCAPTCHA": return NewReCaptchaProvider() + case "reCAPTCHA v2": + return NewReCaptchaProvider() + case "reCAPTCHA v3": + return NewReCaptchaProvider() case "Aliyun Captcha": return NewAliyunCaptchaProvider() case "hCaptcha": diff --git a/web/src/Setting.js b/web/src/Setting.js index 11fdf416..6163c2d5 100644 --- a/web/src/Setting.js +++ b/web/src/Setting.js @@ -287,6 +287,14 @@ export const OtherProviderInfo = { logo: `${StaticBaseUrl}/img/social_recaptcha.png`, url: "https://www.google.com/recaptcha", }, + "reCAPTCHA v2": { + logo: `${StaticBaseUrl}/img/social_recaptcha.png`, + url: "https://www.google.com/recaptcha", + }, + "reCAPTCHA v3": { + logo: `${StaticBaseUrl}/img/social_recaptcha.png`, + url: "https://www.google.com/recaptcha", + }, "hCaptcha": { logo: `${StaticBaseUrl}/img/social_hcaptcha.png`, url: "https://www.hcaptcha.com", @@ -1088,7 +1096,8 @@ export function getProviderTypeOptions(category) { } else if (category === "Captcha") { return ([ {id: "Default", name: "Default"}, - {id: "reCAPTCHA", name: "reCAPTCHA"}, + {id: "reCAPTCHA v2", name: "reCAPTCHA v2"}, + {id: "reCAPTCHA v3", name: "reCAPTCHA v3"}, {id: "hCaptcha", name: "hCaptcha"}, {id: "Aliyun Captcha", name: "Aliyun Captcha"}, {id: "GEETEST", name: "GEETEST"}, diff --git a/web/src/common/CaptchaWidget.js b/web/src/common/CaptchaWidget.js index 58523c25..412c0769 100644 --- a/web/src/common/CaptchaWidget.js +++ b/web/src/common/CaptchaWidget.js @@ -27,7 +27,8 @@ export const CaptchaWidget = (props) => { useEffect(() => { switch (captchaType) { - case "reCAPTCHA": { + case "reCAPTCHA" : + case "reCAPTCHA v2": { const reTimer = setInterval(() => { if (!window.grecaptcha) { loadScript("https://recaptcha.net/recaptcha/api.js"); @@ -42,6 +43,32 @@ export const CaptchaWidget = (props) => { }, 300); break; } + case "reCAPTCHA v3": { + const reTimer = setInterval(() => { + if (!window.grecaptcha) { + loadScript(`https://recaptcha.net/recaptcha/api.js?render=${siteKey}`); + } + if (window.grecaptcha && window.grecaptcha.render) { + const clientId = window.grecaptcha.render("captcha", { + "sitekey": siteKey, + "badge": "inline", + "size": "invisible", + "callback": onChange, + "error-callback": function() { + const logoWidth = `${document.getElementById("captcha").offsetWidth + 40}px`; + document.getElementsByClassName("grecaptcha-logo")[0].firstChild.style.width = logoWidth; + document.getElementsByClassName("grecaptcha-badge")[0].style.width = logoWidth; + }, + }); + + window.grecaptcha.ready(function() { + window.grecaptcha.execute(clientId, {action: "submit"}); + }); + clearInterval(reTimer); + } + }, 300); + break; + } case "hCaptcha": { const hTimer = setInterval(() => { if (!window.hcaptcha) { diff --git a/web/src/common/modal/CaptchaModal.js b/web/src/common/modal/CaptchaModal.js index 4676f87a..8771d191 100644 --- a/web/src/common/modal/CaptchaModal.js +++ b/web/src/common/modal/CaptchaModal.js @@ -115,7 +115,7 @@ export const CaptchaModal = (props) => { } else { return (