feat: add captcha page (#3144)

This commit is contained in:
Love98 2024-08-26 23:22:53 +08:00 committed by GitHub
parent dce0a96dea
commit 230a77e3e3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 120 additions and 1 deletions

View File

@ -344,7 +344,8 @@ class App extends Component {
window.location.pathname.startsWith("/cas") ||
window.location.pathname.startsWith("/select-plan") ||
window.location.pathname.startsWith("/buy-plan") ||
window.location.pathname.startsWith("/qrcode") ;
window.location.pathname.startsWith("/qrcode") ||
window.location.pathname.startsWith("/captcha");
}
onClick = ({key}) => {

116
web/src/CaptchaPage.js Normal file
View File

@ -0,0 +1,116 @@
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import React from "react";
import {CaptchaModal} from "./common/modal/CaptchaModal";
import * as ApplicationBackend from "./backend/ApplicationBackend";
import * as Setting from "./Setting";
class CaptchaPage extends React.Component {
constructor(props) {
super(props);
const params = new URLSearchParams(this.props.location.search);
this.state = {
owner: "admin",
application: null,
clientId: params.get("client_id"),
applicationName: params.get("state"),
redirectUri: params.get("redirect_uri"),
};
}
componentDidMount() {
this.getApplication();
}
onUpdateApplication(application) {
this.setState({
application: application,
});
}
getApplication() {
if (this.state.applicationName === null) {
return null;
}
ApplicationBackend.getApplication(this.state.owner, this.state.applicationName)
.then((res) => {
if (res.status === "error") {
this.onUpdateApplication(null);
this.setState({
msg: res.msg,
});
return ;
}
this.onUpdateApplication(res.data);
});
}
getCaptchaProviderItems(application) {
const providers = application?.providers;
if (providers === undefined || providers === null) {
return null;
}
return providers.filter(providerItem => {
if (providerItem.provider === undefined || providerItem.provider === null) {
return false;
}
return providerItem.provider.category === "Captcha";
});
}
callback(values) {
Setting.goToLink(`${this.state.redirectUri}?code=${values.captchaToken}&type=${values.captchaType}&secret=${values.clientSecret}&applicationId=${values.applicationId}`);
}
renderCaptchaModal(application) {
const captchaProviderItems = this.getCaptchaProviderItems(application);
if (captchaProviderItems === null) {
return null;
}
const alwaysProviderItems = captchaProviderItems.filter(providerItem => providerItem.rule === "Always");
const dynamicProviderItems = captchaProviderItems.filter(providerItem => providerItem.rule === "Dynamic");
const provider = alwaysProviderItems.length > 0
? alwaysProviderItems[0].provider
: dynamicProviderItems[0].provider;
return <CaptchaModal
owner={provider.owner}
name={provider.name}
visible={true}
onOk={(captchaType, captchaToken, clientSecret) => {
const values = {
captchaType: captchaType,
captchaToken: captchaToken,
clientSecret: clientSecret,
applicationId: `${provider.owner}/${provider.name}`,
};
this.callback(values);
}}
onCancel={() => this.callback({captchaType: "none", captchaToken: "", clientSecret: ""})}
isCurrentProvider={true}
/>;
}
render() {
return (
this.renderCaptchaModal(this.state.application)
);
}
}
export default CaptchaPage;

View File

@ -32,6 +32,7 @@ import {authConfig} from "./auth/Auth";
import ProductBuyPage from "./ProductBuyPage";
import PaymentResultPage from "./PaymentResultPage";
import QrCodePage from "./QrCodePage";
import CaptchaPage from "./CaptchaPage";
import CustomHead from "./basic/CustomHead";
class EntryPage extends React.Component {
@ -120,6 +121,7 @@ class EntryPage extends React.Component {
<Route exact path="/buy-plan/:owner/:pricingName" render={(props) => <ProductBuyPage {...this.props} pricing={this.state.pricing} onUpdatePricing={onUpdatePricing} {...props} />} />
<Route exact path="/buy-plan/:owner/:pricingName/result" render={(props) => <PaymentResultPage {...this.props} pricing={this.state.pricing} onUpdatePricing={onUpdatePricing} {...props} />} />
<Route exact path="/qrcode/:owner/:paymentName" render={(props) => <QrCodePage {...this.props} onUpdateApplication={onUpdateApplication} {...props} />} />
<Route exact path="/captcha" render={(props) => <CaptchaPage {...props} />} />
</Switch>
</div>
</React.Fragment>