Frontend component selection logic simplified.
This commit is contained in:
parent
74ba443d3d
commit
3c6c9b29f6
@ -5,7 +5,7 @@
|
||||
<RegisterView v-if="store.currentView === 'register'" />
|
||||
<ProfileView v-if="store.currentView === 'profile'" />
|
||||
<DeviceLinkView v-if="store.currentView === 'device-link'" />
|
||||
<AddCredentialView v-if="store.currentView === 'add-credential'" />
|
||||
<ResetView v-if="store.currentView === 'reset'" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -17,7 +17,7 @@ import LoginView from '@/components/LoginView.vue'
|
||||
import RegisterView from '@/components/RegisterView.vue'
|
||||
import ProfileView from '@/components/ProfileView.vue'
|
||||
import DeviceLinkView from '@/components/DeviceLinkView.vue'
|
||||
import AddCredentialView from '@/components/AddCredentialView.vue'
|
||||
import ResetView from '@/components/ResetView.vue'
|
||||
|
||||
const store = useAuthStore()
|
||||
|
||||
@ -34,15 +34,6 @@ onMounted(async () => {
|
||||
console.log('Failed to load user info:', error)
|
||||
store.currentView = 'login'
|
||||
}
|
||||
if (store.currentCredentials.length) {
|
||||
// User is logged in, go to profile
|
||||
store.currentView = 'profile'
|
||||
} else if (store.currentUser) {
|
||||
// User is logged in via reset link, allow adding a credential
|
||||
store.currentView = 'add-credential'
|
||||
} else {
|
||||
// User is not logged in, show login
|
||||
store.currentView = 'login'
|
||||
}
|
||||
store.selectView()
|
||||
})
|
||||
</script>
|
||||
|
@ -2,14 +2,14 @@
|
||||
<div class="container">
|
||||
<div class="view active">
|
||||
<h1>👋 Welcome!</h1>
|
||||
<div v-if="authStore.currentUser" class="user-info">
|
||||
<h3>👤 {{ authStore.currentUser.user_name }}</h3>
|
||||
<div v-if="authStore.userInfo?.user" class="user-info">
|
||||
<h3>👤 {{ authStore.userInfo.user.user_name }}</h3>
|
||||
<span><strong>Visits:</strong></span>
|
||||
<span>{{ authStore.currentUser.visits || 0 }}</span>
|
||||
<span>{{ authStore.userInfo.user.visits || 0 }}</span>
|
||||
<span><strong>Registered:</strong></span>
|
||||
<span>{{ formatDate(authStore.currentUser.created_at) }}</span>
|
||||
<span>{{ formatDate(authStore.userInfo.user.created_at) }}</span>
|
||||
<span><strong>Last seen:</strong></span>
|
||||
<span>{{ formatDate(authStore.currentUser.last_seen) }}</span>
|
||||
<span>{{ formatDate(authStore.userInfo.user.last_seen) }}</span>
|
||||
</div>
|
||||
|
||||
<h2>Your Passkeys</h2>
|
||||
@ -17,12 +17,12 @@
|
||||
<div v-if="authStore.isLoading">
|
||||
<p>Loading credentials...</p>
|
||||
</div>
|
||||
<div v-else-if="authStore.currentCredentials.length === 0">
|
||||
<div v-else-if="authStore.userInfo?.credentials?.length === 0">
|
||||
<p>No passkeys found.</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div
|
||||
v-for="credential in authStore.currentCredentials"
|
||||
v-for="credential in authStore.userInfo?.credentials || []"
|
||||
:key="credential.credential_uuid"
|
||||
:class="['credential-item', { 'current-session': credential.is_current_session }]"
|
||||
>
|
||||
@ -89,8 +89,9 @@ const updateInterval = ref(null)
|
||||
onMounted(() => {
|
||||
updateInterval.value = setInterval(() => {
|
||||
// Trigger Vue reactivity to update formatDate fields
|
||||
authStore.currentUser = { ...authStore.currentUser }
|
||||
authStore.currentCredentials = [...authStore.currentCredentials]
|
||||
if (authStore.userInfo) {
|
||||
authStore.userInfo = { ...authStore.userInfo }
|
||||
}
|
||||
}, 60000) // Update every minute
|
||||
})
|
||||
|
||||
@ -101,12 +102,12 @@ onUnmounted(() => {
|
||||
})
|
||||
|
||||
const getCredentialAuthName = (credential) => {
|
||||
const authInfo = authStore.aaguidInfo[credential.aaguid]
|
||||
const authInfo = authStore.userInfo?.aaguid_info?.[credential.aaguid]
|
||||
return authInfo ? authInfo.name : 'Unknown Authenticator'
|
||||
}
|
||||
|
||||
const getCredentialAuthIcon = (credential) => {
|
||||
const authInfo = authStore.aaguidInfo[credential.aaguid]
|
||||
const authInfo = authStore.userInfo?.aaguid_info?.[credential.aaguid]
|
||||
if (!authInfo) return null
|
||||
|
||||
const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
|
@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="view active">
|
||||
<h1>🔑 Add Device Credential</h1>
|
||||
<h3>👤 {{ authStore.currentUser.user_name }}</h3>
|
||||
<h1>🔑 Add New Credential</h1>
|
||||
<h3>👤 {{ authStore.userInfo?.user?.user_name }}</h3>
|
||||
<p>Proceed to complete {{authStore.userInfo?.session_type}}:</p>
|
||||
<button
|
||||
class="btn-primary"
|
||||
:disabled="authStore.isLoading"
|
||||
@ -16,25 +17,20 @@
|
||||
|
||||
<script setup>
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { computed } from 'vue'
|
||||
import { registerCredential } from '@/utils/passkey'
|
||||
|
||||
const authStore = useAuthStore()
|
||||
const hasDeviceSession = computed(() => !!authStore.currentUser)
|
||||
|
||||
async function register() {
|
||||
if (!hasDeviceSession.value) {
|
||||
authStore.showMessage('No valid device addition session', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
authStore.isLoading = true
|
||||
authStore.showMessage('Starting registration...', 'info')
|
||||
|
||||
try {
|
||||
// TODO: For reset sessions, might use registerWithToken() in the future
|
||||
const result = await registerCredential()
|
||||
console.log("Result", result)
|
||||
await authStore.setSessionCookie(result.session_token)
|
||||
|
||||
authStore.showMessage('Passkey registered successfully!', 'success', 2000)
|
||||
authStore.currentView = 'profile'
|
||||
} catch (error) {
|
@ -4,13 +4,11 @@ import { registerUser, authenticateUser, registerWithToken } from '@/utils/passk
|
||||
export const useAuthStore = defineStore('auth', {
|
||||
state: () => ({
|
||||
// Auth State
|
||||
currentUser: null,
|
||||
currentCredentials: [],
|
||||
aaguidInfo: {},
|
||||
userInfo: null, // Contains the full user info response: {user, credentials, aaguid_info, session_type, authenticated}
|
||||
isLoading: false,
|
||||
|
||||
// UI State
|
||||
currentView: 'login', // 'login', 'register', 'profile', 'device-link'
|
||||
currentView: 'login', // 'login', 'register', 'profile', 'reset'
|
||||
status: {
|
||||
message: '',
|
||||
type: 'info',
|
||||
@ -46,9 +44,15 @@ export const useAuthStore = defineStore('auth', {
|
||||
try {
|
||||
const result = await registerUser(user_name)
|
||||
|
||||
this.currentUser = {
|
||||
user_id: result.user_id,
|
||||
user_name: user_name,
|
||||
this.userInfo = {
|
||||
user: {
|
||||
user_id: result.user_id,
|
||||
user_name: user_name,
|
||||
},
|
||||
credentials: [],
|
||||
aaguid_info: {},
|
||||
session_type: null,
|
||||
authenticated: false
|
||||
}
|
||||
|
||||
await this.setSessionCookie(result.session_token)
|
||||
@ -70,15 +74,16 @@ export const useAuthStore = defineStore('auth', {
|
||||
this.isLoading = false
|
||||
}
|
||||
},
|
||||
selectView() {
|
||||
if (!store.userInfo) this.currentView = 'login'
|
||||
else if (store.userInfo?.authenticated) this.currentView = 'profile'
|
||||
else this.currentView = 'reset'
|
||||
},
|
||||
async loadUserInfo() {
|
||||
const response = await fetch('/auth/user-info', {method: 'POST'})
|
||||
const result = await response.json()
|
||||
if (result.detail) throw new Error(`Server: ${result.detail}`)
|
||||
|
||||
this.currentUser = result.user
|
||||
this.currentCredentials = result.credentials || []
|
||||
this.aaguidInfo = result.aaguid_info || {}
|
||||
if (result.session_type === 'device addition') this.currentView = 'add-credential'
|
||||
this.userInfo = result
|
||||
console.log('User info loaded:', result)
|
||||
},
|
||||
async deleteCredential(uuid) {
|
||||
@ -95,9 +100,7 @@ export const useAuthStore = defineStore('auth', {
|
||||
console.error('Logout error:', error)
|
||||
}
|
||||
|
||||
this.currentUser = null
|
||||
this.currentCredentials = []
|
||||
this.aaguidInfo = {}
|
||||
this.userInfo = null
|
||||
},
|
||||
}
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user