Phase 1 added impl Drop for SessionHandle on the Rust side so .free()
now actually removes the SESSIONS registry entry. The JS-side
try { current.free() } catch { /* already freed */ } swallow was
hiding the fact that .free() wasn't doing the cleanup at all;
post-Phase-1 it has to go so failures surface instead of being lost.
.free() callsite audit: exactly one match under extension/src/ — the
SW session.ts line this commit edits. Lifecycle audit: clearCurrent()
is reached via (a) popup lock → router popup-only.ts and (b)
session-timer expiry → service-worker/index.ts.
Refs: docs/superpowers/specs/2026-05-04-security-polish-design.md (Phase 2)
Refs: docs/superpowers/reviews/2026-05-04-architecture-review.md (P1.1, DEV-C P2 service-worker)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
35 lines
1.3 KiB
TypeScript
35 lines
1.3 KiB
TypeScript
/// Single module-scope "current" SessionHandle.
|
||
///
|
||
/// α assumes one vault per extension install. The master key lives only
|
||
/// inside WASM linear memory (wrapped in Zeroizing<[u8;32]>); this module
|
||
/// just holds the opaque handle that names it.
|
||
///
|
||
/// Future multi-vault (β+) would replace `current` with
|
||
/// `Map<vaultId, SessionHandle>` and thread `vaultId` through every
|
||
/// handler. Deliberate α simplicity — not an oversight.
|
||
///
|
||
/// As of Phase 1 of the security-polish series, `impl Drop for SessionHandle`
|
||
/// on the Rust side makes `.free()` the meaningful cleanup call: it removes
|
||
/// the entry from the SESSIONS registry and zeroizes `master_key` and
|
||
/// `image_secret`. Calling `wasm.lock(handle.value)` before `.free()` would
|
||
/// be redundant belt-and-suspenders; this module intentionally does not.
|
||
|
||
import type { SessionHandle } from '../../wasm/relicario_wasm';
|
||
|
||
let current: SessionHandle | null = null;
|
||
|
||
export function setCurrent(h: SessionHandle): void { current = h; }
|
||
|
||
export function getCurrent(): SessionHandle | null { return current; }
|
||
|
||
export function requireCurrent(): SessionHandle {
|
||
if (!current) throw new Error('vault_locked');
|
||
return current;
|
||
}
|
||
|
||
export function clearCurrent(): void {
|
||
if (!current) return;
|
||
current.free();
|
||
current = null;
|
||
}
|