feat: refresh inline captcha on login failure (#4108)

This commit is contained in:
Attack825
2025-08-21 10:29:56 +08:00
committed by GitHub
parent e533ff1ee1
commit f7bc822087
2 changed files with 18 additions and 1 deletions

View File

@@ -46,6 +46,7 @@ const FaceRecognitionModal = lazy(() => import("../common/modal/FaceRecognitionM
class LoginPage extends React.Component {
constructor(props) {
super(props);
this.captchaRef = React.createRef();
this.state = {
classes: props,
type: props.type,
@@ -466,6 +467,7 @@ class LoginPage extends React.Component {
login(values) {
// here we are supposed to determine whether Casdoor is working as an OAuth server or CAS server
values["language"] = this.state.userLang ?? "";
const usedCaptcha = this.state.captchaValues !== undefined;
if (this.state.type === "cas") {
// CAS
const casParams = Util.getCasParameters();
@@ -492,6 +494,9 @@ class LoginPage extends React.Component {
Setting.checkLoginMfa(res, values, casParams, loginHandler, this);
} else {
Setting.showMessage("error", `${i18next.t("application:Failed to sign in")}: ${res.msg}`);
if (usedCaptcha) {
this.captchaRef.current?.loadCaptcha?.();
}
}
}).finally(() => {
this.setState({loginLoading: false});
@@ -565,6 +570,9 @@ class LoginPage extends React.Component {
Setting.checkLoginMfa(res, values, oAuthParams, loginHandler, this);
} else {
Setting.showMessage("error", `${i18next.t("application:Failed to sign in")}: ${res.msg}`);
if (usedCaptcha) {
this.captchaRef.current?.loadCaptcha?.();
}
}
}).finally(() => {
this.setState({loginLoading: false});
@@ -1124,6 +1132,7 @@ class LoginPage extends React.Component {
}}
onCancel={() => this.setState({openCaptchaModal: false, loginLoading: false})}
isCurrentProvider={true}
innerRef={this.captchaRef}
/>;
}

View File

@@ -20,7 +20,7 @@ import {CaptchaWidget} from "../CaptchaWidget";
import {SafetyOutlined} from "@ant-design/icons";
export const CaptchaModal = (props) => {
const {owner, name, visible, onOk, onUpdateToken, onCancel, isCurrentProvider, noModal} = props;
const {owner, name, visible, onOk, onUpdateToken, onCancel, isCurrentProvider, noModal, innerRef} = props;
const [captchaType, setCaptchaType] = React.useState("none");
const [clientId, setClientId] = React.useState("");
@@ -59,6 +59,14 @@ export const CaptchaModal = (props) => {
onCancel?.();
};
useEffect(() => {
if (innerRef) {
innerRef.current = {
loadCaptcha: loadCaptcha,
};
}
}, [innerRef]);
const loadCaptcha = () => {
UserBackend.getCaptcha(owner, name, isCurrentProvider).then((res) => {
if (res.type === "none") {