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,
|
useInviteTeamMember,
|
||||||
useRemoveTeamMember,
|
useRemoveTeamMember,
|
||||||
useResetTeamMemberPassword,
|
useResetTeamMemberPassword,
|
||||||
|
useResetTeamMemberMfa,
|
||||||
} from '../../api/tenant-hooks';
|
} from '../../api/tenant-hooks';
|
||||||
import styles from '../../styles/platform.module.css';
|
import styles from '../../styles/platform.module.css';
|
||||||
|
|
||||||
@@ -59,6 +60,7 @@ export function TeamPage() {
|
|||||||
const inviteMember = useInviteTeamMember();
|
const inviteMember = useInviteTeamMember();
|
||||||
const removeMember = useRemoveTeamMember();
|
const removeMember = useRemoveTeamMember();
|
||||||
const resetPassword = useResetTeamMemberPassword();
|
const resetPassword = useResetTeamMemberPassword();
|
||||||
|
const resetMfa = useResetTeamMemberMfa();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
|
||||||
const [showInvite, setShowInvite] = useState(false);
|
const [showInvite, setShowInvite] = useState(false);
|
||||||
@@ -68,6 +70,7 @@ export function TeamPage() {
|
|||||||
const [removeTarget, setRemoveTarget] = useState<TeamMember | null>(null);
|
const [removeTarget, setRemoveTarget] = useState<TeamMember | null>(null);
|
||||||
const [pwTarget, setPwTarget] = useState<TeamMember | null>(null);
|
const [pwTarget, setPwTarget] = useState<TeamMember | null>(null);
|
||||||
const [pwValue, setPwValue] = useState('');
|
const [pwValue, setPwValue] = useState('');
|
||||||
|
const [mfaResetTarget, setMfaResetTarget] = useState<TeamMember | null>(null);
|
||||||
|
|
||||||
const team: TeamMember[] = (rawTeam ?? []).map(toMember).filter((m) => m.id !== '');
|
const team: TeamMember[] = (rawTeam ?? []).map(toMember).filter((m) => m.id !== '');
|
||||||
|
|
||||||
@@ -100,6 +103,13 @@ export function TeamPage() {
|
|||||||
>
|
>
|
||||||
Reset Password
|
Reset Password
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
size="small"
|
||||||
|
onClick={() => setMfaResetTarget(row)}
|
||||||
|
>
|
||||||
|
Reset MFA
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="danger"
|
variant="danger"
|
||||||
onClick={(e) => { e.stopPropagation(); setRemoveTarget(row); }}
|
onClick={(e) => { e.stopPropagation(); setRemoveTarget(row); }}
|
||||||
@@ -244,6 +254,33 @@ export function TeamPage() {
|
|||||||
loading={removeMember.isPending}
|
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 */}
|
{/* Reset password inline form */}
|
||||||
{pwTarget && (
|
{pwTarget && (
|
||||||
<Card title={`Reset password for ${pwTarget.name}`}>
|
<Card title={`Reset password for ${pwTarget.name}`}>
|
||||||
|
|||||||
Reference in New Issue
Block a user