mirror of
https://github.com/bunny-lab-io/Borealis.git
synced 2025-10-26 15:21:57 -06:00
Added Ability to Reset MFA for Users
This commit is contained in:
@@ -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
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => { const u = menuUser; closeMenu(); openResetMfa(u); }}>
|
||||
Reset MFA
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
|
||||
<Dialog open={resetOpen} onClose={() => setResetOpen(false)} PaperProps={{ sx: { bgcolor: "#121212", color: "#fff" } }}>
|
||||
@@ -621,6 +663,12 @@ export default function UserManagement({ isAdmin = false }) {
|
||||
onCancel={() => setConfirmChangeRoleOpen(false)}
|
||||
onConfirm={doChangeRole}
|
||||
/>
|
||||
<ConfirmDeleteDialog
|
||||
open={resetMfaOpen}
|
||||
message={resetMfaTarget ? `Reset MFA enrollment for '${resetMfaTarget.username}'? This clears their existing authenticator.` : ""}
|
||||
onCancel={() => { setResetMfaOpen(false); setResetMfaTarget(null); }}
|
||||
onConfirm={doResetMfa}
|
||||
/>
|
||||
<ConfirmDeleteDialog
|
||||
open={warnOpen}
|
||||
message={warnMessage}
|
||||
|
||||
@@ -1503,10 +1503,16 @@ def api_users_toggle_mfa(username):
|
||||
cur = conn.cursor()
|
||||
now = _now_ts()
|
||||
if enabled:
|
||||
cur.execute(
|
||||
"UPDATE users SET mfa_enabled=1, updated_at=? WHERE LOWER(username)=LOWER(?)",
|
||||
(now, username)
|
||||
)
|
||||
if reset_secret:
|
||||
cur.execute(
|
||||
"UPDATE users SET mfa_enabled=1, mfa_secret=NULL, updated_at=? WHERE LOWER(username)=LOWER(?)",
|
||||
(now, username)
|
||||
)
|
||||
else:
|
||||
cur.execute(
|
||||
"UPDATE users SET mfa_enabled=1, updated_at=? WHERE LOWER(username)=LOWER(?)",
|
||||
(now, username)
|
||||
)
|
||||
else:
|
||||
if reset_secret:
|
||||
cur.execute(
|
||||
|
||||
Reference in New Issue
Block a user