feat: support all captcha for login (#1619)

* refactor: captcha modal

* feat: support all captcha when login

* chore: improve i18 in loginPage.js
This commit is contained in:
Yaodong Yu
2023-03-05 20:31:46 +08:00
committed by GitHub
parent f8bc87eb4e
commit e8a7b7ee9c
19 changed files with 160 additions and 247 deletions

View File

@ -86,8 +86,8 @@ func (captcha *AliyunCaptchaProvider) VerifyCaptcha(token, clientSecret string)
} }
type captchaResponse struct { type captchaResponse struct {
Code int `json:"Code"` Code string `json:"Code"`
Msg string `json:"Msg"` Message string `json:"Message"`
} }
captchaResp := &captchaResponse{} captchaResp := &captchaResponse{}
@ -96,8 +96,8 @@ func (captcha *AliyunCaptchaProvider) VerifyCaptcha(token, clientSecret string)
return false, err return false, err
} }
if captchaResp.Code != 100 { if captchaResp.Code != "100" {
return false, errors.New(captchaResp.Msg) return false, errors.New(captchaResp.Message)
} }
return true, nil return true, nil

View File

@ -51,8 +51,8 @@ func (c *ApiController) SendVerificationCode() {
dest := c.Ctx.Request.Form.Get("dest") dest := c.Ctx.Request.Form.Get("dest")
countryCode := c.Ctx.Request.Form.Get("countryCode") countryCode := c.Ctx.Request.Form.Get("countryCode")
checkType := c.Ctx.Request.Form.Get("checkType") checkType := c.Ctx.Request.Form.Get("checkType")
checkId := c.Ctx.Request.Form.Get("checkId") clientSecret := c.Ctx.Request.Form.Get("clientSecret")
checkKey := c.Ctx.Request.Form.Get("checkKey") captchaToken := c.Ctx.Request.Form.Get("captchaToken")
applicationId := c.Ctx.Request.Form.Get("applicationId") applicationId := c.Ctx.Request.Form.Get("applicationId")
method := c.Ctx.Request.Form.Get("method") method := c.Ctx.Request.Form.Get("method")
checkUser := c.Ctx.Request.Form.Get("checkUser") checkUser := c.Ctx.Request.Form.Get("checkUser")
@ -76,15 +76,15 @@ func (c *ApiController) SendVerificationCode() {
} }
if checkType != "none" { if checkType != "none" {
if checkKey == "" { if captchaToken == "" {
c.ResponseError(c.T("general:Missing parameter") + ": checkKey.") c.ResponseError(c.T("general:Missing parameter") + ": captchaToken.")
return return
} }
if captchaProvider := captcha.GetCaptchaProvider(checkType); captchaProvider == nil { if captchaProvider := captcha.GetCaptchaProvider(checkType); captchaProvider == nil {
c.ResponseError(c.T("general:don't support captchaProvider: ") + checkType) c.ResponseError(c.T("general:don't support captchaProvider: ") + checkType)
return return
} else if isHuman, err := captchaProvider.VerifyCaptcha(checkKey, checkId); err != nil { } else if isHuman, err := captchaProvider.VerifyCaptcha(captchaToken, clientSecret); err != nil {
c.ResponseError(err.Error()) c.ResponseError(err.Error())
return return
} else if !isHuman { } else if !isHuman {

View File

@ -380,7 +380,7 @@ func CheckToEnableCaptcha(application *Application) bool {
if providerItem.Provider == nil { if providerItem.Provider == nil {
continue continue
} }
if providerItem.Provider.Category == "Captcha" && providerItem.Provider.Type == "Default" { if providerItem.Provider.Category == "Captcha" {
return providerItem.Rule == "Always" return providerItem.Rule == "Always"
} }
} }

View File

@ -813,17 +813,17 @@ class ProviderEditPage extends React.Component {
</Col> </Col>
<Col span={22} > <Col span={22} >
<CaptchaPreview <CaptchaPreview
owner={this.state.provider.owner}
name={this.state.provider.name}
provider={this.state.provider} provider={this.state.provider}
providerName={this.state.providerName} providerName={this.state.providerName}
clientSecret={this.state.provider.clientSecret}
captchaType={this.state.provider.type} captchaType={this.state.provider.type}
subType={this.state.provider.subType} subType={this.state.provider.subType}
owner={this.state.provider.owner}
clientId={this.state.provider.clientId} clientId={this.state.provider.clientId}
name={this.state.provider.name} clientSecret={this.state.provider.clientSecret}
providerUrl={this.state.provider.providerUrl}
clientId2={this.state.provider.clientId2} clientId2={this.state.provider.clientId2}
clientSecret2={this.state.provider.clientSecret2} clientSecret2={this.state.provider.clientSecret2}
providerUrl={this.state.provider.providerUrl}
/> />
</Col> </Col>
</Row> </Row>

View File

@ -82,13 +82,13 @@ class LoginPage extends React.Component {
componentDidUpdate(prevProps, prevState, snapshot) { componentDidUpdate(prevProps, prevState, snapshot) {
if (this.state.application && !prevState.application) { if (this.state.application && !prevState.application) {
const defaultCaptchaProviderItems = this.getDefaultCaptchaProviderItems(this.state.application); const captchaProviderItems = this.getCaptchaProviderItems(this.state.application);
if (!defaultCaptchaProviderItems) { if (!captchaProviderItems) {
return; return;
} }
this.setState({enableCaptchaModal: defaultCaptchaProviderItems.some(providerItem => providerItem.rule === "Always")}); this.setState({enableCaptchaModal: captchaProviderItems.some(providerItem => providerItem.rule === "Always")});
} }
} }
@ -228,7 +228,7 @@ class LoginPage extends React.Component {
Setting.goToLinkSoft(ths, `/prompt/${application.name}?redirectUri=${oAuthParams.redirectUri}&code=${code}&state=${oAuthParams.state}`); Setting.goToLinkSoft(ths, `/prompt/${application.name}?redirectUri=${oAuthParams.redirectUri}&code=${code}&state=${oAuthParams.state}`);
} }
} else { } else {
Setting.showMessage("error", `Failed to sign in: ${res.msg}`); Setting.showMessage("error", `${i18next.t("application:Failed to log in")}: ${res.msg}`);
} }
}); });
} else { } else {
@ -262,13 +262,7 @@ class LoginPage extends React.Component {
if (this.state.loginMethod === "password" && this.state.enableCaptchaModal) { if (this.state.loginMethod === "password" && this.state.enableCaptchaModal) {
this.setState({ this.setState({
openCaptchaModal: true, openCaptchaModal: true,
verifyCaptcha: (captchaType, captchaToken, secret) => { values: values,
values["captchaType"] = captchaType;
values["captchaToken"] = captchaToken;
values["clientSecret"] = secret;
this.login(values);
},
}); });
} else { } else {
this.login(values); this.login(values);
@ -290,8 +284,6 @@ class LoginPage extends React.Component {
} }
Setting.showMessage("success", msg); Setting.showMessage("success", msg);
this.setState({openCaptchaModal: false});
if (casParams.service !== "") { if (casParams.service !== "") {
const st = res.data; const st = res.data;
const newUrl = new URL(casParams.service); const newUrl = new URL(casParams.service);
@ -299,8 +291,7 @@ class LoginPage extends React.Component {
window.location.href = newUrl.toString(); window.location.href = newUrl.toString();
} }
} else { } else {
this.setState({openCaptchaModal: false}); Setting.showMessage("error", `${i18next.t("application:Failed to log in")}: ${res.msg}`);
Setting.showMessage("error", `Failed to log in: ${res.msg}`);
} }
}); });
} else { } else {
@ -338,8 +329,7 @@ class LoginPage extends React.Component {
} }
} }
} else { } else {
this.setState({openCaptchaModal: false}); Setting.showMessage("error", `${i18next.t("application:Failed to log in")}: ${res.msg}`);
Setting.showMessage("error", `Failed to log in: ${res.msg}`);
} }
}); });
} }
@ -549,7 +539,7 @@ class LoginPage extends React.Component {
} }
} }
getDefaultCaptchaProviderItems(application) { getCaptchaProviderItems(application) {
const providers = application?.providers; const providers = application?.providers;
if (providers === undefined || providers === null) { if (providers === undefined || providers === null) {
@ -561,7 +551,7 @@ class LoginPage extends React.Component {
return false; return false;
} }
return providerItem.provider.category === "Captcha" && providerItem.provider.type === "Default"; return providerItem.provider.category === "Captcha";
}); });
} }
@ -570,22 +560,25 @@ class LoginPage extends React.Component {
return null; return null;
} }
const provider = this.getDefaultCaptchaProviderItems(application) const provider = this.getCaptchaProviderItems(application)
.filter(providerItem => providerItem.rule === "Always") .filter(providerItem => providerItem.rule === "Always")
.map(providerItem => providerItem.provider)[0]; .map(providerItem => providerItem.provider)[0];
return <CaptchaModal return <CaptchaModal
owner={provider.owner} owner={provider.owner}
name={provider.name} name={provider.name}
captchaType={provider.type} visible={this.state.openCaptchaModal}
subType={provider.subType} onOk={(captchaType, captchaToken, clientSecret) => {
clientId={provider.clientId} const values = this.state.values;
clientId2={provider.clientId2} values["captchaType"] = captchaType;
clientSecret={provider.clientSecret} values["captchaToken"] = captchaToken;
clientSecret2={provider.clientSecret2} values["clientSecret"] = clientSecret;
open={this.state.openCaptchaModal}
onOk={(captchaType, captchaToken, secret) => this.state.verifyCaptcha?.(captchaType, captchaToken, secret)} this.login(values);
canCancel={false} this.setState({openCaptchaModal: false});
}}
onCancel={() => this.setState({openCaptchaModal: false})}
isCurrentProvider={true}
/>; />;
} }

