diff --git a/web/src/App.js b/web/src/App.js index 986f26e6..0955be69 100644 --- a/web/src/App.js +++ b/web/src/App.js @@ -33,6 +33,8 @@ import HomePage from "./basic/HomePage"; import CustomGithubCorner from "./CustomGithubCorner"; import * as Auth from "./auth/Auth"; +import RegisterPage from "./auth/RegisterPage"; +import ResultPage from "./auth/ResultPage"; import LoginPage from "./auth/LoginPage"; import SelfLoginPage from "./auth/SelfLoginPage"; import * as AuthBackend from "./auth/AuthBackend"; @@ -49,6 +51,7 @@ class App extends Component { classes: props, selectedMenuKey: 0, account: undefined, + uri: null, }; Setting.initServerUrl(); @@ -65,9 +68,20 @@ class App extends Component { this.getAccount(); } + componentDidUpdate() { + // eslint-disable-next-line no-restricted-globals + const uri = location.pathname; + if (this.state.uri !== uri) { + this.updateMenuKey(); + } + } + updateMenuKey() { // eslint-disable-next-line no-restricted-globals const uri = location.pathname; + this.setState({ + uri: uri, + }); if (uri === '/') { this.setState({ selectedMenuKey: 0 }); } else if (uri.includes('organizations')) { @@ -80,6 +94,12 @@ class App extends Component { this.setState({ selectedMenuKey: 4 }); } else if (uri.includes('tokens')) { this.setState({ selectedMenuKey: 5 }); + } else if (uri.includes('register')) { + this.setState({ selectedMenuKey: 100 }); + } else if (uri.includes('login')) { + this.setState({ selectedMenuKey: 101 }); + } else if (uri.includes('result')) { + this.setState({ selectedMenuKey: 100 }); } else { this.setState({ selectedMenuKey: -1 }); } @@ -116,7 +136,7 @@ class App extends Component { Setting.goToLink("/"); } else { - Setting.showMessage("error", `Logout failed: ${res.msg}`); + Setting.showMessage("error", `Failed to log out: ${res.msg}`); } }); } @@ -277,7 +297,7 @@ class App extends Component { { @@ -289,6 +309,8 @@ class App extends Component { + this.renderHomeIfLoggedIn()}/> + this.renderHomeIfLoggedIn()}/> this.renderHomeIfLoggedIn()}/> this.renderLoginIfNotLoggedIn()}/> diff --git a/web/src/auth/LoginPage.js b/web/src/auth/LoginPage.js index 196b6afd..547cd96a 100644 --- a/web/src/auth/LoginPage.js +++ b/web/src/auth/LoginPage.js @@ -88,7 +88,7 @@ class LoginPage extends React.Component { if (res.status === 'ok') { const responseType = this.state.type; if (responseType === "login") { - this.props.onLoggedIn(); + // this.props.onLoggedIn(); Util.showMessage("success", `Logged in successfully`); Util.goToLink("/"); } else if (responseType === "code") { @@ -97,7 +97,7 @@ class LoginPage extends React.Component { // Util.showMessage("success", `Authorization code: ${res.data}`); } } else { - Util.showMessage("error", `Log in failed:${res.msg}`); + Util.showMessage("error", `Failed to log in: ${res.msg}`); } }); }; diff --git a/web/src/auth/RegisterPage.js b/web/src/auth/RegisterPage.js new file mode 100644 index 00000000..24e39dd6 --- /dev/null +++ b/web/src/auth/RegisterPage.js @@ -0,0 +1,249 @@ +// Copyright 2021 The casbin 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 {Form, Input, Select, Checkbox, Button, Row, Col} from 'antd'; +import * as Setting from "../Setting"; +import * as AuthBackend from "./AuthBackend"; +import i18next from "i18next"; +import {Link} from "react-router-dom"; + +const { Option } = Select; + +const formItemLayout = { + labelCol: { + xs: { + span: 24, + }, + sm: { + span: 8, + }, + }, + wrapperCol: { + xs: { + span: 24, + }, + sm: { + span: 16, + }, + }, +}; + +const tailFormItemLayout = { + wrapperCol: { + xs: { + span: 24, + offset: 0, + }, + sm: { + span: 16, + offset: 8, + }, + }, +}; + +class RegisterPage extends React.Component { + constructor(props) { + super(props); + this.state = { + classes: props, + }; + + this.form = React.createRef(); + } + + onFinish(values) { + AuthBackend.register(values) + .then((res) => { + if (res.status === 'ok') { + this.props.history.push('/result'); + } else { + Setting.showMessage("error", `Failed to register: ${res.msg}`); + } + }); + } + + onFinishFailed(values, errorFields, outOfDate) { + this.form.current.scrollToField(errorFields[0].name); + } + + renderForm() { + const prefixSelector = ( + + + + ); + + return ( +
this.onFinish(values)} + onFinishFailed={(errorInfo) => this.onFinishFailed(errorInfo.values, errorInfo.errorFields, errorInfo.outOfDate)} + initialValues={{ + prefix: '001', + }} + style={{width: !Setting.isMobile() ? "400px" : "250px"}} + size="large" + > + + + + + + + + + + + + + + + + ({ + validator(rule, value) { + if (!value || getFieldValue('password') === value) { + return Promise.resolve(); + } + + return Promise.reject('Your confirmed password is inconsistent with the password'); + }, + }), + ]} + > + + + + + + + + Accept Terms of Use + + + + +    Have account? + + sign in now + + +
+ ) + } + + render() { + return ( +
+   + + + { + this.renderForm() + } + + +
+ ) + } +} + +export default RegisterPage; diff --git a/web/src/auth/ResultPage.js b/web/src/auth/ResultPage.js new file mode 100644 index 00000000..c9c87869 --- /dev/null +++ b/web/src/auth/ResultPage.js @@ -0,0 +1,46 @@ +// Copyright 2021 The casbin 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 { Result, Button } from 'antd'; + +class ResultPage extends React.Component { + constructor(props) { + super(props); + this.state = { + classes: props, + }; + } + + render() { + return ( +
+ + + + ]} + /> +
+ ); + } +} + +export default ResultPage;