From 4467922199f8dd2bc777c5eca7fe39befbcbf14c Mon Sep 17 00:00:00 2001 From: hoobnn <111053672+hoobnn@users.noreply.github.com> Date: Tue, 12 May 2026 13:53:38 +0800 Subject: [PATCH] fix: add autocomplete="one-time-code" for TOTP autofill support Add a hidden input with autocomplete="one-time-code" so password managers (1Password, Bitwarden, Chrome, Apple Keychain) can detect and auto-fill TOTP verification codes during 2FA login. --- .../src/components/auth/TotpLoginModal.vue | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/frontend/src/components/auth/TotpLoginModal.vue b/frontend/src/components/auth/TotpLoginModal.vue index 0ae2f482..5f68b9a7 100644 --- a/frontend/src/components/auth/TotpLoginModal.vue +++ b/frontend/src/components/auth/TotpLoginModal.vue @@ -24,6 +24,18 @@
+ +
(['', '', '', '', '', '']) const inputRefs = ref<(HTMLInputElement | null)[]>([]) +const hiddenOtpInputRef = ref(null) // Watch for code changes and auto-submit when 6 digits are entered watch( @@ -104,6 +118,10 @@ defineExpose({ inputRefs.value.forEach(input => { if (input) input.value = '' }) + // Clear hidden autofill input + if (hiddenOtpInputRef.value) { + hiddenOtpInputRef.value.value = '' + } nextTick(() => { inputRefs.value[0]?.focus() }) @@ -126,6 +144,26 @@ const handleCodeInput = (event: Event, index: number) => { } } +// Handle autofill from password managers via the hidden autocomplete="one-time-code" input +const handleHiddenOtpInput = (event: Event) => { + const input = event.target as HTMLInputElement + const digits = input.value.replace(/[^0-9]/g, '').slice(0, 6).split('') + + digits.forEach((digit, i) => { + code.value[i] = digit + if (inputRefs.value[i]) { + inputRefs.value[i]!.value = digit + } + }) + + for (let i = digits.length; i < 6; i++) { + code.value[i] = '' + if (inputRefs.value[i]) { + inputRefs.value[i]!.value = '' + } + } +} + const handleKeydown = (event: KeyboardEvent, index: number) => { if (event.key === 'Backspace') { const input = event.target as HTMLInputElement