eleven / messenger Public

home: restore page defines credId again — the app/CLI handoffs were throwing ReferenceError (#1147)

#1058's unlocked-session refactor rewrote restore()'s locals to
`let token, dek, got, opened` but left both handoff paths reading a bare
`credId` — so every app handoff (the Mac browser sign-in) and CLI
handoff died at "Can't find variable: credId" right after the ceremony.
Declare it, fill it from the ceremony result, and carry it through
unlockedHomeSession (sessionStorage home_cred) like the other session
fields.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell c52d6e3761ccefec6b054d6d21705002aae555ba parent 59f8b9e
1 file changed, +7 −3
  • home/web/static/restore.js +7 −3
diff --git a/home/web/static/restore.js b/home/web/static/restore.js
index 4dc2531..5d228a1 100644
--- a/home/web/static/restore.js
+++ b/home/web/static/restore.js
@@ -79,6 +79,9 @@ function prefetch() {
async function unlockedHomeSession() {
const token = sessionStorage.getItem("home_token") || "";
const rawDEK = sessionStorage.getItem("home_dek") || "";
+ // The credential id rides along for the handoff session (the app stores
+ // which passkey wraps its DEK); missing is fine — "" decodes downstream.
+ const credId = sessionStorage.getItem("home_cred") || "";
if (!token || !rawDEK) return null;
try {
const dek = await importDEK(rawDEK);
@@ -87,7 +90,7 @@ async function unlockedHomeSession() {
// Validate the saved DEK now and let the instance restore reuse the opened
// vault instead of decrypting it twice.
const opened = await openBlob(got.bytes, dek);
- return { token, dek, got, opened };
+ return { token, credId, dek, got, opened };
} catch {
return null;
}
@@ -96,18 +99,19 @@ async function unlockedHomeSession() {
async function restore() {
$("restore").disabled = true;
- let token, dek, got, opened;
+ let token, credId, dek, got, opened;
// Only an origin-bound instance restore may reuse the unlocked list. App and
// CLI payloads export the whole home session, so they always retain their
// explicit passkey ceremony and fixed-target security boundary.
const unlocked = payload && payload.ret ? await unlockedHomeSession() : null;
if (unlocked) {
- ({ token, dek, got, opened } = unlocked);
+ ({ token, credId, dek, got, opened } = unlocked);
setStatus("Unlocked. Opening your chat…", "busy");
} else {
setStatus("Confirming it’s you…", "busy");
const login = await runLogin(loginBegin);
token = login.token;
+ credId = login.credId;
if (!login.prf) {
setStatus("Signed in, but this browser can't unlock your spaces here. Try another browser.", "error");
$("restore").disabled = false;