feat: enhance webhook event handling and improve profile fetching logic

- Updated the WebhooksService to differentiate between 'InvoiceSettled' and 'InvoicePaymentSettled' events, ensuring accurate payment confirmation and logging.
- Enhanced the useAccounts composable to improve display name handling by skipping generic placeholder names and ensuring the most recent profile metadata is fetched from multiple relays.
- Modified the IndeehubApiService to handle JWT token refresh failures gracefully, allowing public endpoints to function without authentication.
- Updated content store logic to fetch all published projects from the public API, ensuring backstage content is visible to all users regardless of their active content source.

These changes improve the reliability of payment processing, enhance user profile representation, and ensure content visibility across the application.
This commit is contained in:
Dorian
2026-02-14 12:05:32 +00:00
parent bbac44854c
commit d1ac281ad9
6 changed files with 150 additions and 87 deletions

View File

@@ -57,15 +57,21 @@ export function useAccounts() {
})
/**
* Display name: prefer Nostr profile → test persona → pubkey slice.
* Display name: prefer Nostr profile → test persona → npub slice.
* Skips generic placeholder names like "Nostr" so the user sees
* a more useful identifier while they set up their profile.
*/
const activeName = computed(() => {
if (!activeAccount.value) return null
// First: check if we have kind 0 profile metadata
const profile = activeProfile.value
if (profile?.display_name) return profile.display_name
if (profile?.name) return profile.name
if (profile?.display_name && !/^nostr$/i.test(profile.display_name.trim())) {
return profile.display_name
}
if (profile?.name && !/^nostr$/i.test(profile.name.trim())) {
return profile.name
}
// Second: check test personas
const allPersonas: Persona[] = [
@@ -77,8 +83,10 @@ export function useAccounts() {
)
if (match?.name) return match.name
// Fallback: first 8 chars of pubkey
return activeAccount.value?.pubkey?.slice(0, 8) ?? 'Unknown'
// Fallback: truncated npub for a friendlier display
const pk = activeAccount.value?.pubkey
if (!pk) return 'Unknown'
return `npub...${pk.slice(-6)}`
})
/**
@@ -93,11 +101,15 @@ export function useAccounts() {
/**
* Fetch kind 0 profile metadata for a pubkey from relays.
* Results are cached to avoid redundant relay queries.
* Queries multiple relays and keeps the MOST RECENT event
* (highest created_at) to ensure we get the latest profile.
*/
function fetchProfile(pubkey: string) {
if (!pubkey || profileCache.value.has(pubkey)) return
// Track the best (most recent) event seen so far for this fetch
let bestCreatedAt = 0
const relays = [...APP_RELAYS, ...LOOKUP_RELAYS]
try {
const profileSub = pool
@@ -108,18 +120,34 @@ export function useAccounts() {
.subscribe({
next: (event: any) => {
try {
// Only accept this event if it's newer than what we already have
const eventTime = event.created_at ?? 0
if (eventTime < bestCreatedAt) return
const metadata: NostrProfileMetadata = JSON.parse(event.content)
const updated = new Map(profileCache.value)
updated.set(pubkey, metadata)
profileCache.value = updated
// Skip profiles with no meaningful data (empty or
// generic placeholder names without a picture)
const hasName = !!(metadata.display_name || metadata.name)
const isGeneric = hasName && /^nostr$/i.test((metadata.display_name || metadata.name || '').trim())
const hasPicture = !!metadata.picture
// Accept if: has a non-generic name, has a picture, or
// this is the first event we've received
if (bestCreatedAt === 0 || !isGeneric || hasPicture) {
bestCreatedAt = eventTime
const updated = new Map(profileCache.value)
updated.set(pubkey, metadata)
profileCache.value = updated
}
} catch {
// Invalid JSON in profile event
}
},
})
// Close subscription after 5 seconds
setTimeout(() => profileSub.unsubscribe(), 5000)
// Close subscription after 8 seconds (allows slower relays to respond)
setTimeout(() => profileSub.unsubscribe(), 8000)
subscriptions.push(profileSub)
} catch (err) {
console.error(`[useAccounts] Failed to fetch profile for ${pubkey}:`, err)