|
|
@@ -17,12 +17,25 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
For commercial licensing, please contact support@quantumnous.com
|
|
|
*/
|
|
|
import { API, showError, showSuccess, showWarning } from '../../../../helpers';
|
|
|
-import { Banner, Button, Card, Checkbox, Divider, Input, Modal, Tag, Typography, Steps, Space, Badge } from '@douyinfe/semi-ui';
|
|
|
+import {
|
|
|
+ Banner,
|
|
|
+ Button,
|
|
|
+ Card,
|
|
|
+ Checkbox,
|
|
|
+ Divider,
|
|
|
+ Input,
|
|
|
+ Modal,
|
|
|
+ Tag,
|
|
|
+ Typography,
|
|
|
+ Steps,
|
|
|
+ Space,
|
|
|
+ Badge,
|
|
|
+} from '@douyinfe/semi-ui';
|
|
|
import {
|
|
|
IconShield,
|
|
|
IconAlertTriangle,
|
|
|
IconRefresh,
|
|
|
- IconCopy
|
|
|
+ IconCopy,
|
|
|
} from '@douyinfe/semi-icons';
|
|
|
import React, { useEffect, useState } from 'react';
|
|
|
|
|
|
@@ -35,7 +48,7 @@ const TwoFASetting = ({ t }) => {
|
|
|
const [status, setStatus] = useState({
|
|
|
enabled: false,
|
|
|
locked: false,
|
|
|
- backup_codes_remaining: 0
|
|
|
+ backup_codes_remaining: 0,
|
|
|
});
|
|
|
|
|
|
// 模态框状态
|
|
|
@@ -96,7 +109,7 @@ const TwoFASetting = ({ t }) => {
|
|
|
setLoading(true);
|
|
|
try {
|
|
|
const res = await API.post('/api/user/2fa/enable', {
|
|
|
- code: verificationCode
|
|
|
+ code: verificationCode,
|
|
|
});
|
|
|
if (res.data.success) {
|
|
|
showSuccess(t('两步验证启用成功!'));
|
|
|
@@ -130,7 +143,7 @@ const TwoFASetting = ({ t }) => {
|
|
|
setLoading(true);
|
|
|
try {
|
|
|
const res = await API.post('/api/user/2fa/disable', {
|
|
|
- code: verificationCode
|
|
|
+ code: verificationCode,
|
|
|
});
|
|
|
if (res.data.success) {
|
|
|
showSuccess(t('两步验证已禁用'));
|
|
|
@@ -158,7 +171,7 @@ const TwoFASetting = ({ t }) => {
|
|
|
setLoading(true);
|
|
|
try {
|
|
|
const res = await API.post('/api/user/2fa/backup_codes', {
|
|
|
- code: verificationCode
|
|
|
+ code: verificationCode,
|
|
|
});
|
|
|
if (res.data.success) {
|
|
|
setBackupCodes(res.data.data.backup_codes);
|
|
|
@@ -177,11 +190,14 @@ const TwoFASetting = ({ t }) => {
|
|
|
|
|
|
// 通用复制函数
|
|
|
const copyTextToClipboard = (text, successMessage = t('已复制到剪贴板')) => {
|
|
|
- navigator.clipboard.writeText(text).then(() => {
|
|
|
- showSuccess(successMessage);
|
|
|
- }).catch(() => {
|
|
|
- showError(t('复制失败,请手动复制'));
|
|
|
- });
|
|
|
+ navigator.clipboard
|
|
|
+ .writeText(text)
|
|
|
+ .then(() => {
|
|
|
+ showSuccess(successMessage);
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ showError(t('复制失败,请手动复制'));
|
|
|
+ });
|
|
|
};
|
|
|
|
|
|
const copyBackupCodes = () => {
|
|
|
@@ -192,28 +208,25 @@ const TwoFASetting = ({ t }) => {
|
|
|
// 备用码展示组件
|
|
|
const BackupCodesDisplay = ({ codes, title, onCopy }) => {
|
|
|
return (
|
|
|
- <Card
|
|
|
- className="!rounded-xl"
|
|
|
- style={{ width: '100%' }}
|
|
|
- >
|
|
|
- <div className="space-y-3">
|
|
|
- <div className="flex items-center justify-between">
|
|
|
- <Text strong className="text-slate-700 dark:text-slate-200">
|
|
|
+ <Card className='!rounded-xl' style={{ width: '100%' }}>
|
|
|
+ <div className='space-y-3'>
|
|
|
+ <div className='flex items-center justify-between'>
|
|
|
+ <Text strong className='text-slate-700 dark:text-slate-200'>
|
|
|
{title}
|
|
|
</Text>
|
|
|
</div>
|
|
|
|
|
|
- <div className="grid grid-cols-1 sm:grid-cols-2 gap-2">
|
|
|
+ <div className='grid grid-cols-1 sm:grid-cols-2 gap-2'>
|
|
|
{codes.map((code, index) => (
|
|
|
- <div
|
|
|
- key={index}
|
|
|
- className="rounded-lg p-3"
|
|
|
- >
|
|
|
- <div className="flex items-center justify-between">
|
|
|
- <Text code className="text-sm font-mono text-slate-700 dark:text-slate-200">
|
|
|
+ <div key={index} className='rounded-lg p-3'>
|
|
|
+ <div className='flex items-center justify-between'>
|
|
|
+ <Text
|
|
|
+ code
|
|
|
+ className='text-sm font-mono text-slate-700 dark:text-slate-200'
|
|
|
+ >
|
|
|
{code}
|
|
|
</Text>
|
|
|
- <Text type="quaternary" className="text-xs">
|
|
|
+ <Text type='quaternary' className='text-xs'>
|
|
|
#{(index + 1).toString().padStart(2, '0')}
|
|
|
</Text>
|
|
|
</div>
|
|
|
@@ -223,11 +236,11 @@ const TwoFASetting = ({ t }) => {
|
|
|
|
|
|
<Divider margin={12} />
|
|
|
<Button
|
|
|
- type="primary"
|
|
|
- theme="solid"
|
|
|
+ type='primary'
|
|
|
+ theme='solid'
|
|
|
icon={<IconCopy />}
|
|
|
onClick={onCopy}
|
|
|
- className="!rounded-lg !bg-slate-600 hover:!bg-slate-700 w-full"
|
|
|
+ className='!rounded-lg !bg-slate-600 hover:!bg-slate-700 w-full'
|
|
|
>
|
|
|
{t('复制所有代码')}
|
|
|
</Button>
|
|
|
@@ -243,24 +256,24 @@ const TwoFASetting = ({ t }) => {
|
|
|
{currentStep > 0 && (
|
|
|
<Button
|
|
|
onClick={() => setCurrentStep(currentStep - 1)}
|
|
|
- className="!rounded-lg"
|
|
|
+ className='!rounded-lg'
|
|
|
>
|
|
|
{t('上一步')}
|
|
|
</Button>
|
|
|
)}
|
|
|
{currentStep < 2 ? (
|
|
|
<Button
|
|
|
- type="primary"
|
|
|
- theme="solid"
|
|
|
+ type='primary'
|
|
|
+ theme='solid'
|
|
|
onClick={() => setCurrentStep(currentStep + 1)}
|
|
|
- className="!rounded-lg !bg-slate-600 hover:!bg-slate-700"
|
|
|
+ className='!rounded-lg !bg-slate-600 hover:!bg-slate-700'
|
|
|
>
|
|
|
{t('下一步')}
|
|
|
</Button>
|
|
|
) : (
|
|
|
<Button
|
|
|
- type="primary"
|
|
|
- theme="solid"
|
|
|
+ type='primary'
|
|
|
+ theme='solid'
|
|
|
loading={loading}
|
|
|
onClick={() => {
|
|
|
if (!verificationCode) {
|
|
|
@@ -269,7 +282,7 @@ const TwoFASetting = ({ t }) => {
|
|
|
}
|
|
|
handleEnable2FA();
|
|
|
}}
|
|
|
- className="!rounded-lg !bg-slate-600 hover:!bg-slate-700"
|
|
|
+ className='!rounded-lg !bg-slate-600 hover:!bg-slate-700'
|
|
|
>
|
|
|
{t('完成设置并启用两步验证')}
|
|
|
</Button>
|
|
|
@@ -288,17 +301,17 @@ const TwoFASetting = ({ t }) => {
|
|
|
setVerificationCode('');
|
|
|
setConfirmDisable(false);
|
|
|
}}
|
|
|
- className="!rounded-lg"
|
|
|
+ className='!rounded-lg'
|
|
|
>
|
|
|
{t('取消')}
|
|
|
</Button>
|
|
|
<Button
|
|
|
- type="danger"
|
|
|
- theme="solid"
|
|
|
+ type='danger'
|
|
|
+ theme='solid'
|
|
|
loading={loading}
|
|
|
disabled={!confirmDisable || !verificationCode}
|
|
|
onClick={handleDisable2FA}
|
|
|
- className="!rounded-lg !bg-slate-500 hover:!bg-slate-600"
|
|
|
+ className='!rounded-lg !bg-slate-500 hover:!bg-slate-600'
|
|
|
>
|
|
|
{t('确认禁用')}
|
|
|
</Button>
|
|
|
@@ -311,14 +324,14 @@ const TwoFASetting = ({ t }) => {
|
|
|
if (backupCodes.length > 0) {
|
|
|
return (
|
|
|
<Button
|
|
|
- type="primary"
|
|
|
- theme="solid"
|
|
|
+ type='primary'
|
|
|
+ theme='solid'
|
|
|
onClick={() => {
|
|
|
setBackupModalVisible(false);
|
|
|
setVerificationCode('');
|
|
|
setBackupCodes([]);
|
|
|
}}
|
|
|
- className="!rounded-lg !bg-slate-600 hover:!bg-slate-700"
|
|
|
+ className='!rounded-lg !bg-slate-600 hover:!bg-slate-700'
|
|
|
>
|
|
|
{t('完成')}
|
|
|
</Button>
|
|
|
@@ -333,17 +346,17 @@ const TwoFASetting = ({ t }) => {
|
|
|
setVerificationCode('');
|
|
|
setBackupCodes([]);
|
|
|
}}
|
|
|
- className="!rounded-lg"
|
|
|
+ className='!rounded-lg'
|
|
|
>
|
|
|
{t('取消')}
|
|
|
</Button>
|
|
|
<Button
|
|
|
- type="primary"
|
|
|
- theme="solid"
|
|
|
+ type='primary'
|
|
|
+ theme='solid'
|
|
|
loading={loading}
|
|
|
disabled={!verificationCode}
|
|
|
onClick={handleRegenerateBackupCodes}
|
|
|
- className="!rounded-lg !bg-slate-600 hover:!bg-slate-700"
|
|
|
+ className='!rounded-lg !bg-slate-600 hover:!bg-slate-700'
|
|
|
>
|
|
|
{t('生成新的备用码')}
|
|
|
</Button>
|
|
|
@@ -353,67 +366,82 @@ const TwoFASetting = ({ t }) => {
|
|
|
|
|
|
return (
|
|
|
<>
|
|
|
- <Card className="!rounded-xl w-full">
|
|
|
- <div className="flex flex-col sm:flex-row items-start sm:justify-between gap-4">
|
|
|
- <div className="flex items-start w-full sm:w-auto">
|
|
|
- <div className="w-12 h-12 rounded-full bg-slate-100 dark:bg-slate-700 flex items-center justify-center mr-4 flex-shrink-0">
|
|
|
- <IconShield size="large" className="text-slate-600 dark:text-slate-300" />
|
|
|
+ <Card className='!rounded-xl w-full'>
|
|
|
+ <div className='flex flex-col sm:flex-row items-start sm:justify-between gap-4'>
|
|
|
+ <div className='flex items-start w-full sm:w-auto'>
|
|
|
+ <div className='w-12 h-12 rounded-full bg-slate-100 dark:bg-slate-700 flex items-center justify-center mr-4 flex-shrink-0'>
|
|
|
+ <IconShield
|
|
|
+ size='large'
|
|
|
+ className='text-slate-600 dark:text-slate-300'
|
|
|
+ />
|
|
|
</div>
|
|
|
- <div className="flex-1">
|
|
|
- <div className="flex items-center gap-2 mb-1">
|
|
|
- <Typography.Title heading={6} className="mb-0">
|
|
|
+ <div className='flex-1'>
|
|
|
+ <div className='flex items-center gap-2 mb-1'>
|
|
|
+ <Typography.Title heading={6} className='mb-0'>
|
|
|
{t('两步验证设置')}
|
|
|
</Typography.Title>
|
|
|
{status.enabled ? (
|
|
|
- <Tag color="green" shape="circle" size="small">{t('已启用')}</Tag>
|
|
|
+ <Tag color='green' shape='circle' size='small'>
|
|
|
+ {t('已启用')}
|
|
|
+ </Tag>
|
|
|
) : (
|
|
|
- <Tag color="red" shape="circle" size="small">{t('未启用')}</Tag>
|
|
|
+ <Tag color='red' shape='circle' size='small'>
|
|
|
+ {t('未启用')}
|
|
|
+ </Tag>
|
|
|
)}
|
|
|
{status.locked && (
|
|
|
- <Tag color="orange" shape="circle" size="small">{t('账户已锁定')}</Tag>
|
|
|
+ <Tag color='orange' shape='circle' size='small'>
|
|
|
+ {t('账户已锁定')}
|
|
|
+ </Tag>
|
|
|
)}
|
|
|
</div>
|
|
|
- <Typography.Text type="tertiary" className="text-sm">
|
|
|
- {t('两步验证(2FA)为您的账户提供额外的安全保护。启用后,登录时需要输入密码和验证器应用生成的验证码。')}
|
|
|
+ <Typography.Text type='tertiary' className='text-sm'>
|
|
|
+ {t(
|
|
|
+ '两步验证(2FA)为您的账户提供额外的安全保护。启用后,登录时需要输入密码和验证器应用生成的验证码。',
|
|
|
+ )}
|
|
|
</Typography.Text>
|
|
|
{status.enabled && (
|
|
|
- <div className="mt-2">
|
|
|
- <Text size="small" type="secondary">{t('剩余备用码:')}{status.backup_codes_remaining || 0}{t('个')}</Text>
|
|
|
+ <div className='mt-2'>
|
|
|
+ <Text size='small' type='secondary'>
|
|
|
+ {t('剩余备用码:')}
|
|
|
+ {status.backup_codes_remaining || 0}
|
|
|
+ {t('个')}
|
|
|
+ </Text>
|
|
|
</div>
|
|
|
)}
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div className="flex flex-col space-y-2 w-full sm:w-auto">
|
|
|
+ <div className='flex flex-col space-y-2 w-full sm:w-auto'>
|
|
|
{!status.enabled ? (
|
|
|
<Button
|
|
|
- type="primary"
|
|
|
- theme="solid"
|
|
|
- size="default"
|
|
|
+ type='primary'
|
|
|
+ theme='solid'
|
|
|
+ size='default'
|
|
|
onClick={handleSetup2FA}
|
|
|
loading={loading}
|
|
|
- className="!rounded-lg !bg-slate-600 hover:!bg-slate-700"
|
|
|
+ className='!rounded-lg !bg-slate-600 hover:!bg-slate-700'
|
|
|
icon={<IconShield />}
|
|
|
>
|
|
|
{t('启用验证')}
|
|
|
</Button>
|
|
|
) : (
|
|
|
- <div className="flex flex-col space-y-2">
|
|
|
+ <div className='flex flex-col space-y-2'>
|
|
|
<Button
|
|
|
- type="danger"
|
|
|
- theme="solid"
|
|
|
- size="default"
|
|
|
+ type='danger'
|
|
|
+ theme='solid'
|
|
|
+ size='default'
|
|
|
onClick={() => setDisableModalVisible(true)}
|
|
|
- className="!rounded-lg !bg-slate-500 hover:!bg-slate-600"
|
|
|
+ className='!rounded-lg !bg-slate-500 hover:!bg-slate-600'
|
|
|
icon={<IconAlertTriangle />}
|
|
|
>
|
|
|
{t('禁用两步验证')}
|
|
|
</Button>
|
|
|
<Button
|
|
|
- type="primary"
|
|
|
- theme="solid"
|
|
|
- size="default"
|
|
|
+ type='primary'
|
|
|
+ theme='solid'
|
|
|
+ size='default'
|
|
|
onClick={() => setBackupModalVisible(true)}
|
|
|
- className="!rounded-lg"
|
|
|
+ className='!rounded-lg'
|
|
|
icon={<IconRefresh />}
|
|
|
>
|
|
|
{t('重新生成备用码')}
|
|
|
@@ -427,8 +455,8 @@ const TwoFASetting = ({ t }) => {
|
|
|
{/* 2FA设置模态框 */}
|
|
|
<Modal
|
|
|
title={
|
|
|
- <div className="flex items-center">
|
|
|
- <IconShield className="mr-2 text-slate-600" />
|
|
|
+ <div className='flex items-center'>
|
|
|
+ <IconShield className='mr-2 text-slate-600' />
|
|
|
{t('设置两步验证')}
|
|
|
</div>
|
|
|
}
|
|
|
@@ -444,36 +472,50 @@ const TwoFASetting = ({ t }) => {
|
|
|
style={{ maxWidth: '90vw' }}
|
|
|
>
|
|
|
{setupData && (
|
|
|
- <div className="space-y-6">
|
|
|
+ <div className='space-y-6'>
|
|
|
{/* 步骤进度 */}
|
|
|
- <Steps type="basic" size="small" current={currentStep}>
|
|
|
- <Steps.Step title={t('扫描二维码')} description={t('使用认证器应用扫描二维码')} />
|
|
|
- <Steps.Step title={t('保存备用码')} description={t('保存备用码以备不时之需')} />
|
|
|
- <Steps.Step title={t('验证设置')} description={t('输入验证码完成设置')} />
|
|
|
+ <Steps type='basic' size='small' current={currentStep}>
|
|
|
+ <Steps.Step
|
|
|
+ title={t('扫描二维码')}
|
|
|
+ description={t('使用认证器应用扫描二维码')}
|
|
|
+ />
|
|
|
+ <Steps.Step
|
|
|
+ title={t('保存备用码')}
|
|
|
+ description={t('保存备用码以备不时之需')}
|
|
|
+ />
|
|
|
+ <Steps.Step
|
|
|
+ title={t('验证设置')}
|
|
|
+ description={t('输入验证码完成设置')}
|
|
|
+ />
|
|
|
</Steps>
|
|
|
|
|
|
{/* 步骤内容 */}
|
|
|
- <div className="rounded-xl">
|
|
|
+ <div className='rounded-xl'>
|
|
|
{currentStep === 0 && (
|
|
|
<div>
|
|
|
- <Paragraph className="text-gray-600 dark:text-gray-300 mb-4">
|
|
|
- {t('使用认证器应用(如 Google Authenticator、Microsoft Authenticator)扫描下方二维码:')}
|
|
|
+ <Paragraph className='text-gray-600 dark:text-gray-300 mb-4'>
|
|
|
+ {t(
|
|
|
+ '使用认证器应用(如 Google Authenticator、Microsoft Authenticator)扫描下方二维码:',
|
|
|
+ )}
|
|
|
</Paragraph>
|
|
|
- <div className="flex justify-center mb-4">
|
|
|
- <div className="bg-white p-4 rounded-lg shadow-sm">
|
|
|
+ <div className='flex justify-center mb-4'>
|
|
|
+ <div className='bg-white p-4 rounded-lg shadow-sm'>
|
|
|
<QRCodeSVG value={setupData.qr_code_data} size={180} />
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div className="bg-blue-50 dark:bg-blue-900 rounded-lg p-3">
|
|
|
- <Text className="text-blue-800 dark:text-blue-200 text-sm">
|
|
|
- {t('或手动输入密钥:')}<Text code copyable className="ml-2">{setupData.secret}</Text>
|
|
|
+ <div className='bg-blue-50 dark:bg-blue-900 rounded-lg p-3'>
|
|
|
+ <Text className='text-blue-800 dark:text-blue-200 text-sm'>
|
|
|
+ {t('或手动输入密钥:')}
|
|
|
+ <Text code copyable className='ml-2'>
|
|
|
+ {setupData.secret}
|
|
|
+ </Text>
|
|
|
</Text>
|
|
|
</div>
|
|
|
</div>
|
|
|
)}
|
|
|
|
|
|
{currentStep === 1 && (
|
|
|
- <div className="space-y-4">
|
|
|
+ <div className='space-y-4'>
|
|
|
{/* 备用码展示 */}
|
|
|
<BackupCodesDisplay
|
|
|
codes={setupData.backup_codes}
|
|
|
@@ -491,9 +533,9 @@ const TwoFASetting = ({ t }) => {
|
|
|
placeholder={t('输入认证器应用显示的6位数字验证码')}
|
|
|
value={verificationCode}
|
|
|
onChange={setVerificationCode}
|
|
|
- size="large"
|
|
|
+ size='large'
|
|
|
maxLength={6}
|
|
|
- className="!rounded-lg"
|
|
|
+ className='!rounded-lg'
|
|
|
/>
|
|
|
)}
|
|
|
</div>
|
|
|
@@ -504,8 +546,8 @@ const TwoFASetting = ({ t }) => {
|
|
|
{/* 禁用2FA模态框 */}
|
|
|
<Modal
|
|
|
title={
|
|
|
- <div className="flex items-center">
|
|
|
- <IconAlertTriangle className="mr-2 text-red-500" />
|
|
|
+ <div className='flex items-center'>
|
|
|
+ <IconAlertTriangle className='mr-2 text-red-500' />
|
|
|
{t('禁用两步验证')}
|
|
|
</div>
|
|
|
}
|
|
|
@@ -519,36 +561,41 @@ const TwoFASetting = ({ t }) => {
|
|
|
width={550}
|
|
|
style={{ maxWidth: '90vw' }}
|
|
|
>
|
|
|
- <div className="space-y-6">
|
|
|
+ <div className='space-y-6'>
|
|
|
{/* 警告提示 */}
|
|
|
- <div className="rounded-xl">
|
|
|
+ <div className='rounded-xl'>
|
|
|
<Banner
|
|
|
- type="warning"
|
|
|
- description={t('警告:禁用两步验证将永久删除您的验证设置和所有备用码,此操作不可撤销!')}
|
|
|
- className="!rounded-lg"
|
|
|
+ type='warning'
|
|
|
+ description={t(
|
|
|
+ '警告:禁用两步验证将永久删除您的验证设置和所有备用码,此操作不可撤销!',
|
|
|
+ )}
|
|
|
+ className='!rounded-lg'
|
|
|
/>
|
|
|
</div>
|
|
|
|
|
|
{/* 内容区域 */}
|
|
|
- <div className="space-y-4">
|
|
|
+ <div className='space-y-4'>
|
|
|
<div>
|
|
|
- <Text strong className="block mb-2 text-slate-700 dark:text-slate-200">
|
|
|
+ <Text
|
|
|
+ strong
|
|
|
+ className='block mb-2 text-slate-700 dark:text-slate-200'
|
|
|
+ >
|
|
|
{t('禁用后的影响:')}
|
|
|
</Text>
|
|
|
- <ul className="space-y-2 text-sm text-slate-600 dark:text-slate-300">
|
|
|
- <li className="flex items-start gap-2">
|
|
|
+ <ul className='space-y-2 text-sm text-slate-600 dark:text-slate-300'>
|
|
|
+ <li className='flex items-start gap-2'>
|
|
|
<Badge dot type='warning' />
|
|
|
{t('降低您账户的安全性')}
|
|
|
</li>
|
|
|
- <li className="flex items-start gap-2">
|
|
|
+ <li className='flex items-start gap-2'>
|
|
|
<Badge dot type='warning' />
|
|
|
{t('需要重新完整设置才能再次启用')}
|
|
|
</li>
|
|
|
- <li className="flex items-start gap-2">
|
|
|
+ <li className='flex items-start gap-2'>
|
|
|
<Badge dot type='danger' />
|
|
|
{t('永久删除您的两步验证设置')}
|
|
|
</li>
|
|
|
- <li className="flex items-start gap-2">
|
|
|
+ <li className='flex items-start gap-2'>
|
|
|
<Badge dot type='danger' />
|
|
|
{t('永久删除所有备用码(包括未使用的)')}
|
|
|
</li>
|
|
|
@@ -557,17 +604,20 @@ const TwoFASetting = ({ t }) => {
|
|
|
|
|
|
<Divider margin={16} />
|
|
|
|
|
|
- <div className="space-y-4">
|
|
|
+ <div className='space-y-4'>
|
|
|
<div>
|
|
|
- <Text strong className="block mb-2 text-slate-700 dark:text-slate-200">
|
|
|
+ <Text
|
|
|
+ strong
|
|
|
+ className='block mb-2 text-slate-700 dark:text-slate-200'
|
|
|
+ >
|
|
|
{t('验证身份')}
|
|
|
</Text>
|
|
|
<Input
|
|
|
placeholder={t('请输入认证器验证码或备用码')}
|
|
|
value={verificationCode}
|
|
|
onChange={setVerificationCode}
|
|
|
- size="large"
|
|
|
- className="!rounded-lg"
|
|
|
+ size='large'
|
|
|
+ className='!rounded-lg'
|
|
|
/>
|
|
|
</div>
|
|
|
|
|
|
@@ -575,9 +625,11 @@ const TwoFASetting = ({ t }) => {
|
|
|
<Checkbox
|
|
|
checked={confirmDisable}
|
|
|
onChange={(e) => setConfirmDisable(e.target.checked)}
|
|
|
- className="text-sm"
|
|
|
+ className='text-sm'
|
|
|
>
|
|
|
- {t('我已了解禁用两步验证将永久删除所有相关设置和备用码,此操作不可撤销')}
|
|
|
+ {t(
|
|
|
+ '我已了解禁用两步验证将永久删除所有相关设置和备用码,此操作不可撤销',
|
|
|
+ )}
|
|
|
</Checkbox>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -588,8 +640,8 @@ const TwoFASetting = ({ t }) => {
|
|
|
{/* 重新生成备用码模态框 */}
|
|
|
<Modal
|
|
|
title={
|
|
|
- <div className="flex items-center">
|
|
|
- <IconRefresh className="mr-2 text-slate-600" />
|
|
|
+ <div className='flex items-center'>
|
|
|
+ <IconRefresh className='mr-2 text-slate-600' />
|
|
|
{t('重新生成备用码')}
|
|
|
</div>
|
|
|
}
|
|
|
@@ -603,30 +655,35 @@ const TwoFASetting = ({ t }) => {
|
|
|
width={500}
|
|
|
style={{ maxWidth: '90vw' }}
|
|
|
>
|
|
|
- <div className="space-y-6">
|
|
|
+ <div className='space-y-6'>
|
|
|
{backupCodes.length === 0 ? (
|
|
|
<>
|
|
|
{/* 警告提示 */}
|
|
|
- <div className="rounded-xl">
|
|
|
+ <div className='rounded-xl'>
|
|
|
<Banner
|
|
|
- type="warning"
|
|
|
- description={t('重新生成备用码将使现有的备用码失效,请确保您已保存了当前的备用码。')}
|
|
|
- className="!rounded-lg"
|
|
|
+ type='warning'
|
|
|
+ description={t(
|
|
|
+ '重新生成备用码将使现有的备用码失效,请确保您已保存了当前的备用码。',
|
|
|
+ )}
|
|
|
+ className='!rounded-lg'
|
|
|
/>
|
|
|
</div>
|
|
|
|
|
|
{/* 验证区域 */}
|
|
|
- <div className="space-y-4">
|
|
|
+ <div className='space-y-4'>
|
|
|
<div>
|
|
|
- <Text strong className="block mb-2 text-slate-700 dark:text-slate-200">
|
|
|
+ <Text
|
|
|
+ strong
|
|
|
+ className='block mb-2 text-slate-700 dark:text-slate-200'
|
|
|
+ >
|
|
|
{t('验证身份')}
|
|
|
</Text>
|
|
|
<Input
|
|
|
placeholder={t('请输入认证器验证码')}
|
|
|
value={verificationCode}
|
|
|
onChange={setVerificationCode}
|
|
|
- size="large"
|
|
|
- className="!rounded-lg"
|
|
|
+ size='large'
|
|
|
+ className='!rounded-lg'
|
|
|
/>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -635,13 +692,16 @@ const TwoFASetting = ({ t }) => {
|
|
|
<>
|
|
|
{/* 成功提示 */}
|
|
|
<Space vertical style={{ width: '100%' }}>
|
|
|
- <div className="flex items-center justify-center gap-2">
|
|
|
+ <div className='flex items-center justify-center gap-2'>
|
|
|
<Badge dot type='success' />
|
|
|
- <Text strong className="text-lg text-slate-700 dark:text-slate-200">
|
|
|
+ <Text
|
|
|
+ strong
|
|
|
+ className='text-lg text-slate-700 dark:text-slate-200'
|
|
|
+ >
|
|
|
{t('新的备用码已生成')}
|
|
|
</Text>
|
|
|
</div>
|
|
|
- <Text className="text-slate-500 dark:text-slate-400 text-sm">
|
|
|
+ <Text className='text-slate-500 dark:text-slate-400 text-sm'>
|
|
|
{t('旧的备用码已失效,请保存新的备用码')}
|
|
|
</Text>
|
|
|
|
|
|
@@ -660,4 +720,4 @@ const TwoFASetting = ({ t }) => {
|
|
|
);
|
|
|
};
|
|
|
|
|
|
-export default TwoFASetting;
|
|
|
+export default TwoFASetting;
|