Refactor authentication architecture to eliminate dual auth complexity

This major refactor consolidates the authentication system to use a single
source of truth, eliminating timing issues and architectural complexity
that was causing chat and payment functionality problems.

Key Changes:
• Remove old global useAuth composable and replace with useAuthService wrapper
• Update all 25+ files to use consistent auth pattern via dependency injection
• Eliminate dual auth detection workarounds from services (ChatService, PaymentService, etc.)
• Fix TypeScript errors and add proper Uint8Array conversion for Nostr private keys
• Consolidate auth state management to AuthService as single source of truth

Benefits:
• Resolves chat peer loading and message subscription timing issues
• Fixes wallet detection problems for Lightning payments
• Eliminates race conditions between global and injected auth
• Maintains API compatibility while improving architecture
• Reduces code complexity and improves maintainability

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
padreug 2025-09-07 00:47:02 +02:00
parent 5633aa154b
commit 4feb5459cc
27 changed files with 210 additions and 518 deletions

View file

@ -51,82 +51,23 @@ export class PaymentService extends BaseService {
this.debug('PaymentService initialized with clean state')
}
/**
* Get global auth composable
*/
private async getGlobalAuth() {
try {
// Use async dynamic import to avoid circular dependencies
const { auth } = await import('@/composables/useAuth')
return auth
} catch (error) {
this.debug('Could not access global auth:', error)
return null
}
}
/**
* Get user wallets from authenticated user (using dual auth detection)
*/
async getUserWalletsAsync() {
// Check both injected auth service AND global auth composable
const hasAuthService = this.authService?.user?.value?.wallets
const globalAuth = await this.getGlobalAuth()
const hasGlobalAuth = globalAuth?.currentUser?.value?.wallets
const wallets = hasAuthService || hasGlobalAuth || []
this.debug('Getting user wallets:', {
hasAuthService: !!hasAuthService,
hasGlobalAuth: !!hasGlobalAuth,
walletsCount: Array.isArray(wallets) ? wallets.length : 0,
walletsSource: hasAuthService ? 'authService' : (hasGlobalAuth ? 'globalAuth' : 'none')
})
return wallets
}
/**
* Get user wallets from authenticated user (synchronous fallback)
* Get user wallets from authenticated user
*/
get userWallets() {
// Fallback to just auth service for synchronous access
return this.authService?.user?.value?.wallets || []
}
/**
* Check if user has any wallet with balance (async version)
*/
async hasWalletWithBalanceAsync(): Promise<boolean> {
const wallets = await this.getUserWalletsAsync()
return wallets.some((wallet: any) => wallet.balance_msat > 0)
}
/**
* Check if user has any wallet with balance (synchronous fallback)
* Check if user has any wallet with balance
*/
get hasWalletWithBalance(): boolean {
return this.userWallets.some((wallet: any) => wallet.balance_msat > 0)
}
/**
* Find wallet with sufficient balance for payment (async version)
*/
async getWalletWithBalanceAsync(requiredAmountSats?: number): Promise<any | null> {
const wallets = await this.getUserWalletsAsync()
if (!wallets.length) return null
if (requiredAmountSats) {
// Convert sats to msat for comparison
const requiredMsat = requiredAmountSats * 1000
return wallets.find((wallet: any) => wallet.balance_msat >= requiredMsat)
}
return wallets.find((wallet: any) => wallet.balance_msat > 0)
}
/**
* Find wallet with sufficient balance for payment (synchronous fallback)
* Find wallet with sufficient balance for payment
*/
getWalletWithBalance(requiredAmountSats?: number): any | null {
const wallets = this.userWallets
@ -197,26 +138,14 @@ export class PaymentService extends BaseService {
requiredAmountSats?: number,
options: PaymentOptions = {}
): Promise<PaymentResult> {
// Check authentication using dual auth detection
const hasAuthService = this.authService?.isAuthenticated?.value && this.authService?.user?.value
const globalAuth = await this.getGlobalAuth()
const hasGlobalAuth = globalAuth?.isAuthenticated?.value && globalAuth?.currentUser?.value
if (!hasAuthService && !hasGlobalAuth) {
this.debug('Payment failed - user not authenticated:', {
hasAuthService: !!hasAuthService,
hasGlobalAuth: !!hasGlobalAuth
})
// Check authentication
if (!this.authService?.isAuthenticated?.value || !this.authService?.user?.value) {
throw new Error('User must be authenticated to pay with wallet')
}
// Find suitable wallet using async version for proper dual auth detection
const wallet = await this.getWalletWithBalanceAsync(requiredAmountSats)
// Find suitable wallet
const wallet = this.getWalletWithBalance(requiredAmountSats)
if (!wallet) {
this.debug('No wallet with sufficient balance found:', {
requiredAmountSats,
walletsAvailable: (await this.getUserWalletsAsync()).length
})
throw new Error('No wallet with sufficient balance found')
}
@ -307,8 +236,8 @@ export class PaymentService extends BaseService {
return null
}
// Try wallet payment first if user has balance (use async check for proper dual auth detection)
if (await this.hasWalletWithBalanceAsync()) {
// Try wallet payment first if user has balance
if (this.hasWalletWithBalance) {
try {
return await this.payWithWallet(
paymentRequest,
@ -319,8 +248,6 @@ export class PaymentService extends BaseService {
this.debug('Wallet payment failed, offering external wallet option:', error)
// Don't throw here, continue to external wallet option
}
} else {
this.debug('No wallet with balance available, skipping wallet payment')
}
// Fallback to external wallet