295 lines
7.5 KiB
JavaScript
295 lines
7.5 KiB
JavaScript
// Copyright 2021 99cloud
|
|
//
|
|
// 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, { Component } from 'react';
|
|
import { Input, Button, Select, Row, Col } from 'antd';
|
|
import { inject, observer } from 'mobx-react';
|
|
import { Link } from 'react-router-dom';
|
|
import { InfoCircleFilled } from '@ant-design/icons';
|
|
import SimpleForm from 'components/SimpleForm';
|
|
import globalSkylineStore from 'stores/skyline/skyline';
|
|
import i18n from 'core/i18n';
|
|
import { isEmpty } from 'lodash';
|
|
import styles from './index.less';
|
|
|
|
@inject('rootStore')
|
|
@observer
|
|
export default class Login extends Component {
|
|
constructor(props) {
|
|
super(props);
|
|
this.init();
|
|
this.state = {
|
|
error: false,
|
|
message: '',
|
|
loading: false,
|
|
};
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.getDomains();
|
|
this.getRegions();
|
|
}
|
|
|
|
async getDomains() {
|
|
await this.store.fetchDomainList();
|
|
this.updateDefaultValue();
|
|
}
|
|
|
|
async getRegions() {
|
|
await this.store.fetchRegionList();
|
|
this.updateDefaultValue();
|
|
}
|
|
|
|
get rootStore() {
|
|
return this.props.rootStore;
|
|
}
|
|
|
|
get info() {
|
|
const { info = {} } = this.rootStore;
|
|
return info || {};
|
|
}
|
|
|
|
get productName() {
|
|
const {
|
|
product_name: { zh = t('Cloud Platform'), en = 'Cloud Platform' } = {},
|
|
} = this.info;
|
|
const { isLocaleZh } = i18n;
|
|
return isLocaleZh ? zh : en;
|
|
}
|
|
|
|
get domains() {
|
|
return (this.store.domains || []).map((it) => ({
|
|
label: it,
|
|
value: it,
|
|
}));
|
|
}
|
|
|
|
get regions() {
|
|
return (this.store.regions || []).map((it) => ({
|
|
label: it,
|
|
value: it,
|
|
}));
|
|
}
|
|
|
|
get nextPage() {
|
|
const { location = {} } = this.props;
|
|
const { search } = location;
|
|
if (search) {
|
|
return search.split('=')[1];
|
|
}
|
|
return '/base/overview';
|
|
}
|
|
|
|
get defaultValue() {
|
|
const data = {};
|
|
if (this.regions.length === 1) {
|
|
data.region = this.regions[0].value;
|
|
}
|
|
if (this.domains.length === 1) {
|
|
data.domain = this.domains[0].value;
|
|
}
|
|
return data;
|
|
}
|
|
|
|
get formItems() {
|
|
const { error, loading } = this.state;
|
|
// eslint-disable-next-line no-unused-vars
|
|
const buttonProps = {
|
|
block: true,
|
|
type: 'primary',
|
|
};
|
|
return [
|
|
{
|
|
name: 'error',
|
|
hidden: !error,
|
|
render: () => (
|
|
<div className={styles['login-error']}>
|
|
<InfoCircleFilled />
|
|
{this.getErrorMessage()}
|
|
</div>
|
|
),
|
|
},
|
|
{
|
|
name: 'region',
|
|
required: true,
|
|
message: t('Please select your Region!'),
|
|
render: () => (
|
|
<Select placeholder={t('Select a region')} options={this.regions} />
|
|
),
|
|
},
|
|
{
|
|
name: 'domain',
|
|
required: true,
|
|
message: t('Please select your Domain!'),
|
|
render: () => (
|
|
<Select placeholder={t('Select a domain')} options={this.domains} />
|
|
),
|
|
},
|
|
{
|
|
name: 'username',
|
|
required: true,
|
|
message: t('Please input your Username!'),
|
|
render: () => <Input placeholder={t('Username')} />,
|
|
},
|
|
{
|
|
name: 'password',
|
|
required: true,
|
|
message: t('Please input your Password!'),
|
|
render: () => <Input.Password placeholder={t('Password')} />,
|
|
},
|
|
{
|
|
name: 'extra',
|
|
hidden: true,
|
|
render: () => (
|
|
<Row gutter={8}>
|
|
<Col span={12}>
|
|
<Link to="password">{t('Forgot your password?')}</Link>
|
|
</Col>
|
|
<Col span={12}>
|
|
<Link to="register" className={styles.register}>
|
|
{t('Sign up')}
|
|
</Link>
|
|
</Col>
|
|
</Row>
|
|
),
|
|
},
|
|
{
|
|
name: 'submit',
|
|
render: () => (
|
|
<Row gutter={8}>
|
|
<Col span={12}>
|
|
<Button
|
|
loading={loading}
|
|
type="primary"
|
|
htmlType="submit"
|
|
className="login-form-button"
|
|
>
|
|
{t('Log in')}
|
|
</Button>
|
|
</Col>
|
|
</Row>
|
|
),
|
|
},
|
|
];
|
|
}
|
|
|
|
getUserId = (str) => str.split(':')[1].trim().split('.')[0];
|
|
|
|
onFinish = (values) => {
|
|
this.setState({
|
|
loading: true,
|
|
});
|
|
const { domain, password, region, username } = values;
|
|
const body = { domain, password, region, username };
|
|
this.rootStore.login(body).then(
|
|
() => {
|
|
this.setState({
|
|
loading: false,
|
|
error: false,
|
|
});
|
|
if (this.rootStore.user && !isEmpty(this.rootStore.user)) {
|
|
this.rootStore.routing.push(this.nextPage);
|
|
}
|
|
},
|
|
(error) => {
|
|
this.setState({
|
|
loading: false,
|
|
});
|
|
const {
|
|
data: { detail },
|
|
} = error.response;
|
|
if (
|
|
detail.indexOf(
|
|
'The password is expired and needs to be changed for user'
|
|
) >= 0
|
|
) {
|
|
const userId = this.getUserId(detail);
|
|
const data = {
|
|
region: values.region,
|
|
oldPassword: values.password,
|
|
userId,
|
|
};
|
|
this.rootStore.setPasswordInfo(data);
|
|
this.rootStore.routing.push('/auth/changepassword');
|
|
} else {
|
|
this.setState({
|
|
error: true,
|
|
message: detail,
|
|
});
|
|
}
|
|
}
|
|
);
|
|
};
|
|
|
|
onGetCaptcha = () => {
|
|
if (this.formRef) {
|
|
return this.formRef.current.validateFields(['username']);
|
|
// const values = this.formRef.current.getFieldsValue();
|
|
// console.log(values);
|
|
}
|
|
return Promise.resolve();
|
|
};
|
|
|
|
getErrorMessage() {
|
|
const { message } = this.state;
|
|
if (message.includes('The account is locked for user')) {
|
|
return t(
|
|
'Frequent login failure will cause the account to be temporarily locked, please operate after 5 minutes'
|
|
);
|
|
}
|
|
if (message.includes('The account is disabled for user')) {
|
|
return t('The user has been disabled, please contact the administrator');
|
|
}
|
|
if (
|
|
message.includes('You are not authorized for any projects or domains')
|
|
) {
|
|
return t(
|
|
'If you are not authorized to access any project, or if the project you are involved in has been deleted or disabled, contact the platform administrator to reassign the project'
|
|
);
|
|
}
|
|
return t('Username or password is incorrect');
|
|
}
|
|
|
|
updateDefaultValue = () => {
|
|
this.formRef.current.resetFields();
|
|
if (this.formRef.current && this.formRef.current.resetFields) {
|
|
this.formRef.current.resetFields();
|
|
}
|
|
};
|
|
|
|
init() {
|
|
this.store = globalSkylineStore;
|
|
this.formRef = React.createRef();
|
|
}
|
|
|
|
render() {
|
|
return (
|
|
<>
|
|
<h1 className={styles.welcome}>
|
|
{t('Welcome, {name}', { name: this.productName })}
|
|
</h1>
|
|
<SimpleForm
|
|
formItems={this.formItems}
|
|
name="normal_login"
|
|
className={styles.login_form}
|
|
initialValues={this.defaultValue}
|
|
onFinish={this.onFinish}
|
|
formRef={this.formRef}
|
|
size="large"
|
|
/>
|
|
</>
|
|
);
|
|
}
|
|
}
|