fix: abort dangling fetches and handle localStorage exceptions
- useNostr.ts: wrap auto-restore login fetch with AbortController, abort on logout to cancel in-flight request - useWallet.ts: wrap localStorage.setItem/removeItem calls in try/catch for Safari private browsing quota exceptions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
d98b264935
commit
edd08fde59
@@ -90,12 +90,14 @@ export function useNostr() {
|
|||||||
const hasExtension = computed(() => !!window.nostr)
|
const hasExtension = computed(() => !!window.nostr)
|
||||||
|
|
||||||
// Restore session on first load — re-verify with server (once only)
|
// Restore session on first load — re-verify with server (once only)
|
||||||
|
const autoRestoreController = new AbortController()
|
||||||
if (!autoRestoreRan && pubkey.value && !bot.value) {
|
if (!autoRestoreRan && pubkey.value && !bot.value) {
|
||||||
autoRestoreRan = true
|
autoRestoreRan = true
|
||||||
fetch('/api/auth/login', {
|
fetch('/api/auth/login', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ pubkey: pubkey.value }),
|
body: JSON.stringify({ pubkey: pubkey.value }),
|
||||||
|
signal: autoRestoreController.signal,
|
||||||
}).then(r => r.json()).then(data => {
|
}).then(r => r.json()).then(data => {
|
||||||
if (data.exists) {
|
if (data.exists) {
|
||||||
bot.value = normalizeBotData(data.bot)
|
bot.value = normalizeBotData(data.bot)
|
||||||
@@ -368,6 +370,7 @@ export function useNostr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function logout() {
|
function logout() {
|
||||||
|
autoRestoreController.abort()
|
||||||
clearAllState()
|
clearAllState()
|
||||||
// Don't clear bf_nsec on logout — user may want to log back in
|
// Don't clear bf_nsec on logout — user may want to log back in
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,10 @@ function loadStored<T>(key: string): T | null {
|
|||||||
} catch { return null }
|
} catch { return null }
|
||||||
}
|
}
|
||||||
function store(key: string, value: unknown) {
|
function store(key: string, value: unknown) {
|
||||||
if (value == null) localStorage.removeItem(key)
|
try {
|
||||||
else localStorage.setItem(key, JSON.stringify(value))
|
if (value == null) localStorage.removeItem(key)
|
||||||
|
else localStorage.setItem(key, JSON.stringify(value))
|
||||||
|
} catch { /* Safari private browsing quota exception */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
const isWalletConnected = ref(!!loadStored<string>('bf_wallet_method'))
|
const isWalletConnected = ref(!!loadStored<string>('bf_wallet_method'))
|
||||||
@@ -73,7 +75,7 @@ export function useWallet() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Store NWC string locally for client-side payment sending
|
// Store NWC string locally for client-side payment sending
|
||||||
localStorage.setItem('bf_nwc_url', connectionString)
|
try { localStorage.setItem('bf_nwc_url', connectionString) } catch { /* quota */ }
|
||||||
walletMethod.value = 'nwc'
|
walletMethod.value = 'nwc'
|
||||||
isWalletConnected.value = true
|
isWalletConnected.value = true
|
||||||
store('bf_wallet_method', 'nwc')
|
store('bf_wallet_method', 'nwc')
|
||||||
@@ -120,7 +122,7 @@ export function useWallet() {
|
|||||||
paymentStatus.value = 'idle'
|
paymentStatus.value = 'idle'
|
||||||
pendingPayment.value = null
|
pendingPayment.value = null
|
||||||
store('bf_wallet_method', null)
|
store('bf_wallet_method', null)
|
||||||
localStorage.removeItem('bf_nwc_url')
|
try { localStorage.removeItem('bf_nwc_url') } catch { /* quota */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkWalletStatus(): Promise<void> {
|
async function checkWalletStatus(): Promise<void> {
|
||||||
|
|||||||
Reference in New Issue
Block a user