Enhance authentication handling and error logging in ChatService and NostrmarketService

- Introduce a flag in ChatService to track initialization status and improve message handling.
- Enhance error handling and logging for API responses in ChatService, including warnings for invalid data formats.
- Update NostrmarketService to utilize global authentication checks, improving user authentication flow.
- Refactor CheckoutPage to streamline pubkey retrieval and enhance error messages related to Nostr identity configuration.

These changes improve the robustness of authentication processes and provide clearer feedback to users during interactions.
This commit is contained in:
padreug 2025-09-06 23:46:23 +02:00
commit d3ee19f56f
3 changed files with 65 additions and 23 deletions

View file

@ -127,6 +127,8 @@ export class ChatService extends BaseService {
this.debug('Chat service fully initialized and ready!') this.debug('Chat service fully initialized and ready!')
} }
private isFullyInitialized = false
// Initialize message handling (subscription + history loading) // Initialize message handling (subscription + history loading)
async initializeMessageHandling(): Promise<void> { async initializeMessageHandling(): Promise<void> {
// Set up real-time subscription // Set up real-time subscription
@ -381,10 +383,13 @@ export class ChatService extends BaseService {
try { try {
const authToken = getAuthToken() const authToken = getAuthToken()
if (!authToken) { if (!authToken) {
console.warn('💬 No authentication token found for loading peers from API')
throw new Error('No authentication token found') throw new Error('No authentication token found')
} }
const API_BASE_URL = config.api.baseUrl || 'http://localhost:5006' const API_BASE_URL = config.api.baseUrl || 'http://localhost:5006'
console.log('💬 Loading peers from API:', `${API_BASE_URL}/api/v1/auth/nostr/pubkeys`)
const response = await fetch(`${API_BASE_URL}/api/v1/auth/nostr/pubkeys`, { const response = await fetch(`${API_BASE_URL}/api/v1/auth/nostr/pubkeys`, {
headers: { headers: {
'Authorization': `Bearer ${authToken}`, 'Authorization': `Bearer ${authToken}`,
@ -393,15 +398,26 @@ export class ChatService extends BaseService {
}) })
if (!response.ok) { if (!response.ok) {
throw new Error(`Failed to load peers: ${response.status}`) const errorText = await response.text()
console.error('💬 API response error:', response.status, errorText)
throw new Error(`Failed to load peers: ${response.status} - ${errorText}`)
} }
const data = await response.json() const data = await response.json()
console.log('💬 API returned', data?.length || 0, 'peers')
// Clear existing peers and load from API if (!Array.isArray(data)) {
this.peers.value.clear() console.warn('💬 Invalid API response format - expected array, got:', typeof data)
return
}
// Don't clear existing peers - merge instead
data.forEach((peer: any) => { data.forEach((peer: any) => {
if (!peer.pubkey) {
console.warn('💬 Skipping peer without pubkey:', peer)
return
}
const chatPeer: ChatPeer = { const chatPeer: ChatPeer = {
pubkey: peer.pubkey, pubkey: peer.pubkey,
name: peer.username || `User ${peer.pubkey.slice(0, 8)}`, name: peer.username || `User ${peer.pubkey.slice(0, 8)}`,
@ -414,25 +430,31 @@ export class ChatService extends BaseService {
// Save to storage // Save to storage
this.savePeersToStorage() this.savePeersToStorage()
console.log(`Loaded ${data.length} peers from API`) console.log(`Loaded ${data.length} peers from API, total peers now: ${this.peers.value.size}`)
} catch (error) { } catch (error) {
console.error('Failed to load peers from API:', error) console.error('Failed to load peers from API:', error)
throw error // Don't re-throw - peers from storage are still available
} }
} }
private loadPeersFromStorage(): void { private loadPeersFromStorage(): void {
// Skip loading peers in constructor as StorageService may not be available yet // Skip loading peers in constructor as StorageService may not be available yet
// This will be called later during initialization when dependencies are ready // This will be called later during initialization when dependencies are ready
if (!this.isInitialized.value) { if (!this.isInitialized.value || !this.storageService) {
this.debug('Skipping peer loading from storage - not initialized or storage unavailable')
return return
} }
try {
const peersArray = this.storageService.getUserData('chat-peers', []) as ChatPeer[] const peersArray = this.storageService.getUserData('chat-peers', []) as ChatPeer[]
console.log('💬 Loading', peersArray.length, 'peers from storage')
peersArray.forEach(peer => { peersArray.forEach(peer => {
this.peers.value.set(peer.pubkey, peer) this.peers.value.set(peer.pubkey, peer)
}) })
} catch (error) {
console.warn('💬 Failed to load peers from storage:', error)
}
} }
private savePeersToStorage(): void { private savePeersToStorage(): void {
@ -743,7 +765,6 @@ export class ChatService extends BaseService {
const hasGlobalAuth = auth.currentUser.value?.pubkey const hasGlobalAuth = auth.currentUser.value?.pubkey
const userPubkey = hasAuthService ? this.authService.user.value.pubkey : auth.currentUser.value?.pubkey const userPubkey = hasAuthService ? this.authService.user.value.pubkey : auth.currentUser.value?.pubkey
if (!userPubkey || !this.relayHub) return if (!userPubkey || !this.relayHub) return
try { try {

View file

@ -1,6 +1,7 @@
import { finalizeEvent, type EventTemplate, nip04 } from 'nostr-tools' import { finalizeEvent, type EventTemplate, nip04 } from 'nostr-tools'
import { BaseService } from '@/core/base/BaseService' import { BaseService } from '@/core/base/BaseService'
import type { Stall, Product, Order } from '@/stores/market' import type { Stall, Product, Order } from '@/stores/market'
import { auth } from '@/composables/useAuth'
export interface NostrmarketStall { export interface NostrmarketStall {
id: string id: string
@ -106,15 +107,32 @@ export class NostrmarketService extends BaseService {
} }
private getAuth() { private getAuth() {
if (!this.authService?.isAuthenticated?.value || !this.authService?.user?.value?.prvkey) { // Check global auth first
throw new Error('User not authenticated or private key not available') if (!auth.isAuthenticated.value) {
throw new Error('User not authenticated')
} }
const pubkey = this.authService.user.value.pubkey // Try to get keys from global auth first, fallback to injected auth service
const prvkey = this.authService.user.value.prvkey const globalUser = auth.currentUser.value
const serviceUser = this.authService?.user?.value
const pubkey = globalUser?.pubkey || serviceUser?.pubkey
const prvkey = globalUser?.prvkey || serviceUser?.prvkey
if (!pubkey || !prvkey) { if (!pubkey || !prvkey) {
throw new Error('Public key or private key is missing') this.debug('Auth check failed:', {
globalUser: {
exists: !!globalUser,
hasPubkey: !!globalUser?.pubkey,
hasPrvkey: !!globalUser?.prvkey
},
serviceUser: {
exists: !!serviceUser,
hasPubkey: !!serviceUser?.pubkey,
hasPrvkey: !!serviceUser?.prvkey
}
})
throw new Error('Nostr keys not available. Please ensure your Nostr identity is configured in your profile.')
} }
// Validate that we have proper hex strings // Validate that we have proper hex strings

View file

@ -272,6 +272,7 @@ import { ref, computed, onMounted } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { useMarketStore } from '@/stores/market' import { useMarketStore } from '@/stores/market'
import { injectService, SERVICE_TOKENS } from '@/core/di-container' import { injectService, SERVICE_TOKENS } from '@/core/di-container'
import { auth } from '@/composables/useAuth'
import { import {
Card, Card,
CardHeader, CardHeader,
@ -411,21 +412,23 @@ const placeOrder = async () => {
} }
// Debug logging to understand auth state // Debug logging to understand auth state
console.log('Auth check:', { console.log('Auth check:', {
isAuthenticated: authService.isAuthenticated.value, isAuthenticated: auth.isAuthenticated.value,
user: authService.user.value, user: auth.currentUser.value,
userPubkey: auth.currentUser.value?.pubkey,
authServiceUser: authService.user.value,
hasPubkey: !!authService.user.value?.pubkey, hasPubkey: !!authService.user.value?.pubkey,
nostrPubkey: authService.user.value?.pubkey nostrPubkey: authService.user.value?.pubkey
}) })
// Get pubkey from auth service // Try to get pubkey from main auth first, fallback to auth service
const userPubkey = authService.user.value?.pubkey const userPubkey = auth.currentUser.value?.pubkey || authService.user.value?.pubkey
if (!authService.isAuthenticated.value) { if (!auth.isAuthenticated.value) {
throw new Error('You must be logged in to place an order') throw new Error('You must be logged in to place an order')
} }
if (!userPubkey) { if (!userPubkey) {
throw new Error('No Nostr public key found. Please ensure your Nostr identity is configured.') throw new Error('Nostr identity required: Please configure your Nostr public key in your profile settings to place orders.')
} }
// Create the order using the market store's order placement functionality // Create the order using the market store's order placement functionality