webapp/src/modules/base/auth/auth-service.ts
padreug f93058add2 Implement updateWalletBalance method in PaymentService and deprecate AuthService method
- 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.
2025-09-18 09:31:15 +02:00

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()