OTP security hardened
This commit is contained in:
@@ -152,6 +152,11 @@ function renderUsers(users) {
|
||||
privilegeLabel.append(privilegeCheckbox, document.createTextNode(' Administrator'));
|
||||
row.append(label, privilegeLabel);
|
||||
if (!isCurrentUser) {
|
||||
const otpButton = document.createElement('button');
|
||||
otpButton.type = 'button';
|
||||
otpButton.textContent = 'Reset OTP';
|
||||
otpButton.addEventListener('click', () => resetUserOtp(user, otpButton));
|
||||
row.append(otpButton);
|
||||
const button = document.createElement('button');
|
||||
button.type = 'button';
|
||||
button.className = 'danger-button';
|
||||
@@ -163,6 +168,27 @@ function renderUsers(users) {
|
||||
}));
|
||||
}
|
||||
|
||||
async function resetUserOtp(user, button) {
|
||||
if (!window.confirm(`Disable OTP for ${user.username}?`)) return;
|
||||
button.disabled = true;
|
||||
const status = document.querySelector('#user-status');
|
||||
try {
|
||||
const response = await fetch(`/api/admin/users/${encodeURIComponent(user.id)}/otp/reset`, {
|
||||
method: 'POST',
|
||||
headers: authHeaders(),
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(await responseError(response, `Request failed (${response.status})`));
|
||||
}
|
||||
status.textContent = `OTP disabled for ${user.username}.`;
|
||||
status.style.color = '#94e2d5';
|
||||
} catch (error) {
|
||||
status.textContent = `Could not reset OTP for ${user.username}: ${error.message}`;
|
||||
status.style.color = '#f38ba8';
|
||||
button.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadUsers() {
|
||||
const response = await fetch('/api/admin/users', {headers: authHeaders()});
|
||||
if (!response.ok) throw new Error('Could not load users');
|
||||
|
||||
Reference in New Issue
Block a user