// Account recovery describes only the selected role's live server-side seat. It never reads browser caches. import { randomUUID } from 'node:crypto'; export function createAccountRecovery({ registry, lobby }) { const roomIds = new WeakMap(); return { describe(playerId) { const session = playerId && registry.byId(playerId); if (!session || registry.isExpired(session, registry.now())) return null; const room = lobby.roomOf(session); if (!room || room.disposed) return null; if (!roomIds.has(room)) roomIds.set(room, randomUUID()); return { // A selector, not a credential: a replaced room or a later match must not satisfy a stale recovery request. id: roomIds.get(room) + ':' + room.matchCount, name: session.name, code: room.code, mode: room.mode, difficulty: room.difficulty, inMatch: !!room.match, round: room.match?.round ?? 0, connected: session.connected, spectating: !!room.spectatorOf(playerId), }; }, }; }