fix: 🐛 2fa verification
This commit is contained in:
@@ -686,6 +686,9 @@ def register_routes(app, limiter=None):
|
|||||||
code = request.form.get('code', '').strip()
|
code = request.form.get('code', '').strip()
|
||||||
use_backup = request.form.get('use_backup') == 'true'
|
use_backup = request.form.get('use_backup') == 'true'
|
||||||
|
|
||||||
|
if not code:
|
||||||
|
return render_with_user('verify_2fa.html', error='Please enter a verification code.')
|
||||||
|
|
||||||
with get_db_connection(current_app) as conn:
|
with get_db_connection(current_app) as conn:
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute('SELECT totp_secret, backup_codes FROM User WHERE id = %s', (pending_user_id,))
|
cursor.execute('SELECT totp_secret, backup_codes FROM User WHERE id = %s', (pending_user_id,))
|
||||||
@@ -695,13 +698,21 @@ def register_routes(app, limiter=None):
|
|||||||
|
|
||||||
totp_secret, backup_codes_json = result
|
totp_secret, backup_codes_json = result
|
||||||
|
|
||||||
|
# CRITICAL: Ensure TOTP secret exists before attempting verification
|
||||||
|
if not totp_secret:
|
||||||
|
return render_with_user('verify_2fa.html', error='2FA is not properly configured for this account.')
|
||||||
|
|
||||||
if use_backup:
|
if use_backup:
|
||||||
# Verify backup code
|
# Verify backup code
|
||||||
|
if not backup_codes_json:
|
||||||
|
return render_with_user('verify_2fa.html', error='No backup codes available.')
|
||||||
|
|
||||||
valid, updated_codes = verify_backup_code(backup_codes_json, code)
|
valid, updated_codes = verify_backup_code(backup_codes_json, code)
|
||||||
if valid:
|
if valid:
|
||||||
# Update backup codes in database
|
# Update backup codes in database
|
||||||
cursor.execute('UPDATE User SET backup_codes = %s WHERE id = %s',
|
cursor.execute('UPDATE User SET backup_codes = %s WHERE id = %s',
|
||||||
(updated_codes, pending_user_id))
|
(updated_codes, pending_user_id))
|
||||||
|
conn.commit()
|
||||||
session['logged_in'] = True
|
session['logged_in'] = True
|
||||||
session['user_id'] = pending_user_id
|
session['user_id'] = pending_user_id
|
||||||
session.pop('pending_user_id', None)
|
session.pop('pending_user_id', None)
|
||||||
@@ -712,7 +723,10 @@ def register_routes(app, limiter=None):
|
|||||||
else:
|
else:
|
||||||
return render_with_user('verify_2fa.html', error='Invalid backup code.')
|
return render_with_user('verify_2fa.html', error='Invalid backup code.')
|
||||||
else:
|
else:
|
||||||
# Verify TOTP code
|
# Verify TOTP code - ensure code is exactly 6 digits
|
||||||
|
if len(code) != 6 or not code.isdigit():
|
||||||
|
return render_with_user('verify_2fa.html', error='Invalid code format. Please enter a 6-digit code.')
|
||||||
|
|
||||||
if verify_totp(totp_secret, code):
|
if verify_totp(totp_secret, code):
|
||||||
session['logged_in'] = True
|
session['logged_in'] = True
|
||||||
session['user_id'] = pending_user_id
|
session['user_id'] = pending_user_id
|
||||||
|
|||||||
@@ -81,14 +81,39 @@
|
|||||||
|
|
||||||
// Auto-submit on 6 digits for TOTP codes
|
// Auto-submit on 6 digits for TOTP codes
|
||||||
const codeInput = document.getElementById('code');
|
const codeInput = document.getElementById('code');
|
||||||
|
let isSubmitting = false;
|
||||||
codeInput.addEventListener('input', function(e) {
|
codeInput.addEventListener('input', function(e) {
|
||||||
if (!backupMode) {
|
if (!backupMode && !isSubmitting) {
|
||||||
this.value = this.value.replace(/[^0-9]/g, '');
|
this.value = this.value.replace(/[^0-9]/g, '');
|
||||||
if (this.value.length === 6) {
|
if (this.value.length === 6 && this.value.trim() !== '') {
|
||||||
this.form.submit();
|
isSubmitting = true;
|
||||||
|
// Small delay to ensure value is set
|
||||||
|
setTimeout(() => {
|
||||||
|
if (this.value.length === 6 && this.value.trim() !== '') {
|
||||||
|
this.form.submit();
|
||||||
|
} else {
|
||||||
|
isSubmitting = false;
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Prevent form submission if code is empty
|
||||||
|
const form = codeInput.closest('form');
|
||||||
|
form.addEventListener('submit', function(e) {
|
||||||
|
const code = codeInput.value.trim();
|
||||||
|
if (!code) {
|
||||||
|
e.preventDefault();
|
||||||
|
alert('Please enter a verification code.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!backupMode && (code.length !== 6 || !/^\d{6}$/.test(code))) {
|
||||||
|
e.preventDefault();
|
||||||
|
alert('Please enter a valid 6-digit code.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user