Refactor authentication and async operation handling in useAuth composable
- Introduce useMultiAsyncOperation to manage multiple async operations in useAuth, enhancing error handling and loading state management. - Replace manual loading and error state management with standardized async operation patterns for initialize, login, register, and logout functions. - Update related components to utilize the new async operation structure, improving code clarity and maintainability. - Add useAsyncOperation to other composables (useChat, useTicketPurchase, useMarket) for consistent async handling across the application.
This commit is contained in:
parent
e0443742c5
commit
7c439361b7
5 changed files with 298 additions and 133 deletions
|
|
@ -1,31 +1,45 @@
|
|||
import { ref, computed } from 'vue'
|
||||
import { lnbitsAPI, type User, type LoginCredentials, type RegisterData } from '@/lib/api/lnbits'
|
||||
import { useMultiAsyncOperation } from '@/core/composables/useAsyncOperation'
|
||||
|
||||
const currentUser = ref<User | null>(null)
|
||||
const isLoading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
|
||||
// Shared async operations for auth actions
|
||||
const authOperations = useMultiAsyncOperation<{
|
||||
initialize: User | null
|
||||
login: User
|
||||
register: User
|
||||
logout: void
|
||||
}>()
|
||||
|
||||
export function useAuth() {
|
||||
const isAuthenticated = computed(() => !!currentUser.value)
|
||||
|
||||
// Get operation instances
|
||||
const initializeOp = authOperations.createOperation('initialize')
|
||||
const loginOp = authOperations.createOperation('login')
|
||||
const registerOp = authOperations.createOperation('register')
|
||||
const logoutOp = authOperations.createOperation('logout')
|
||||
|
||||
/**
|
||||
* Initialize authentication on app start
|
||||
*/
|
||||
async function initialize(): Promise<void> {
|
||||
try {
|
||||
isLoading.value = true
|
||||
error.value = null
|
||||
|
||||
if (lnbitsAPI.isAuthenticated()) {
|
||||
const user = await lnbitsAPI.getCurrentUser()
|
||||
currentUser.value = user
|
||||
}
|
||||
} catch (err) {
|
||||
error.value = err instanceof Error ? err.message : 'Failed to initialize authentication'
|
||||
// Clear invalid token
|
||||
await initializeOp.execute(async () => {
|
||||
if (lnbitsAPI.isAuthenticated()) {
|
||||
const user = await lnbitsAPI.getCurrentUser()
|
||||
currentUser.value = user
|
||||
return user
|
||||
}
|
||||
return null
|
||||
}, {
|
||||
errorMessage: 'Failed to initialize authentication',
|
||||
showToast: false // Don't show toast for initialization errors
|
||||
})
|
||||
} catch {
|
||||
// Clear invalid token on error
|
||||
await logout()
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -33,88 +47,77 @@ export function useAuth() {
|
|||
* Login with username and password
|
||||
*/
|
||||
async function login(credentials: LoginCredentials): Promise<void> {
|
||||
try {
|
||||
isLoading.value = true
|
||||
error.value = null
|
||||
|
||||
await loginOp.execute(async () => {
|
||||
await lnbitsAPI.login(credentials)
|
||||
|
||||
// Get user details
|
||||
const user = await lnbitsAPI.getCurrentUser()
|
||||
currentUser.value = user
|
||||
} catch (err) {
|
||||
error.value = err instanceof Error ? err.message : 'Login failed'
|
||||
throw err
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
return user
|
||||
}, {
|
||||
errorMessage: 'Login failed'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new user
|
||||
*/
|
||||
async function register(data: RegisterData): Promise<void> {
|
||||
try {
|
||||
isLoading.value = true
|
||||
error.value = null
|
||||
|
||||
await registerOp.execute(async () => {
|
||||
await lnbitsAPI.register(data)
|
||||
|
||||
// Get user details
|
||||
const user = await lnbitsAPI.getCurrentUser()
|
||||
currentUser.value = user
|
||||
} catch (err) {
|
||||
error.value = err instanceof Error ? err.message : 'Registration failed'
|
||||
throw err
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
return user
|
||||
}, {
|
||||
errorMessage: 'Registration failed'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout and clear user data
|
||||
*/
|
||||
async function logout(): Promise<void> {
|
||||
// Clear local state
|
||||
lnbitsAPI.logout()
|
||||
currentUser.value = null
|
||||
error.value = null
|
||||
await logoutOp.execute(async () => {
|
||||
// Clear local state
|
||||
lnbitsAPI.logout()
|
||||
currentUser.value = null
|
||||
// Clear all auth operation states
|
||||
authOperations.clearAll()
|
||||
}, {
|
||||
showToast: false // Don't show toast for logout
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user password
|
||||
*/
|
||||
async function updatePassword(currentPassword: string, newPassword: string): Promise<void> {
|
||||
try {
|
||||
isLoading.value = true
|
||||
error.value = null
|
||||
|
||||
const updatePasswordOp = authOperations.createOperation('updatePassword' as any)
|
||||
|
||||
return await updatePasswordOp.execute(async () => {
|
||||
const updatedUser = await lnbitsAPI.updatePassword(currentPassword, newPassword)
|
||||
currentUser.value = updatedUser
|
||||
} catch (err) {
|
||||
error.value = err instanceof Error ? err.message : 'Failed to update password'
|
||||
throw err
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
return updatedUser
|
||||
}, {
|
||||
errorMessage: 'Failed to update password'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user profile
|
||||
*/
|
||||
async function updateProfile(data: Partial<User>): Promise<void> {
|
||||
try {
|
||||
isLoading.value = true
|
||||
error.value = null
|
||||
|
||||
const updateProfileOp = authOperations.createOperation('updateProfile' as any)
|
||||
|
||||
return await updateProfileOp.execute(async () => {
|
||||
const updatedUser = await lnbitsAPI.updateProfile(data)
|
||||
currentUser.value = updatedUser
|
||||
} catch (err) {
|
||||
error.value = err instanceof Error ? err.message : 'Failed to update profile'
|
||||
throw err
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
return updatedUser
|
||||
}, {
|
||||
errorMessage: 'Failed to update profile'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -145,8 +148,9 @@ export function useAuth() {
|
|||
// State
|
||||
currentUser: computed(() => currentUser.value),
|
||||
isAuthenticated,
|
||||
isLoading,
|
||||
error,
|
||||
isLoading: computed(() => authOperations.isAnyLoading()),
|
||||
error: computed(() => authOperations.hasAnyError() ?
|
||||
(initializeOp.error.value || loginOp.error.value || registerOp.error.value || logoutOp.error.value) : null),
|
||||
userDisplay,
|
||||
|
||||
// Actions
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue