fix: improve secret input

Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
2026-08-08 22:39:48 -04:00
parent 0dd735045d
commit 71ddd3442f
+16 -10
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, onMounted, computed, watch } from 'vue';
import { ref, onMounted, computed, watch, nextTick } from 'vue';
import { useRoute } from 'vue-router';
import { useUserStore } from '@KTXC/stores/userStore';
import { authenticationService } from '@KTXC/services/authenticationService';
@@ -15,6 +15,7 @@ type LoginPhase = 'identity' | 'method' | 'mfa';
// Form state
const identity = ref('');
const authResponse = ref(''); // password, code, etc.
const authInput = ref<{ focus: () => void } | null>(null);
const showPassword = ref(false);
const rememberMe = ref(false);
@@ -60,14 +61,14 @@ const pageTitle = computed(() => {
});
// Input label/type based on selected method
const isPasswordMethod = computed(() => selectedMethod.value?.id === 'password');
const authInputLabel = computed(() => {
if (!selectedMethod.value) return 'Password';
return selectedMethod.value.method === 'credential' ? 'Password' : 'Verification Code';
return isPasswordMethod.value ? 'Password' : 'Verification Code';
});
const authInputType = computed(() => {
if (!selectedMethod.value) return 'password';
return selectedMethod.value.method === 'credential' ? 'password' : 'text';
return isPasswordMethod.value ? 'password' : 'text';
});
// Validation rules
@@ -115,6 +116,9 @@ onMounted(async () => {
// Watch for method selection changes (for challenge-based methods)
watch(selectedMethod, async (newMethod) => {
await nextTick();
authInput.value?.focus();
if (newMethod && newMethod.method === 'challenge' && !challengeSent.value) {
// Initiate challenge for methods that need it (SMS, email, TOTP)
await initiateChallenge(newMethod.id);
@@ -452,6 +456,7 @@ function getMethodIcon(method: AuthenticationMethod): string {
>
<div class="mb-6">
<v-text-field
ref="authInput"
v-model="authResponse"
:rules="authResponseRules"
:type="authInputType === 'password' && !showPassword ? 'password' : 'text'"
@@ -460,8 +465,8 @@ function getMethodIcon(method: AuthenticationMethod): string {
hide-details="auto"
variant="outlined"
color="primary"
:autocomplete="selectedMethod?.method === 'credential' ? 'current-password' : 'one-time-code'"
:inputmode="selectedMethod?.method !== 'credential' ? 'numeric' : undefined"
:autocomplete="isPasswordMethod ? 'current-password' : 'off'"
:inputmode="isPasswordMethod ? undefined : 'numeric'"
autofocus
>
<template v-if="authInputType === 'password'" v-slot:append-inner>
@@ -475,7 +480,7 @@ function getMethodIcon(method: AuthenticationMethod): string {
</v-text-field>
</div>
<div v-if="selectedMethod?.method === 'credential'" class="d-flex align-center mt-4 mb-7 mb-sm-0">
<div v-if="isPasswordMethod" class="d-flex align-center mt-4 mb-7 mb-sm-0">
<v-checkbox
v-model="rememberMe"
label="Keep me logged in"
@@ -498,7 +503,7 @@ function getMethodIcon(method: AuthenticationMethod): string {
size="large"
type="submit"
>
{{ selectedMethod?.method === 'credential' ? 'Login' : 'Verify' }}
{{ isPasswordMethod ? 'Login' : 'Verify' }}
</v-btn>
<v-btn
@@ -539,6 +544,7 @@ function getMethodIcon(method: AuthenticationMethod): string {
<div class="mb-6">
<v-label>Verification Code</v-label>
<v-text-field
ref="authInput"
v-model="authResponse"
:rules="authResponseRules"
type="text"
@@ -547,7 +553,7 @@ function getMethodIcon(method: AuthenticationMethod): string {
hide-details="auto"
variant="outlined"
color="primary"
autocomplete="one-time-code"
autocomplete="off"
inputmode="numeric"
autofocus
></v-text-field>