diff --git a/web/src/auth/LoginPage.js b/web/src/auth/LoginPage.js index 81d8a3ce..d215f864 100644 --- a/web/src/auth/LoginPage.js +++ b/web/src/auth/LoginPage.js @@ -437,18 +437,26 @@ class LoginPage extends React.Component { values["password"] = passwordCipher; } const captchaRule = this.getCaptchaRule(this.getApplicationObj()); - if (captchaRule === CaptchaRule.Always) { - this.setState({ - openCaptchaModal: true, - values: values, - }); - return; - } else if (captchaRule === CaptchaRule.Dynamic) { - this.checkCaptchaStatus(values); - return; - } else if (captchaRule === CaptchaRule.InternetOnly) { - this.checkCaptchaStatus(values); - return; + const application = this.getApplicationObj(); + const noModal = application?.signinItems.map(signinItem => signinItem.name === "Captcha" && signinItem.rule === "inline").includes(true); + if (!noModal) { + if (captchaRule === CaptchaRule.Always) { + this.setState({ + openCaptchaModal: true, + values: values, + }); + return; + } else if (captchaRule === CaptchaRule.Dynamic) { + this.checkCaptchaStatus(values); + return; + } else if (captchaRule === CaptchaRule.InternetOnly) { + this.checkCaptchaStatus(values); + return; + } + } else { + values["captchaType"] = this.state?.captchaValues?.captchaType; + values["captchaToken"] = this.state?.captchaValues?.captchaToken; + values["clientSecret"] = this.state?.captchaValues?.clientSecret; } } this.login(values); @@ -775,7 +783,7 @@ class LoginPage extends React.Component { > } { - this.renderCaptchaModal(application) + application?.signinItems.map(signinItem => signinItem.name === "Captcha" && signinItem.rule === "inline").includes(true) ? null : this.renderCaptchaModal(application, false) } ); @@ -819,6 +827,8 @@ class LoginPage extends React.Component { ); + } else if (signinItem.name === "Captcha" && signinItem.rule === "inline") { + return this.renderCaptchaModal(application, true); } else if (signinItem.name.startsWith("Text ") || signinItem?.isCustom) { return (
@@ -964,7 +974,7 @@ class LoginPage extends React.Component { }); } - renderCaptchaModal(application) { + renderCaptchaModal(application, noModal) { if (this.getCaptchaRule(this.getApplicationObj()) === CaptchaRule.Never) { return null; } @@ -993,6 +1003,12 @@ class LoginPage extends React.Component { owner={provider.owner} name={provider.name} visible={this.state.openCaptchaModal} + noModal={noModal} + onUpdateToken={(captchaType, captchaToken, clientSecret) => { + this.setState({captchaValues: { + captchaType, captchaToken, clientSecret, + }}); + }} onOk={(captchaType, captchaToken, clientSecret) => { const values = this.state.values; values["captchaType"] = captchaType; diff --git a/web/src/common/modal/CaptchaModal.js b/web/src/common/modal/CaptchaModal.js index 16dab111..2c20e297 100644 --- a/web/src/common/modal/CaptchaModal.js +++ b/web/src/common/modal/CaptchaModal.js @@ -20,7 +20,7 @@ import {CaptchaWidget} from "../CaptchaWidget"; import {SafetyOutlined} from "@ant-design/icons"; export const CaptchaModal = (props) => { - const {owner, name, visible, onOk, onCancel, isCurrentProvider} = props; + const {owner, name, visible, onOk, onUpdateToken, onCancel, isCurrentProvider, noModal} = props; const [captchaType, setCaptchaType] = React.useState("none"); const [clientId, setClientId] = React.useState(""); @@ -36,16 +36,16 @@ export const CaptchaModal = (props) => { const defaultInputRef = React.useRef(null); useEffect(() => { - if (visible) { + if (visible || noModal) { loadCaptcha(); } else { handleCancel(); setOpen(false); } - }, [visible]); + }, [visible, noModal]); useEffect(() => { - if (captchaToken !== "" && captchaType !== "Default") { + if (captchaToken !== "" && captchaType !== "Default" && !noModal) { handleOk(); } }, [captchaToken]); @@ -81,6 +81,36 @@ export const CaptchaModal = (props) => { }; const renderDefaultCaptcha = () => { + if (noModal) { + return ( +