- Added updateWalletBalance method in PaymentService to handle wallet balance updates from WebSocket notifications, improving wallet management. - Deprecated the existing updateWalletBalance method in AuthService, redirecting calls to the new PaymentService method for better consistency and maintainability. - Updated WalletWebSocketService to utilize PaymentService for balance updates, ensuring accurate wallet state management. These changes enhance the architecture of wallet balance handling and streamline the update process across services.
192 lines
No EOL
5.6 KiB
TypeScript
192 lines
No EOL
5.6 KiB
TypeScript
// Auth service for LNbits integration
|
|
import { ref, computed } from 'vue'
|
|
import { BaseService } from '@/core/base/BaseService'
|
|
import { eventBus } from '@/core/event-bus'
|
|
import { tryInjectService, SERVICE_TOKENS } from '@/core/di-container'
|
|
import type { LoginCredentials, RegisterData, User } from '@/lib/api/lnbits'
|
|
|
|
export class AuthService extends BaseService {
|
|
// Service metadata
|
|
protected readonly metadata = {
|
|
name: 'AuthService',
|
|
version: '1.0.0',
|
|
dependencies: ['LnbitsAPI'] // Auth service depends on LnbitsAPI for authentication
|
|
}
|
|
|
|
// Public state
|
|
public isAuthenticated = ref(false)
|
|
public user = ref<User | null>(null)
|
|
public isLoading = ref(false)
|
|
public error = ref<Error | null>(null)
|
|
|
|
// Computed properties for compatibility with global auth
|
|
public currentUser = computed(() => this.user.value)
|
|
public userDisplay = computed(() => {
|
|
if (!this.user.value) return null
|
|
|
|
return {
|
|
name: this.user.value.username || this.user.value.email || 'Anonymous',
|
|
username: this.user.value.username,
|
|
email: this.user.value.email,
|
|
id: this.user.value.id,
|
|
shortId: this.user.value.id.slice(0, 8) + '...' + this.user.value.id.slice(-8)
|
|
}
|
|
})
|
|
|
|
/**
|
|
* Service-specific initialization (called by BaseService)
|
|
*/
|
|
protected async onInitialize(): Promise<void> {
|
|
this.debug('Initializing auth service...')
|
|
|
|
// Check for existing auth state and fetch user data
|
|
await this.checkAuth()
|
|
|
|
if (this.isAuthenticated.value) {
|
|
eventBus.emit('auth:login', { user: this.user.value }, 'auth-service')
|
|
}
|
|
}
|
|
|
|
async checkAuth(): Promise<boolean> {
|
|
if (!this.lnbitsAPI.isAuthenticated()) {
|
|
this.debug('No auth token found - user needs to login')
|
|
this.isAuthenticated.value = false
|
|
this.user.value = null
|
|
return false
|
|
}
|
|
|
|
try {
|
|
this.isLoading.value = true
|
|
const userData = await this.lnbitsAPI.getCurrentUser()
|
|
|
|
this.user.value = userData
|
|
this.isAuthenticated.value = true
|
|
|
|
this.debug(`User authenticated: ${userData.username || userData.id} (${userData.pubkey?.slice(0, 8)})`)
|
|
|
|
return true
|
|
|
|
} catch (error) {
|
|
this.handleError(error, 'checkAuth')
|
|
this.isAuthenticated.value = false
|
|
this.user.value = null
|
|
// Clear invalid token
|
|
this.lnbitsAPI.logout()
|
|
return false
|
|
} finally {
|
|
this.isLoading.value = false
|
|
}
|
|
}
|
|
|
|
async login(credentials: LoginCredentials): Promise<void> {
|
|
this.isLoading.value = true
|
|
|
|
try {
|
|
await this.lnbitsAPI.login(credentials)
|
|
const userData = await this.lnbitsAPI.getCurrentUser()
|
|
|
|
this.user.value = userData
|
|
this.isAuthenticated.value = true
|
|
|
|
eventBus.emit('auth:login', { user: userData }, 'auth-service')
|
|
|
|
} catch (error) {
|
|
const err = this.handleError(error, 'login')
|
|
eventBus.emit('auth:login-failed', { error: err }, 'auth-service')
|
|
throw err
|
|
} finally {
|
|
this.isLoading.value = false
|
|
}
|
|
}
|
|
|
|
async register(data: RegisterData): Promise<void> {
|
|
this.isLoading.value = true
|
|
|
|
try {
|
|
await this.lnbitsAPI.register(data)
|
|
const userData = await this.lnbitsAPI.getCurrentUser()
|
|
|
|
this.user.value = userData
|
|
this.isAuthenticated.value = true
|
|
|
|
eventBus.emit('auth:login', { user: userData }, 'auth-service')
|
|
|
|
} catch (error) {
|
|
const err = this.handleError(error, 'register')
|
|
eventBus.emit('auth:login-failed', { error: err }, 'auth-service')
|
|
throw err
|
|
} finally {
|
|
this.isLoading.value = false
|
|
}
|
|
}
|
|
|
|
async logout(): Promise<void> {
|
|
this.lnbitsAPI.logout()
|
|
this.user.value = null
|
|
this.isAuthenticated.value = false
|
|
this.error.value = null
|
|
|
|
eventBus.emit('auth:logout', {}, 'auth-service')
|
|
}
|
|
|
|
async refresh(): Promise<void> {
|
|
// Re-fetch user data from API
|
|
await this.checkAuth()
|
|
}
|
|
|
|
/**
|
|
* @deprecated Use PaymentService.updateWalletBalance() instead
|
|
* This method will be removed in a future version
|
|
*/
|
|
updateWalletBalance(balanceMsat: number, walletId?: string): void {
|
|
console.warn('AuthService.updateWalletBalance is deprecated. Use PaymentService.updateWalletBalance() instead')
|
|
|
|
// For backwards compatibility, delegate to PaymentService if available
|
|
const paymentService = tryInjectService(SERVICE_TOKENS.PAYMENT_SERVICE) as any
|
|
if (paymentService?.updateWalletBalance) {
|
|
paymentService.updateWalletBalance(balanceMsat, walletId)
|
|
}
|
|
}
|
|
|
|
async initialize(): Promise<void> {
|
|
// Call BaseService initialize first to inject dependencies
|
|
await super.initialize()
|
|
}
|
|
|
|
async updatePassword(currentPassword: string, newPassword: string): Promise<void> {
|
|
try {
|
|
this.isLoading.value = true
|
|
const updatedUser = await this.lnbitsAPI.updatePassword(currentPassword, newPassword)
|
|
this.user.value = updatedUser
|
|
} catch (error) {
|
|
const err = this.handleError(error, 'updatePassword')
|
|
throw err
|
|
} finally {
|
|
this.isLoading.value = false
|
|
}
|
|
}
|
|
|
|
async updateProfile(data: Partial<User>): Promise<void> {
|
|
try {
|
|
this.isLoading.value = true
|
|
const updatedUser = await this.lnbitsAPI.updateProfile(data)
|
|
this.user.value = updatedUser
|
|
} catch (error) {
|
|
const err = this.handleError(error, 'updateProfile')
|
|
throw err
|
|
} finally {
|
|
this.isLoading.value = false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Cleanup when service is disposed
|
|
*/
|
|
protected async onDispose(): Promise<void> {
|
|
this.logout()
|
|
this.debug('Auth service disposed')
|
|
}
|
|
}
|
|
|
|
// Export singleton instance
|
|
export const auth = new AuthService() |