diff --git a/src/App.vue b/src/App.vue index fa10298..28ad4be 100644 --- a/src/App.vue +++ b/src/App.vue @@ -49,6 +49,7 @@ import { ref, computed, onMounted } from 'vue' import { useRouter, useRoute } from 'vue-router' import { useAuthStore } from './stores/auth' +import { useContentStore } from './stores/content' import { useSearchSelectionStore } from './stores/searchSelection' import AppHeader from './components/AppHeader.vue' import BackstageHeader from './components/BackstageHeader.vue' @@ -62,6 +63,7 @@ import type { Content } from './types/content' const router = useRouter() const route = useRoute() const authStore = useAuthStore() +const contentStore = useContentStore() const searchSelection = useSearchSelectionStore() /** @@ -93,6 +95,12 @@ function handleAuthClose() { function handleAuthSuccess() { showAuthModal.value = false + + // Re-fetch content so backstage-published projects are merged + // into the active catalog (they require session tokens which + // are only available after login completes). + contentStore.fetchContent() + if (pendingRedirect.value) { router.push(pendingRedirect.value) pendingRedirect.value = null diff --git a/src/components/AuthModal.vue b/src/components/AuthModal.vue index 90b7504..221bd28 100644 --- a/src/components/AuthModal.vue +++ b/src/components/AuthModal.vue @@ -493,15 +493,10 @@ async function handleAmberPubkeyRead() { const pubkey = await decodePubkeyFromClipboard(clipboardText) amberPubkey.value = pubkey - // Register the Amber account in the account manager so the app - // knows who is signing in (the signer is set but we won't call - // signEvent on it — we use intents + clipboard for that) - const { AmberClipboardSigner, AmberClipboardAccount } = await import('../lib/accounts') - const signer = new AmberClipboardSigner() - signer.pubkey = pubkey - const account = new AmberClipboardAccount(pubkey, signer) - accountManager.addAccount(account) - accountManager.setActive(account) + // NOTE: We do NOT register the Amber account in accountManager here. + // That happens in Phase 3 after backend login succeeds, to avoid a + // split state where accountManager.active is set but authStore + // isn't authenticated (which confuses guards and the UI). // Build the unsigned NIP-98 event that the backend expects. // Store it so Phase 3 can reuse the exact same event data @@ -605,6 +600,19 @@ async function handleAmberSignComplete() { // Authenticate with the pre-signed NIP-98 header (bypasses signer.signEvent) await loginWithNostr(pubkey, 'amber-nip55', {}, authHeader) + // Backend login succeeded — NOW register the Amber account in + // accountManager so the rest of the UI reflects the logged-in state. + try { + const { AmberClipboardSigner, AmberClipboardAccount } = await import('../lib/accounts') + const signer = new AmberClipboardSigner() + signer.pubkey = pubkey + const account = new AmberClipboardAccount(pubkey, signer) + accountManager.addAccount(account) + accountManager.setActive(account) + } catch (accountErr) { + console.warn('[Amber] Account registration after login:', accountErr) + } + amberPhase.value = 'idle' amberPubkey.value = null amberUnsignedEvent.value = null