diff --git a/Data/Server/WebUI/src/Admin/User_Management.jsx b/Data/Server/WebUI/src/Admin/User_Management.jsx
index f992f11..794131f 100644
--- a/Data/Server/WebUI/src/Admin/User_Management.jsx
+++ b/Data/Server/WebUI/src/Admin/User_Management.jsx
@@ -89,6 +89,8 @@ export default function UserManagement({ isAdmin = false }) {
const [warnMessage, setWarnMessage] = useState("");
const [me, setMe] = useState(null);
const [mfaBusyUser, setMfaBusyUser] = useState(null);
+ const [resetMfaOpen, setResetMfaOpen] = useState(false);
+ const [resetMfaTarget, setResetMfaTarget] = useState(null);
// Columns and filters
const columns = useMemo(() => ([
@@ -243,6 +245,43 @@ export default function UserManagement({ isAdmin = false }) {
}
};
+ const openResetMfa = (user) => {
+ if (!user) return;
+ setResetMfaTarget(user);
+ setResetMfaOpen(true);
+ };
+
+ const doResetMfa = async () => {
+ const user = resetMfaTarget;
+ setResetMfaOpen(false);
+ setResetMfaTarget(null);
+ if (!user) return;
+ const username = user.username;
+ const keepEnabled = Boolean(user.mfa_enabled);
+ setMfaBusyUser(username);
+ try {
+ const resp = await fetch(`/api/users/${encodeURIComponent(username)}/mfa`, {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ credentials: "include",
+ body: JSON.stringify({ enabled: keepEnabled, reset_secret: true })
+ });
+ const data = await resp.json();
+ if (!resp.ok) {
+ setWarnMessage(data?.error || "Failed to reset MFA for this user.");
+ setWarnOpen(true);
+ return;
+ }
+ await fetchUsers();
+ } catch (err) {
+ console.error(err);
+ setWarnMessage("Failed to reset MFA for this user.");
+ setWarnOpen(true);
+ } finally {
+ setMfaBusyUser(null);
+ }
+ };
+
const toggleMfa = async (user, enabled) => {
if (!user) return;
const previous = Boolean(user.mfa_enabled);
@@ -509,6 +548,9 @@ export default function UserManagement({ isAdmin = false }) {
>
Change Role
+