feat: add Reset MFA action for team members
Adds a Reset MFA button in the Actions column and an inline confirmation card (with warning Alert) that calls useResetTeamMemberMfa on confirm. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,7 @@ import {
|
||||
useInviteTeamMember,
|
||||
useRemoveTeamMember,
|
||||
useResetTeamMemberPassword,
|
||||
useResetTeamMemberMfa,
|
||||
} from '../../api/tenant-hooks';
|
||||
import styles from '../../styles/platform.module.css';
|
||||
|
||||
@@ -59,6 +60,7 @@ export function TeamPage() {
|
||||
const inviteMember = useInviteTeamMember();
|
||||
const removeMember = useRemoveTeamMember();
|
||||
const resetPassword = useResetTeamMemberPassword();
|
||||
const resetMfa = useResetTeamMemberMfa();
|
||||
const { toast } = useToast();
|
||||
|
||||
const [showInvite, setShowInvite] = useState(false);
|
||||
@@ -68,6 +70,7 @@ export function TeamPage() {
|
||||
const [removeTarget, setRemoveTarget] = useState<TeamMember | null>(null);
|
||||
const [pwTarget, setPwTarget] = useState<TeamMember | null>(null);
|
||||
const [pwValue, setPwValue] = useState('');
|
||||
const [mfaResetTarget, setMfaResetTarget] = useState<TeamMember | null>(null);
|
||||
|
||||
const team: TeamMember[] = (rawTeam ?? []).map(toMember).filter((m) => m.id !== '');
|
||||
|
||||
@@ -100,6 +103,13 @@ export function TeamPage() {
|
||||
>
|
||||
Reset Password
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="small"
|
||||
onClick={() => setMfaResetTarget(row)}
|
||||
>
|
||||
Reset MFA
|
||||
</Button>
|
||||
<Button
|
||||
variant="danger"
|
||||
onClick={(e) => { e.stopPropagation(); setRemoveTarget(row); }}
|
||||
@@ -244,6 +254,33 @@ export function TeamPage() {
|
||||
loading={removeMember.isPending}
|
||||
/>
|
||||
|
||||
{/* Reset MFA inline form */}
|
||||
{mfaResetTarget && (
|
||||
<Card title={`Reset MFA for ${mfaResetTarget.name || mfaResetTarget.email}`} style={{ marginTop: 16 }}>
|
||||
<Alert variant="warning">
|
||||
This will remove all MFA factors for this user. They will need to re-enroll if MFA is required.
|
||||
</Alert>
|
||||
<div style={{ display: 'flex', gap: 8, marginTop: 16 }}>
|
||||
<Button
|
||||
variant="danger"
|
||||
onClick={async () => {
|
||||
try {
|
||||
await resetMfa.mutateAsync(mfaResetTarget.id);
|
||||
toast({ title: `MFA reset for ${mfaResetTarget.name || mfaResetTarget.email}`, variant: 'success' });
|
||||
setMfaResetTarget(null);
|
||||
} catch (err) {
|
||||
toast({ title: 'Failed to reset MFA', description: String(err), variant: 'error' });
|
||||
}
|
||||
}}
|
||||
loading={resetMfa.isPending}
|
||||
>
|
||||
Confirm Reset MFA
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={() => setMfaResetTarget(null)}>Cancel</Button>
|
||||
</div>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* Reset password inline form */}
|
||||
{pwTarget && (
|
||||
<Card title={`Reset password for ${pwTarget.name}`}>
|
||||
|
||||
Reference in New Issue
Block a user