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