View File

@ -109,11 +109,11 @@ export function setPassword(userOwner, userName, oldPassword, newPassword) {
}).then(res => res.json()); }).then(res => res.json());
} }
export function sendCode(checkType, checkId, checkKey, method, countryCode = "", dest, type, applicationId, checkUser = "") { export function sendCode(checkType, captchaToken, clientSecret, method, countryCode = "", dest, type, applicationId, checkUser = "") {
const formData = new FormData(); const formData = new FormData();
formData.append("checkType", checkType); formData.append("checkType", checkType);
formData.append("checkId", checkId); formData.append("captchaToken", captchaToken);
formData.append("checkKey", checkKey); formData.append("clientSecret", clientSecret);
formData.append("method", method); formData.append("method", method);
formData.append("countryCode", countryCode); formData.append("countryCode", countryCode);
formData.append("dest", dest); formData.append("dest", dest);

View File

@ -19,60 +19,57 @@ import * as UserBackend from "../backend/UserBackend";
import {CaptchaWidget} from "./CaptchaWidget"; import {CaptchaWidget} from "./CaptchaWidget";
import {SafetyOutlined} from "@ant-design/icons"; import {SafetyOutlined} from "@ant-design/icons";
export const CaptchaModal = ({ export const CaptchaModal = (props) => {
owner, const {owner, name, visible, onOk, onCancel, isCurrentProvider} = props;
name,
captchaType, const [captchaType, setCaptchaType] = React.useState("none");
subType, const [clientId, setClientId] = React.useState("");
clientId, const [clientSecret, setClientSecret] = React.useState("");
clientId2, const [subType, setSubType] = React.useState("");
clientSecret, const [clientId2, setClientId2] = React.useState("");
clientSecret2, const [clientSecret2, setClientSecret2] = React.useState("");
open,
onOk, const [open, setOpen] = React.useState(false);
onCancel,
canCancel,
}) => {
const [visible, setVisible] = React.useState(false);
const [captchaImg, setCaptchaImg] = React.useState(""); const [captchaImg, setCaptchaImg] = React.useState("");
const [captchaToken, setCaptchaToken] = React.useState(""); const [captchaToken, setCaptchaToken] = React.useState("");
const [secret, setSecret] = React.useState(clientSecret);
const [secret2, setSecret2] = React.useState(clientSecret2);
const defaultInputRef = React.useRef(null); const defaultInputRef = React.useRef(null);
useEffect(() => { useEffect(() => {
setVisible(() => { if (visible) {
if (open) { loadCaptcha();
getCaptchaFromBackend(); } else {
} else { handleCancel();
cleanUp(); setOpen(false);
} }
return open; }, [visible]);
});
}, [open]);
const handleOk = () => { const handleOk = () => {
onOk?.(captchaType, captchaToken, secret); onOk?.(captchaType, captchaToken, clientSecret);
}; };
const handleCancel = () => { const handleCancel = () => {
setCaptchaToken("");
onCancel?.(); onCancel?.();
}; };
const cleanUp = () => { const loadCaptcha = () => {
setCaptchaToken(""); UserBackend.getCaptcha(owner, name, isCurrentProvider).then((res) => {
}; if (res.type === "none") {
handleOk();
const getCaptchaFromBackend = () => { } else if (res.type === "Default") {
UserBackend.getCaptcha(owner, name, true).then((res) => { setOpen(true);
if (captchaType === "Default") { setClientSecret(res.captchaId);
setSecret(res.captchaId);
setCaptchaImg(res.captchaImage); setCaptchaImg(res.captchaImage);
setCaptchaType("Default");
defaultInputRef.current?.focus();
} else { } else {
setSecret(res.clientSecret); setOpen(true);
setSecret2(res.clientSecret2); setCaptchaType(res.type);
setClientId(res.clientId);
setClientSecret(res.clientSecret);
setSubType(res.subType);
setClientId2(res.clientId2);
setClientSecret2(res.clientSecret2);
} }
}); });
}; };
@ -108,11 +105,11 @@ export const CaptchaModal = ({
); );
}; };
const onSubmit = (token) => { const onChange = (token) => {
setCaptchaToken(token); setCaptchaToken(token);
}; };
const renderCheck = () => { const renderCaptcha = () => {
if (captchaType === "Default") { if (captchaType === "Default") {
return renderDefaultCaptcha(); return renderDefaultCaptcha();
} else { } else {
@ -123,10 +120,10 @@ export const CaptchaModal = ({
captchaType={captchaType} captchaType={captchaType}
subType={subType} subType={subType}
siteKey={clientId} siteKey={clientId}
clientSecret={secret} clientSecret={clientSecret}
onChange={onSubmit} onChange={onChange}
clientId2={clientId2} clientId2={clientId2}
clientSecret2={secret2} clientSecret2={clientSecret2}
/> />
</Row> </Row>
</Col> </Col>
@ -141,37 +138,35 @@ export const CaptchaModal = ({
if (!regex.test(captchaToken)) { if (!regex.test(captchaToken)) {
isOkDisabled = true; isOkDisabled = true;
} }
} else if (captchaToken === "") {
isOkDisabled = true;
} }
if (canCancel) { return [
return [ <Button key="cancel" onClick={handleCancel}>{i18next.t("user:Cancel")}</Button>,
<Button key="cancel" onClick={handleCancel}>{i18next.t("user:Cancel")}</Button>, <Button key="ok" disabled={isOkDisabled} onClick={handleOk}>{i18next.t("user:OK")}</Button>,
<Button key="ok" disabled={isOkDisabled} type="primary" onClick={handleOk}>{i18next.t("user:OK")}</Button>, ];
];
} else {
return [
<Button key="ok" disabled={isOkDisabled} type="primary" onClick={handleOk}>{i18next.t("user:OK")}</Button>,
];
}
}; };
return ( return (
<React.Fragment> <Modal
<Modal closable={false}
closable={false} maskClosable={false}
maskClosable={false} destroyOnClose={true}
destroyOnClose={true} title={i18next.t("general:Captcha")}
title={i18next.t("general:Captcha")} open={open}
open={visible} okText={i18next.t("user:OK")}
width={348} cancelText={i18next.t("user:Cancel")}
footer={renderFooter()} width={350}
> footer={renderFooter()}
<div style={{marginTop: "20px", marginBottom: "50px"}}> onCancel={handleCancel}
{ onOk={handleOk}
renderCheck() >
} <div style={{marginTop: "20px", marginBottom: "50px"}}>
</div> {
</Modal> renderCaptcha()
</React.Fragment> }
</div>
</Modal>
); );
}; };

View File

@ -18,19 +18,9 @@ import i18next from "i18next";
import {CaptchaModal} from "./CaptchaModal"; import {CaptchaModal} from "./CaptchaModal";
import * as UserBackend from "../backend/UserBackend"; import * as UserBackend from "../backend/UserBackend";
export const CaptchaPreview = ({ export const CaptchaPreview = (props) => {
provider, const {owner, name, provider, captchaType, subType, clientId, clientSecret, clientId2, clientSecret2, providerUrl} = props;
clientSecret, const [visible, setVisible] = React.useState(false);
captchaType,
subType,
owner,
clientId,
name,
providerUrl,
clientId2,
clientSecret2,
}) => {
const [open, setOpen] = React.useState(false);
const clickPreview = () => { const clickPreview = () => {
provider.name = name; provider.name = name;
@ -42,13 +32,13 @@ export const CaptchaPreview = ({
// ProviderBackend.updateProvider(owner, providerName, provider).then(() => { // ProviderBackend.updateProvider(owner, providerName, provider).then(() => {
// setOpen(true); // setOpen(true);
// }); // });
setOpen(true); setVisible(true);
} else { } else {
setOpen(true); setVisible(true);
} }
}; };
const getButtonDisabled = () => { const isButtonDisabled = () => {
if (captchaType !== "Default") { if (captchaType !== "Default") {
if (!clientId || !clientSecret) { if (!clientId || !clientSecret) {
return true; return true;
@ -62,14 +52,14 @@ export const CaptchaPreview = ({
return false; return false;
}; };
const onOk = (captchaType, captchaToken, secret) => { const onOk = (captchaType, captchaToken, clientSecret) => {
UserBackend.verifyCaptcha(captchaType, captchaToken, secret).then(() => { UserBackend.verifyCaptcha(captchaType, captchaToken, clientSecret).then(() => {
setOpen(false); setVisible(false);
}); });
}; };
const onCancel = () => { const onCancel = () => {
setOpen(false); setVisible(false);
}; };
return ( return (
@ -78,23 +68,17 @@ export const CaptchaPreview = ({
style={{fontSize: 14}} style={{fontSize: 14}}
type={"primary"} type={"primary"}
onClick={clickPreview} onClick={clickPreview}
disabled={getButtonDisabled()} disabled={isButtonDisabled()}
> >
{i18next.t("general:Preview")} {i18next.t("general:Preview")}
</Button> </Button>
<CaptchaModal <CaptchaModal
owner={owner} owner={owner}
name={name} name={name}
captchaType={captchaType} visible={visible}
subType={subType}
clientId={clientId}
clientId2={clientId2}
clientSecret={clientSecret}
clientSecret2={clientSecret2}
open={open}
onOk={onOk} onOk={onOk}
onCancel={onCancel} onCancel={onCancel}
canCancel={true} isCurrentProvider={true}
/> />
</React.Fragment> </React.Fragment>
); );

View File

@ -14,7 +14,9 @@
import React, {useEffect} from "react"; import React, {useEffect} from "react";
export const CaptchaWidget = ({captchaType, subType, siteKey, clientSecret, onChange, clientId2, clientSecret2}) => { export const CaptchaWidget = (props) => {
const {captchaType, subType, siteKey, clientSecret, clientId2, clientSecret2, onChange} = props;
const loadScript = (src) => { const loadScript = (src) => {
const tag = document.createElement("script"); const tag = document.createElement("script");
tag.async = false; tag.async = false;

View File

@ -12,29 +12,21 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import {Button, Col, Input, Modal, Row} from "antd"; import {Button, Input} from "antd";
import React from "react"; import React from "react";
import i18next from "i18next"; import i18next from "i18next";
import * as UserBackend from "../backend/UserBackend"; import * as UserBackend from "../backend/UserBackend";
import {SafetyOutlined} from "@ant-design/icons"; import {SafetyOutlined} from "@ant-design/icons";
import {CaptchaWidget} from "./CaptchaWidget"; import {CaptchaModal} from "./CaptchaModal";
const {Search} = Input; const {Search} = Input;
export const SendCodeInput = (props) => { export const SendCodeInput = (props) => {
const {disabled, textBefore, onChange, onButtonClickArgs, application, method, countryCode} = props; const {disabled, textBefore, onChange, onButtonClickArgs, application, method, countryCode} = props;
const [visible, setVisible] = React.useState(false); const [visible, setVisible] = React.useState(false);
const [key, setKey] = React.useState("");
const [captchaImg, setCaptchaImg] = React.useState("");
const [checkType, setCheckType] = React.useState("");
const [checkId, setCheckId] = React.useState("");
const [buttonLeftTime, setButtonLeftTime] = React.useState(0); const [buttonLeftTime, setButtonLeftTime] = React.useState(0);
const [buttonLoading, setButtonLoading] = React.useState(false); const [buttonLoading, setButtonLoading] = React.useState(false);
const [buttonDisabled, setButtonDisabled] = React.useState(true);
const [clientId, setClientId] = React.useState("");
const [subType, setSubType] = React.useState("");
const [clientId2, setClientId2] = React.useState("");
const [clientSecret2, setClientSecret2] = React.useState("");
const handleCountDown = (leftTime = 60) => { const handleCountDown = (leftTime = 60) => {
let leftTimeSecond = leftTime; let leftTimeSecond = leftTime;
@ -50,11 +42,10 @@ export const SendCodeInput = (props) => {
setTimeout(countDown, 1000); setTimeout(countDown, 1000);
}; };
const handleOk = () => { const handleOk = (captchaType, captchaToken, clintSecret) => {
setVisible(false); setVisible(false);
setButtonLoading(true); setButtonLoading(true);
UserBackend.sendCode(checkType, checkId, key, method, countryCode, ...onButtonClickArgs).then(res => { UserBackend.sendCode(captchaType, captchaToken, clintSecret, method, countryCode, ...onButtonClickArgs).then(res => {
setKey("");
setButtonLoading(false); setButtonLoading(false);
if (res) { if (res) {
handleCountDown(60); handleCountDown(60);
@ -64,76 +55,6 @@ export const SendCodeInput = (props) => {
const handleCancel = () => { const handleCancel = () => {
setVisible(false); setVisible(false);
setKey("");
};
const loadCaptcha = () => {
UserBackend.getCaptcha(application.owner, application.name, false).then(res => {
if (res.type === "none") {
UserBackend.sendCode("none", "", "", method, countryCode, ...onButtonClickArgs).then(res => {
if (res) {
handleCountDown(60);
}
});
} else if (res.type === "Default") {
setCheckId(res.captchaId);
setCaptchaImg(res.captchaImage);
setCheckType("Default");
setVisible(true);
} else {
setCheckType(res.type);
setClientId(res.clientId);
setCheckId(res.clientSecret);
setVisible(true);
setSubType(res.subType);
setClientId2(res.clientId2);
setClientSecret2(res.clientSecret2);
}
});
};
const renderCaptcha = () => {
return (
<Col>
<Row
style={{
backgroundImage: `url('data:image/png;base64,${captchaImg}')`,
backgroundRepeat: "no-repeat",
height: "80px",
width: "200px",
borderRadius: "5px",
border: "1px solid #ccc",
marginBottom: 10,
}}
/>
<Row>
<Input autoFocus value={key} prefix={<SafetyOutlined />} placeholder={i18next.t("general:Captcha")} onPressEnter={handleOk} onChange={e => setKey(e.target.value)} />
</Row>
</Col>
);
};
const onSubmit = (token) => {
setButtonDisabled(false);
setKey(token);
};
const renderCheck = () => {
if (checkType === "Default") {
return renderCaptcha();
} else {
return (
<CaptchaWidget
captchaType={checkType}
subType={subType}
siteKey={clientId}
clientSecret={checkId}
onChange={onSubmit}
clientId2={clientId2}
clientSecret2={clientSecret2}
/>
);
}
}; };
return ( return (
@ -149,25 +70,16 @@ export const SendCodeInput = (props) => {
{buttonLeftTime > 0 ? `${buttonLeftTime} s` : buttonLoading ? i18next.t("code:Sending Code") : i18next.t("code:Send Code")} {buttonLeftTime > 0 ? `${buttonLeftTime} s` : buttonLoading ? i18next.t("code:Sending Code") : i18next.t("code:Send Code")}
</Button> </Button>
} }
onSearch={loadCaptcha} onSearch={() => setVisible(true)}
/> />
<Modal <CaptchaModal
closable={false} owner={application.owner}
maskClosable={false} name={application.name}
destroyOnClose={true} visible={visible}
title={i18next.t("general:Captcha")}
open={visible}
okText={i18next.t("user:OK")}
cancelText={i18next.t("user:Cancel")}
onOk={handleOk} onOk={handleOk}
onCancel={handleCancel} onCancel={handleCancel}
okButtonProps={{disabled: key.length !== 5 && buttonDisabled}} isCurrentProvider={false}
width={348} />
>
{
renderCheck()
}
</Modal>
</React.Fragment> </React.Fragment>
); );
}; };

View File

@ -38,6 +38,7 @@
"Enable signin session - Tooltip": "Aktiviere Anmeldesession - Tooltip", "Enable signin session - Tooltip": "Aktiviere Anmeldesession - Tooltip",
"Enable signup": "Anmeldung aktivieren", "Enable signup": "Anmeldung aktivieren",
"Enable signup - Tooltip": "Whether to allow users to sign up", "Enable signup - Tooltip": "Whether to allow users to sign up",
"Failed to log in": "Failed to log in",
"Failed to sign in": "Anmeldung fehlgeschlagen", "Failed to sign in": "Anmeldung fehlgeschlagen",
"File uploaded successfully": "Datei erfolgreich hochgeladen", "File uploaded successfully": "Datei erfolgreich hochgeladen",
"Follow organization theme": "Follow organization theme", "Follow organization theme": "Follow organization theme",
@ -311,6 +312,7 @@
"No account?": "Kein Konto?", "No account?": "Kein Konto?",
"Or sign in with another account": "Oder melden Sie sich mit einem anderen Konto an", "Or sign in with another account": "Oder melden Sie sich mit einem anderen Konto an",
"Password": "Passwort", "Password": "Passwort",
"Password - Tooltip": "Password - Tooltip",
"Please input your Email or Phone!": "Please input your Email or Phone!", "Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your code!": "Bitte gib deinen Code ein!", "Please input your code!": "Bitte gib deinen Code ein!",
"Please input your password!": "Bitte geben Sie Ihr Passwort ein!", "Please input your password!": "Bitte geben Sie Ihr Passwort ein!",
@ -653,6 +655,7 @@
"The input is not valid Email!": "Die Eingabe ist ungültig!", "The input is not valid Email!": "Die Eingabe ist ungültig!",
"The input is not valid Phone!": "Die Eingabe ist nicht gültig!", "The input is not valid Phone!": "Die Eingabe ist nicht gültig!",
"Username": "Benutzername", "Username": "Benutzername",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "Ihr Konto wurde erstellt!", "Your account has been created!": "Ihr Konto wurde erstellt!",
"Your confirmed password is inconsistent with the password!": "Ihr bestätigtes Passwort stimmt nicht mit dem Passwort überein!", "Your confirmed password is inconsistent with the password!": "Ihr bestätigtes Passwort stimmt nicht mit dem Passwort überein!",
"sign in now": "jetzt anmelden" "sign in now": "jetzt anmelden"

View File

@ -38,6 +38,7 @@
"Enable signin session - Tooltip": "Enable signin session - Tooltip", "Enable signin session - Tooltip": "Enable signin session - Tooltip",
"Enable signup": "Enable signup", "Enable signup": "Enable signup",
"Enable signup - Tooltip": "Enable signup - Tooltip", "Enable signup - Tooltip": "Enable signup - Tooltip",
"Failed to log in": "Failed to log in",
"Failed to sign in": "Failed to sign in", "Failed to sign in": "Failed to sign in",
"File uploaded successfully": "File uploaded successfully", "File uploaded successfully": "File uploaded successfully",
"Follow organization theme": "Follow organization theme", "Follow organization theme": "Follow organization theme",
@ -311,6 +312,7 @@
"No account?": "No account?", "No account?": "No account?",
"Or sign in with another account": "Or sign in with another account", "Or sign in with another account": "Or sign in with another account",
"Password": "Password", "Password": "Password",
"Password - Tooltip": "Password - Tooltip",
"Please input your Email or Phone!": "Please input your Email or Phone!", "Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your code!": "Please input your code!", "Please input your code!": "Please input your code!",
"Please input your password!": "Please input your password!", "Please input your password!": "Please input your password!",
@ -653,6 +655,7 @@
"The input is not valid Email!": "The input is not valid Email!", "The input is not valid Email!": "The input is not valid Email!",
"The input is not valid Phone!": "The input is not valid Phone!", "The input is not valid Phone!": "The input is not valid Phone!",
"Username": "Username", "Username": "Username",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "Your account has been created!", "Your account has been created!": "Your account has been created!",
"Your confirmed password is inconsistent with the password!": "Your confirmed password is inconsistent with the password!", "Your confirmed password is inconsistent with the password!": "Your confirmed password is inconsistent with the password!",
"sign in now": "sign in now" "sign in now": "sign in now"

View File

@ -38,6 +38,7 @@
"Enable signin session - Tooltip": "Enable signin session - Tooltip", "Enable signin session - Tooltip": "Enable signin session - Tooltip",
"Enable signup": "Habilitar nuevos registros", "Enable signup": "Habilitar nuevos registros",
"Enable signup - Tooltip": "Habilitar nuevos registros - Tooltip", "Enable signup - Tooltip": "Habilitar nuevos registros - Tooltip",
"Failed to log in": "Failed to log in",
"Failed to sign in": "Failed to sign in", "Failed to sign in": "Failed to sign in",
"File uploaded successfully": "El archivo ha sido subido con éxito", "File uploaded successfully": "El archivo ha sido subido con éxito",
"Follow organization theme": "Follow organization theme", "Follow organization theme": "Follow organization theme",
@ -311,6 +312,7 @@
"No account?": "¿No estás registrado?", "No account?": "¿No estás registrado?",
"Or sign in with another account": "O inicia sesión con otra cuenta", "Or sign in with another account": "O inicia sesión con otra cuenta",
"Password": "Contraseña", "Password": "Contraseña",
"Password - Tooltip": "Password - Tooltip",
"Please input your Email or Phone!": "Please input your Email or Phone!", "Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your code!": "¡Por favor ingrese su código!", "Please input your code!": "¡Por favor ingrese su código!",
"Please input your password!": "¡Por favor ingrese su contraseña!", "Please input your password!": "¡Por favor ingrese su contraseña!",
@ -653,6 +655,7 @@
"The input is not valid Email!": "El valor ingresado no es un Email válido!", "The input is not valid Email!": "El valor ingresado no es un Email válido!",
"The input is not valid Phone!": "El valor ingresado no es un Teléfono válido!", "The input is not valid Phone!": "El valor ingresado no es un Teléfono válido!",
"Username": "Nombre de usuario", "Username": "Nombre de usuario",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "¡Tu cuenta ha sido creada!", "Your account has been created!": "¡Tu cuenta ha sido creada!",
"Your confirmed password is inconsistent with the password!": "¡La confirmación de su contraseña es inconsistente!", "Your confirmed password is inconsistent with the password!": "¡La confirmación de su contraseña es inconsistente!",
"sign in now": "iniciar sesión ahora" "sign in now": "iniciar sesión ahora"

View File

@ -38,6 +38,7 @@
"Enable signin session - Tooltip": "Activer la session de connexion - infobulle", "Enable signin session - Tooltip": "Activer la session de connexion - infobulle",
"Enable signup": "Activer l'inscription", "Enable signup": "Activer l'inscription",
"Enable signup - Tooltip": "Whether to allow users to sign up", "Enable signup - Tooltip": "Whether to allow users to sign up",
"Failed to log in": "Failed to log in",
"Failed to sign in": "Failed to sign in", "Failed to sign in": "Failed to sign in",
"File uploaded successfully": "Fichier téléchargé avec succès", "File uploaded successfully": "Fichier téléchargé avec succès",
"Follow organization theme": "Follow organization theme", "Follow organization theme": "Follow organization theme",
@ -311,6 +312,7 @@
"No account?": "Pas de compte ?", "No account?": "Pas de compte ?",
"Or sign in with another account": "Ou connectez-vous avec un autre compte", "Or sign in with another account": "Ou connectez-vous avec un autre compte",
"Password": "Mot de passe", "Password": "Mot de passe",
"Password - Tooltip": "Password - Tooltip",
"Please input your Email or Phone!": "Please input your Email or Phone!", "Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your code!": "Veuillez saisir votre code !", "Please input your code!": "Veuillez saisir votre code !",
"Please input your password!": "Veuillez saisir votre mot de passe !", "Please input your password!": "Veuillez saisir votre mot de passe !",
@ -653,6 +655,7 @@
"The input is not valid Email!": "L'entrée n'est pas un email valide !", "The input is not valid Email!": "L'entrée n'est pas un email valide !",
"The input is not valid Phone!": "L'entrée n'est pas un téléphone valide !", "The input is not valid Phone!": "L'entrée n'est pas un téléphone valide !",
"Username": "Nom d'utilisateur", "Username": "Nom d'utilisateur",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "Votre compte a été créé !", "Your account has been created!": "Votre compte a été créé !",
"Your confirmed password is inconsistent with the password!": "Votre mot de passe confirmé est incompatible avec le mot de passe !", "Your confirmed password is inconsistent with the password!": "Votre mot de passe confirmé est incompatible avec le mot de passe !",
"sign in now": "connectez-vous maintenant" "sign in now": "connectez-vous maintenant"

View File

@ -38,6 +38,7 @@
"Enable signin session - Tooltip": "Enable signin session - Tooltip", "Enable signin session - Tooltip": "Enable signin session - Tooltip",
"Enable signup": "サインアップを有効にする", "Enable signup": "サインアップを有効にする",
"Enable signup - Tooltip": "Whether to allow users to sign up", "Enable signup - Tooltip": "Whether to allow users to sign up",
"Failed to log in": "Failed to log in",
"Failed to sign in": "Failed to sign in", "Failed to sign in": "Failed to sign in",
"File uploaded successfully": "ファイルが正常にアップロードされました", "File uploaded successfully": "ファイルが正常にアップロードされました",
"Follow organization theme": "Follow organization theme", "Follow organization theme": "Follow organization theme",
@ -311,6 +312,7 @@
"No account?": "アカウントがありませんか?", "No account?": "アカウントがありませんか?",
"Or sign in with another account": "または別のアカウントでサインイン", "Or sign in with another account": "または別のアカウントでサインイン",
"Password": "パスワード", "Password": "パスワード",
"Password - Tooltip": "Password - Tooltip",
"Please input your Email or Phone!": "Please input your Email or Phone!", "Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your code!": "コードを入力してください!", "Please input your code!": "コードを入力してください!",
"Please input your password!": "パスワードを入力してください!", "Please input your password!": "パスワードを入力してください!",
@ -653,6 +655,7 @@
"The input is not valid Email!": "入力されたメールアドレスが無効です!", "The input is not valid Email!": "入力されたメールアドレスが無効です!",
"The input is not valid Phone!": "入力された電話番号が正しくありません!", "The input is not valid Phone!": "入力された電話番号が正しくありません!",
"Username": "ユーザー名", "Username": "ユーザー名",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "あなたのアカウントが作成されました!", "Your account has been created!": "あなたのアカウントが作成されました!",
"Your confirmed password is inconsistent with the password!": "確認されたパスワードがパスワードと一致していません!", "Your confirmed password is inconsistent with the password!": "確認されたパスワードがパスワードと一致していません!",
"sign in now": "今すぐサインイン" "sign in now": "今すぐサインイン"

View File

@ -38,6 +38,7 @@
"Enable signin session - Tooltip": "Enable signin session - Tooltip", "Enable signin session - Tooltip": "Enable signin session - Tooltip",
"Enable signup": "Enable signup", "Enable signup": "Enable signup",
"Enable signup - Tooltip": "Whether to allow users to sign up", "Enable signup - Tooltip": "Whether to allow users to sign up",
"Failed to log in": "Failed to log in",
"Failed to sign in": "Failed to sign in", "Failed to sign in": "Failed to sign in",
"File uploaded successfully": "File uploaded successfully", "File uploaded successfully": "File uploaded successfully",
"Follow organization theme": "Follow organization theme", "Follow organization theme": "Follow organization theme",
@ -311,6 +312,7 @@
"No account?": "No account?", "No account?": "No account?",
"Or sign in with another account": "Or sign in with another account", "Or sign in with another account": "Or sign in with another account",
"Password": "Password", "Password": "Password",
"Password - Tooltip": "Password - Tooltip",
"Please input your Email or Phone!": "Please input your Email or Phone!", "Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your code!": "Please input your code!", "Please input your code!": "Please input your code!",
"Please input your password!": "Please input your password!", "Please input your password!": "Please input your password!",
@ -653,6 +655,7 @@
"The input is not valid Email!": "The input is not valid Email!", "The input is not valid Email!": "The input is not valid Email!",
"The input is not valid Phone!": "The input is not valid Phone!", "The input is not valid Phone!": "The input is not valid Phone!",
"Username": "Username", "Username": "Username",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "Your account has been created!", "Your account has been created!": "Your account has been created!",
"Your confirmed password is inconsistent with the password!": "Your confirmed password is inconsistent with the password!", "Your confirmed password is inconsistent with the password!": "Your confirmed password is inconsistent with the password!",
"sign in now": "sign in now" "sign in now": "sign in now"

View File

@ -38,6 +38,7 @@
"Enable signin session - Tooltip": "Включить сеанс входа - Подсказка", "Enable signin session - Tooltip": "Включить сеанс входа - Подсказка",
"Enable signup": "Включить регистрацию", "Enable signup": "Включить регистрацию",
"Enable signup - Tooltip": "Whether to allow users to sign up", "Enable signup - Tooltip": "Whether to allow users to sign up",
"Failed to log in": "Failed to log in",
"Failed to sign in": "Failed to sign in", "Failed to sign in": "Failed to sign in",
"File uploaded successfully": "Файл успешно загружен", "File uploaded successfully": "Файл успешно загружен",
"Follow organization theme": "Follow organization theme", "Follow organization theme": "Follow organization theme",
@ -311,6 +312,7 @@
"No account?": "Нет учетной записи?", "No account?": "Нет учетной записи?",
"Or sign in with another account": "Или войти с помощью другой учетной записи", "Or sign in with another account": "Или войти с помощью другой учетной записи",
"Password": "Пароль", "Password": "Пароль",
"Password - Tooltip": "Password - Tooltip",
"Please input your Email or Phone!": "Please input your Email or Phone!", "Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your code!": "Пожалуйста, введите ваш код!", "Please input your code!": "Пожалуйста, введите ваш код!",
"Please input your password!": "Пожалуйста, введите ваш пароль!", "Please input your password!": "Пожалуйста, введите ваш пароль!",
@ -653,6 +655,7 @@
"The input is not valid Email!": "Ввод не является допустимым Email!", "The input is not valid Email!": "Ввод не является допустимым Email!",
"The input is not valid Phone!": "Введен неверный телефон!", "The input is not valid Phone!": "Введен неверный телефон!",
"Username": "Имя пользователя", "Username": "Имя пользователя",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "Ваша учетная запись была создана!", "Your account has been created!": "Ваша учетная запись была создана!",
"Your confirmed password is inconsistent with the password!": "Подтвержденный пароль не соответствует паролю!", "Your confirmed password is inconsistent with the password!": "Подтвержденный пароль не соответствует паролю!",
"sign in now": "войти сейчас" "sign in now": "войти сейчас"

View File

@ -38,6 +38,7 @@
"Enable signin session - Tooltip": "Enable signin session - Tooltip", "Enable signin session - Tooltip": "Enable signin session - Tooltip",
"Enable signup": "Enable signup", "Enable signup": "Enable signup",
"Enable signup - Tooltip": "Enable signup - Tooltip", "Enable signup - Tooltip": "Enable signup - Tooltip",
"Failed to log in": "Failed to log in",
"Failed to sign in": "Failed to sign in", "Failed to sign in": "Failed to sign in",
"File uploaded successfully": "File uploaded successfully", "File uploaded successfully": "File uploaded successfully",
"Follow organization theme": "Follow organization theme", "Follow organization theme": "Follow organization theme",
@ -311,6 +312,7 @@
"No account?": "No account?", "No account?": "No account?",
"Or sign in with another account": "Or sign in with another account", "Or sign in with another account": "Or sign in with another account",
"Password": "Password", "Password": "Password",
"Password - Tooltip": "Password - Tooltip",
"Please input your Email or Phone!": "Please input your Email or Phone!", "Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your code!": "Please input your code!", "Please input your code!": "Please input your code!",
"Please input your password!": "Please input your password!", "Please input your password!": "Please input your password!",
@ -653,6 +655,7 @@
"The input is not valid Email!": "The input is not valid Email!", "The input is not valid Email!": "The input is not valid Email!",
"The input is not valid Phone!": "The input is not valid Phone!", "The input is not valid Phone!": "The input is not valid Phone!",
"Username": "Username", "Username": "Username",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "Your account has been created!", "Your account has been created!": "Your account has been created!",
"Your confirmed password is inconsistent with the password!": "Your confirmed password is inconsistent with the password!", "Your confirmed password is inconsistent with the password!": "Your confirmed password is inconsistent with the password!",
"sign in now": "sign in now" "sign in now": "sign in now"

View File

@ -38,6 +38,7 @@
"Enable signin session - Tooltip": "从应用登录Casdoor后Casdoor是否保持会话", "Enable signin session - Tooltip": "从应用登录Casdoor后Casdoor是否保持会话",
"Enable signup": "启用注册", "Enable signup": "启用注册",
"Enable signup - Tooltip": "是否允许用户注册", "Enable signup - Tooltip": "是否允许用户注册",
"Failed to log in": "登录失败",
"Failed to sign in": "登录失败", "Failed to sign in": "登录失败",
"File uploaded successfully": "文件上传成功", "File uploaded successfully": "文件上传成功",
"Follow organization theme": "使用组织主题", "Follow organization theme": "使用组织主题",
@ -311,6 +312,7 @@
"No account?": "没有账号?", "No account?": "没有账号?",
"Or sign in with another account": "或者,登录其他账号", "Or sign in with another account": "或者,登录其他账号",
"Password": "密码", "Password": "密码",
"Password - Tooltip": "密码",
"Please input your Email or Phone!": "请输入您的Email或手机号!", "Please input your Email or Phone!": "请输入您的Email或手机号!",
"Please input your code!": "请输入您的验证码!", "Please input your code!": "请输入您的验证码!",
"Please input your password!": "请输入您的密码!", "Please input your password!": "请输入您的密码!",
@ -653,6 +655,7 @@
"The input is not valid Email!": "您输入的电子邮箱格式有误!", "The input is not valid Email!": "您输入的电子邮箱格式有误!",
"The input is not valid Phone!": "您输入的手机号格式有误!", "The input is not valid Phone!": "您输入的手机号格式有误!",
"Username": "用户名", "Username": "用户名",
"Username - Tooltip": "唯一的用户名",
"Your account has been created!": "您的账号已创建!", "Your account has been created!": "您的账号已创建!",
"Your confirmed password is inconsistent with the password!": "您两次输入的密码不一致!", "Your confirmed password is inconsistent with the password!": "您两次输入的密码不一致!",
"sign in now": "立即登录" "sign in now": "立即登录"