feat: passkey
This commit is contained in:
@@ -204,6 +204,8 @@ const renderOperations = (
|
||||
showDemoteModal,
|
||||
showEnableDisableModal,
|
||||
showDeleteModal,
|
||||
showResetPasskeyModal,
|
||||
showResetTwoFAModal,
|
||||
t,
|
||||
},
|
||||
) => {
|
||||
@@ -253,6 +255,20 @@ const renderOperations = (
|
||||
>
|
||||
{t('降级')}
|
||||
</Button>
|
||||
<Button
|
||||
type='warning'
|
||||
size='small'
|
||||
onClick={() => showResetPasskeyModal(record)}
|
||||
>
|
||||
{t('重置 Passkey')}
|
||||
</Button>
|
||||
<Button
|
||||
type='warning'
|
||||
size='small'
|
||||
onClick={() => showResetTwoFAModal(record)}
|
||||
>
|
||||
{t('重置 2FA')}
|
||||
</Button>
|
||||
<Button
|
||||
type='danger'
|
||||
size='small'
|
||||
@@ -275,6 +291,8 @@ export const getUsersColumns = ({
|
||||
showDemoteModal,
|
||||
showEnableDisableModal,
|
||||
showDeleteModal,
|
||||
showResetPasskeyModal,
|
||||
showResetTwoFAModal,
|
||||
}) => {
|
||||
return [
|
||||
{
|
||||
@@ -329,6 +347,8 @@ export const getUsersColumns = ({
|
||||
showDemoteModal,
|
||||
showEnableDisableModal,
|
||||
showDeleteModal,
|
||||
showResetPasskeyModal,
|
||||
showResetTwoFAModal,
|
||||
t,
|
||||
}),
|
||||
},
|
||||
|
||||
@@ -29,6 +29,8 @@ import PromoteUserModal from './modals/PromoteUserModal';
|
||||
import DemoteUserModal from './modals/DemoteUserModal';
|
||||
import EnableDisableUserModal from './modals/EnableDisableUserModal';
|
||||
import DeleteUserModal from './modals/DeleteUserModal';
|
||||
import ResetPasskeyModal from './modals/ResetPasskeyModal';
|
||||
import ResetTwoFAModal from './modals/ResetTwoFAModal';
|
||||
|
||||
const UsersTable = (usersData) => {
|
||||
const {
|
||||
@@ -45,6 +47,8 @@ const UsersTable = (usersData) => {
|
||||
setShowEditUser,
|
||||
manageUser,
|
||||
refresh,
|
||||
resetUserPasskey,
|
||||
resetUserTwoFA,
|
||||
t,
|
||||
} = usersData;
|
||||
|
||||
@@ -55,6 +59,8 @@ const UsersTable = (usersData) => {
|
||||
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
||||
const [modalUser, setModalUser] = useState(null);
|
||||
const [enableDisableAction, setEnableDisableAction] = useState('');
|
||||
const [showResetPasskeyModal, setShowResetPasskeyModal] = useState(false);
|
||||
const [showResetTwoFAModal, setShowResetTwoFAModal] = useState(false);
|
||||
|
||||
// Modal handlers
|
||||
const showPromoteUserModal = (user) => {
|
||||
@@ -78,6 +84,16 @@ const UsersTable = (usersData) => {
|
||||
setShowDeleteModal(true);
|
||||
};
|
||||
|
||||
const showResetPasskeyUserModal = (user) => {
|
||||
setModalUser(user);
|
||||
setShowResetPasskeyModal(true);
|
||||
};
|
||||
|
||||
const showResetTwoFAUserModal = (user) => {
|
||||
setModalUser(user);
|
||||
setShowResetTwoFAModal(true);
|
||||
};
|
||||
|
||||
// Modal confirm handlers
|
||||
const handlePromoteConfirm = () => {
|
||||
manageUser(modalUser.id, 'promote', modalUser);
|
||||
@@ -94,6 +110,16 @@ const UsersTable = (usersData) => {
|
||||
setShowEnableDisableModal(false);
|
||||
};
|
||||
|
||||
const handleResetPasskeyConfirm = async () => {
|
||||
await resetUserPasskey(modalUser);
|
||||
setShowResetPasskeyModal(false);
|
||||
};
|
||||
|
||||
const handleResetTwoFAConfirm = async () => {
|
||||
await resetUserTwoFA(modalUser);
|
||||
setShowResetTwoFAModal(false);
|
||||
};
|
||||
|
||||
// Get all columns
|
||||
const columns = useMemo(() => {
|
||||
return getUsersColumns({
|
||||
@@ -104,8 +130,20 @@ const UsersTable = (usersData) => {
|
||||
showDemoteModal: showDemoteUserModal,
|
||||
showEnableDisableModal: showEnableDisableUserModal,
|
||||
showDeleteModal: showDeleteUserModal,
|
||||
showResetPasskeyModal: showResetPasskeyUserModal,
|
||||
showResetTwoFAModal: showResetTwoFAUserModal,
|
||||
});
|
||||
}, [t, setEditingUser, setShowEditUser]);
|
||||
}, [
|
||||
t,
|
||||
setEditingUser,
|
||||
setShowEditUser,
|
||||
showPromoteUserModal,
|
||||
showDemoteUserModal,
|
||||
showEnableDisableUserModal,
|
||||
showDeleteUserModal,
|
||||
showResetPasskeyUserModal,
|
||||
showResetTwoFAUserModal,
|
||||
]);
|
||||
|
||||
// Handle compact mode by removing fixed positioning
|
||||
const tableColumns = useMemo(() => {
|
||||
@@ -188,6 +226,22 @@ const UsersTable = (usersData) => {
|
||||
manageUser={manageUser}
|
||||
t={t}
|
||||
/>
|
||||
|
||||
<ResetPasskeyModal
|
||||
visible={showResetPasskeyModal}
|
||||
onCancel={() => setShowResetPasskeyModal(false)}
|
||||
onConfirm={handleResetPasskeyConfirm}
|
||||
user={modalUser}
|
||||
t={t}
|
||||
/>
|
||||
|
||||
<ResetTwoFAModal
|
||||
visible={showResetTwoFAModal}
|
||||
onCancel={() => setShowResetTwoFAModal(false)}
|
||||
onConfirm={handleResetTwoFAConfirm}
|
||||
user={modalUser}
|
||||
t={t}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
39
web/src/components/table/users/modals/ResetPasskeyModal.jsx
Normal file
39
web/src/components/table/users/modals/ResetPasskeyModal.jsx
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright (C) 2025 QuantumNous
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Modal } from '@douyinfe/semi-ui';
|
||||
|
||||
const ResetPasskeyModal = ({ visible, onCancel, onConfirm, user, t }) => {
|
||||
return (
|
||||
<Modal
|
||||
title={t('确认重置 Passkey')}
|
||||
visible={visible}
|
||||
onCancel={onCancel}
|
||||
onOk={onConfirm}
|
||||
type='warning'
|
||||
>
|
||||
{t('此操作将解绑用户当前的 Passkey,下次登录需要重新注册。')}{' '}
|
||||
{user?.username ? t('目标用户:{{username}}', { username: user.username }) : ''}
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default ResetPasskeyModal;
|
||||
|
||||
39
web/src/components/table/users/modals/ResetTwoFAModal.jsx
Normal file
39
web/src/components/table/users/modals/ResetTwoFAModal.jsx
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright (C) 2025 QuantumNous
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Modal } from '@douyinfe/semi-ui';
|
||||
|
||||
const ResetTwoFAModal = ({ visible, onCancel, onConfirm, user, t }) => {
|
||||
return (
|
||||
<Modal
|
||||
title={t('确认重置两步验证')}
|
||||
visible={visible}
|
||||
onCancel={onCancel}
|
||||
onOk={onConfirm}
|
||||
type='warning'
|
||||
>
|
||||
{t('此操作将禁用该用户当前的两步验证配置,下次登录将不再强制输入验证码,直到用户重新启用。')}{' '}
|
||||
{user?.username ? t('目标用户:{{username}}', { username: user.username }) : ''}
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default ResetTwoFAModal;
|
||||
|
||||
Reference in New Issue
Block a user