OTP security hardened
This commit is contained in:
@@ -12,11 +12,13 @@ const mastodonConnectButton = document.querySelector('#mastodon-connect');
|
||||
const otpSetupButton = document.querySelector('#otp-setup');
|
||||
const otpEnableButton = document.querySelector('#otp-enable');
|
||||
const otpDisableButton = document.querySelector('#otp-disable');
|
||||
const otpRecoverButton = document.querySelector('#otp-recover');
|
||||
const otpProvisioning = document.querySelector('#otp-provisioning');
|
||||
const otpDisabled = document.querySelector('#otp-disabled');
|
||||
const otpEnabled = document.querySelector('#otp-enabled');
|
||||
const otpSecret = document.querySelector('#otp-secret');
|
||||
const otpUri = document.querySelector('#otp-uri');
|
||||
const otpRecoveryCodes = document.querySelector('#otp-recovery-codes');
|
||||
const otpStatus = document.querySelector('#otp-status');
|
||||
const emailAddressList = document.querySelector('#email-address-list');
|
||||
const additionalEmailForm = document.querySelector('#additional-email-form');
|
||||
@@ -131,6 +133,7 @@ otpSetupButton.addEventListener('click', async () => {
|
||||
}
|
||||
otpSecret.textContent = result.secret;
|
||||
otpUri.href = result.otpauth_url;
|
||||
otpRecoveryCodes.textContent = result.recovery_codes.join('\n');
|
||||
otpProvisioning.classList.remove('hidden');
|
||||
setOtpStatus('Enter a code from your authenticator app to confirm setup.');
|
||||
});
|
||||
@@ -153,8 +156,9 @@ otpEnableButton.addEventListener('click', async () => {
|
||||
|
||||
otpDisableButton.addEventListener('click', async () => {
|
||||
const code = document.querySelector('#otp-disable-code').value.trim();
|
||||
const currentPassword = document.querySelector('#otp-current-password').value;
|
||||
const response = await fetch('/api/user/otp', {
|
||||
method: 'POST', headers: authHeaders(true), body: JSON.stringify({action: 'disable', code}),
|
||||
method: 'POST', headers: authHeaders(true), body: JSON.stringify({action: 'disable', code, current_password: currentPassword}),
|
||||
});
|
||||
const result = await response.json();
|
||||
if (!response.ok) {
|
||||
@@ -167,6 +171,24 @@ otpDisableButton.addEventListener('click', async () => {
|
||||
setOtpStatus('One-time password disabled.');
|
||||
});
|
||||
|
||||
otpRecoverButton.addEventListener('click', async () => {
|
||||
const currentPassword = document.querySelector('#otp-current-password').value;
|
||||
const recoveryCode = document.querySelector('#otp-recovery-code').value.trim();
|
||||
const response = await fetch('/api/user/otp/recover', {
|
||||
method: 'POST', headers: authHeaders(true), body: JSON.stringify({current_password: currentPassword, recovery_code: recoveryCode}),
|
||||
});
|
||||
const result = await response.json();
|
||||
if (!response.ok) {
|
||||
setOtpStatus(result.detail || 'Could not recover one-time password access.', true);
|
||||
return;
|
||||
}
|
||||
otpDisabled.classList.remove('hidden');
|
||||
otpEnabled.classList.add('hidden');
|
||||
document.querySelector('#otp-current-password').value = '';
|
||||
document.querySelector('#otp-recovery-code').value = '';
|
||||
setOtpStatus('One-time password access recovered.');
|
||||
});
|
||||
|
||||
async function loadProfile() {
|
||||
const response = await fetch('/api/user/me', {headers: authHeaders()});
|
||||
if (!response.ok) throw new Error('Could not load profile');
|
||||
|
||||
Reference in New Issue
Block a user