qinglong/src/pages/setting/security.tsx
2022-09-18 20:40:59 +08:00

260 lines
6.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useEffect, useState } from 'react';
import { Typography, Input, Form, Button, message, Avatar, Upload } from 'antd';
import { request } from '@/utils/http';
import config from '@/utils/config';
import { history } from '@umijs/max';
import QRCode from 'qrcode.react';
import { PageLoading } from '@ant-design/pro-layout';
import { UploadOutlined, UserOutlined } from '@ant-design/icons';
import ImgCrop from 'antd-img-crop';
import 'antd/es/slider/style';
const { Title, Link } = Typography;
const SecuritySettings = ({ user, userChange }: any) => {
const [loading, setLoading] = useState(false);
const [twoFactorActivated, setTwoFactorActivated] = useState<boolean>();
const [twoFactoring, setTwoFactoring] = useState(false);
const [twoFactorInfo, setTwoFactorInfo] = useState<any>();
const [code, setCode] = useState<string>();
const [avatar, setAvatar] = useState<string>();
const handleOk = (values: any) => {
request
.put(`${config.apiPrefix}user`, {
data: {
username: values.username,
password: values.password,
},
})
.then((data: any) => {
localStorage.removeItem(config.authKey);
history.push('/login');
})
.catch((error: any) => {
console.log(error);
});
};
const activeOrDeactiveTwoFactor = () => {
if (twoFactorActivated) {
deactiveTowFactor();
} else {
getTwoFactorInfo();
setTwoFactoring(true);
}
};
const deactiveTowFactor = () => {
request
.put(`${config.apiPrefix}user/two-factor/deactive`)
.then((data: any) => {
if (data.data) {
setTwoFactorActivated(false);
userChange();
}
})
.catch((error: any) => {
console.log(error);
});
};
const completeTowFactor = () => {
setLoading(true);
request
.put(`${config.apiPrefix}user/two-factor/active`, { data: { code } })
.then((data: any) => {
if (data.data) {
message.success('激活成功');
setTwoFactoring(false);
setTwoFactorActivated(true);
userChange();
} else {
message.success('验证失败');
}
})
.catch((error: any) => {
console.log(error);
})
.finally(() => setLoading(false));
};
const getTwoFactorInfo = () => {
request
.get(`${config.apiPrefix}user/two-factor/init`)
.then((data: any) => {
setTwoFactorInfo(data.data);
})
.catch((error: any) => {
console.log(error);
});
};
const onChange = (e) => {
if (e.file && e.file.response) {
setAvatar(`/api/static/${e.file.response.data}`);
userChange();
}
};
useEffect(() => {
setTwoFactorActivated(user && user.twoFactorActivated);
setAvatar(user.avatar && `/api/static/${user.avatar}`);
}, [user]);
return twoFactoring ? (
<>
{twoFactorInfo ? (
<div>
<Title level={5}></Title>
Google Authenticator
<Link
href="https://www.microsoft.com/en-us/security/mobile-authenticator-app"
target="_blank"
>
Microsoft Authenticator
</Link>
<Link href="https://authy.com/download/" target="_blank">
Authy
</Link>
<Link
href="https://support.1password.com/one-time-passwords/"
target="_blank"
>
1Password
</Link>
<Link
href="https://support.logmeininc.com/lastpass/help/lastpass-authenticator-lp030014"
target="_blank"
>
LastPass Authenticator
</Link>
<Title style={{ marginTop: 5 }} level={5}>
</Title>
使 {twoFactorInfo?.secret}
<div style={{ marginTop: 10 }}>
<QRCode
style={{ border: '1px solid #21262d', borderRadius: 6 }}
includeMargin={true}
size={187}
value={twoFactorInfo?.url}
/>
</div>
<Title style={{ marginTop: 5 }} level={5}>
</Title>
6
<Input
style={{ margin: '10px 0 10px 0', display: 'block', maxWidth: 200 }}
value={code}
onChange={(e) => setCode(e.target.value)}
placeholder="123456"
/>
<Button type="primary" loading={loading} onClick={completeTowFactor}>
</Button>
</div>
) : (
<PageLoading />
)}
</>
) : (
<>
<div
style={{
fontSize: 18,
borderBottom: '1px solid #f0f0f0',
marginBottom: 8,
paddingBottom: 4,
}}
>
</div>
<Form onFinish={handleOk} layout="vertical">
<Form.Item
label="用户名"
name="username"
rules={[{ required: true }]}
hasFeedback
style={{ maxWidth: 300 }}
>
<Input placeholder="用户名" />
</Form.Item>
<Form.Item
label="密码"
name="password"
rules={[
{ required: true },
{
pattern: /^(?!admin$).*$/,
message: '密码不能为admin',
},
]}
hasFeedback
style={{ maxWidth: 300 }}
>
<Input type="password" placeholder="密码" />
</Form.Item>
<Button type="primary" htmlType="submit">
</Button>
</Form>
<div
style={{
fontSize: 18,
borderBottom: '1px solid #f0f0f0',
marginBottom: 8,
paddingBottom: 4,
marginTop: 16,
}}
>
</div>
<Button
type="primary"
danger={twoFactorActivated}
onClick={activeOrDeactiveTwoFactor}
>
{twoFactorActivated ? '禁用' : '启用'}
</Button>
<div
style={{
fontSize: 18,
borderBottom: '1px solid #f0f0f0',
marginBottom: 8,
paddingBottom: 4,
marginTop: 16,
}}
>
</div>
<Avatar size={128} shape="square" icon={<UserOutlined />} src={avatar} />
<ImgCrop rotate>
<Upload
method="put"
showUploadList={false}
maxCount={1}
action="/api/user/avatar"
onChange={onChange}
name="avatar"
headers={{
Authorization: `Bearer ${localStorage.getItem(config.authKey)}`,
}}
>
<Button icon={<UploadOutlined />} style={{ marginLeft: 8 }}>
</Button>
</Upload>
</ImgCrop>
</>
);
};
export default SecuritySettings;