mirror of
https://github.com/tompro/sattle.git
synced 2026-08-27 07:15:59 +00:00
feat: add persisted owner guards and events
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
// Mutators must not let a still-running old tab overwrite namespaces after a
|
||||
// successor has installed its saved-key owner marker. Ownerless data may only
|
||||
// move through explicit migration APIs after their own proof checks succeed.
|
||||
|
||||
import {savedKeyOwnerId} from '../keys'
|
||||
|
||||
export class WalletOwnerMismatchError extends Error {
|
||||
override readonly name = 'WalletOwnerMismatchError'
|
||||
constructor() {
|
||||
super('The active wallet owner no longer matches the saved wallet.')
|
||||
}
|
||||
}
|
||||
|
||||
export const savedKeyOwnerAllows = (ownerId: string): boolean => {
|
||||
return savedKeyOwnerId() === ownerId
|
||||
}
|
||||
|
||||
export const assertSavedKeyOwner = (ownerId: string): void => {
|
||||
if (!savedKeyOwnerAllows(ownerId)) throw new WalletOwnerMismatchError()
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Storage events only wake an owning store to reread its saved-key marker.
|
||||
// Their payload may be stale when writes arrive faster than delivery.
|
||||
|
||||
export const LINKING_KEY_STORAGE_KEY = 'sattle_linking_key'
|
||||
|
||||
// Each subscription binds its own storage listener and removes exactly it on
|
||||
// unsubscribe: no shared reference counting, so an abandoned subscriber can
|
||||
// never keep another subscriber's window listener (or runtime) alive.
|
||||
export const onSavedKeyStorageChange = (listener: () => void): (() => void) => {
|
||||
const target = typeof window === 'undefined' ? null : window
|
||||
const onStorage = (event: StorageEvent): void => {
|
||||
if (event.key !== LINKING_KEY_STORAGE_KEY && event.key !== null) return
|
||||
listener()
|
||||
}
|
||||
target?.addEventListener('storage', onStorage)
|
||||
return () => target?.removeEventListener('storage', onStorage)
|
||||
}
|
||||
Reference in New Issue
Block a user