@echomem/mcp 1.4.21 → 1.4.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/assets/hud/echo-pricing-free-sticker.png +0 -0
- package/assets/hud/echo-pricing-power-sticker.png +0 -0
- package/assets/hud/echo-pricing-pro-sticker.png +0 -0
- package/assets/hud/scan-loop/frame-01-ready.png +0 -0
- package/assets/hud/scan-loop/frame-02-open.png +0 -0
- package/assets/hud/scan-loop/frame-03-pull.png +0 -0
- package/assets/hud/scan-loop/frame-04-read.png +0 -0
- package/assets/hud/scan-loop/frame-05-file.png +0 -0
- package/assets/hud/scan-loop/frame-06-close.png +0 -0
- package/dist/hud/web.js +3 -3
- package/dist/index.js +264 -7
- package/dist/migrate.js +6 -5
- package/dist/package-metadata.js +2 -0
- package/dist/setup-page/client-core.js +144 -48
- package/dist/setup-page/client-extraction.js +260 -70
- package/dist/setup-page/client-lifecycle.js +45 -39
- package/dist/setup-page/client-report-audit.js +1 -1
- package/dist/setup-page/client-report-city.js +35 -22
- package/dist/setup-page/document.js +1 -1
- package/dist/setup-page/styles-extraction.js +330 -0
- package/dist/setup-page/styles-mvp.js +1079 -0
- package/dist/setup-page/styles-website-alignment.js +237 -5
- package/dist/setup-page/styles.js +2 -0
- package/dist/setup-preview.js +22 -6
- package/dist/setup.js +272 -40
- package/dist/v1-contract.js +226 -11
- package/package.json +1 -1
|
@@ -8,6 +8,9 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
8
8
|
var status = document.getElementById("status");
|
|
9
9
|
var report = null;
|
|
10
10
|
var reportEnvelope = null;
|
|
11
|
+
// The local bridge is authoritative. Login never gets access to scan/import routes;
|
|
12
|
+
// onboarding may request the separate local-history permission.
|
|
13
|
+
var setupFlow = "onboarding";
|
|
11
14
|
var activeScanId = "";
|
|
12
15
|
var stats = null;
|
|
13
16
|
var statsSlow = false;
|
|
@@ -27,6 +30,8 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
27
30
|
var billingStatus = null;
|
|
28
31
|
var billingStatusLoading = false;
|
|
29
32
|
var setupPlanChoice = "";
|
|
33
|
+
var setupPlanPreview = "free";
|
|
34
|
+
var billingActivationPendingPlan = "";
|
|
30
35
|
var selectedSessionKeys = Object.create(null);
|
|
31
36
|
var sessionSelectionTouched = false;
|
|
32
37
|
var sessionPickerQuery = "";
|
|
@@ -37,13 +42,30 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
37
42
|
var localAuthAgeConfirmed = false;
|
|
38
43
|
var statsPollStarted = false;
|
|
39
44
|
var reportPollStarted = false;
|
|
45
|
+
var reportEstimateDeadline = 0;
|
|
46
|
+
var reportEstimateTimer = null;
|
|
47
|
+
var readyStage = "";
|
|
40
48
|
var NIGHT_HOURS = { 22: 1, 23: 1, 0: 1, 1: 1, 2: 1, 3: 1 };
|
|
41
49
|
|
|
50
|
+
try {
|
|
51
|
+
var storedSetupPlanChoice = sessionStorage.getItem("echomem:setup-plan:" + nonce) || "";
|
|
52
|
+
if (storedSetupPlanChoice === "free" || storedSetupPlanChoice === "pro" || storedSetupPlanChoice === "power") {
|
|
53
|
+
setupPlanChoice = storedSetupPlanChoice;
|
|
54
|
+
}
|
|
55
|
+
} catch (_) {}
|
|
56
|
+
|
|
42
57
|
function esc(value) {
|
|
43
58
|
return String(value == null ? "" : value).replace(/[&<>"']/g, function (ch) {
|
|
44
59
|
return { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[ch];
|
|
45
60
|
});
|
|
46
61
|
}
|
|
62
|
+
function rememberSetupPlanChoice(choice) {
|
|
63
|
+
setupPlanChoice = choice === "free" || choice === "pro" || choice === "power" ? choice : "";
|
|
64
|
+
try {
|
|
65
|
+
if (setupPlanChoice) sessionStorage.setItem("echomem:setup-plan:" + nonce, setupPlanChoice);
|
|
66
|
+
else sessionStorage.removeItem("echomem:setup-plan:" + nonce);
|
|
67
|
+
} catch (_) {}
|
|
68
|
+
}
|
|
47
69
|
function setupIcon(name) {
|
|
48
70
|
var paths = {
|
|
49
71
|
"shield-check": '<path d="M12 3 5 6v5c0 4.6 2.9 8.1 7 10 4.1-1.9 7-5.4 7-10V6l-7-3Z"/><path d="m8.8 12.1 2 2 4.4-4.5"/>',
|
|
@@ -109,7 +131,10 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
109
131
|
}
|
|
110
132
|
async function getJson(path) {
|
|
111
133
|
var sep = path.indexOf("?") >= 0 ? "&" : "?";
|
|
112
|
-
var res = await fetch(path + sep + "nonce=" + encodeURIComponent(nonce), {
|
|
134
|
+
var res = await fetch(path + sep + "nonce=" + encodeURIComponent(nonce), {
|
|
135
|
+
credentials: "omit",
|
|
136
|
+
cache: "no-store"
|
|
137
|
+
});
|
|
113
138
|
if (!res.ok) throw new Error(await res.text() || ("HTTP " + res.status));
|
|
114
139
|
return await res.json();
|
|
115
140
|
}
|
|
@@ -152,14 +177,18 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
152
177
|
return false;
|
|
153
178
|
}
|
|
154
179
|
function localAuthLegalHtml() {
|
|
155
|
-
return '<
|
|
156
|
-
'<
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
'<span>I have read and agree to the Echo <a href="https://echoknows.com/terms-of-use" target="_blank" rel="noopener noreferrer">Terms of Use</a>, <a href="https://echoknows.com/memory-terms" target="_blank" rel="noopener noreferrer">Memory Usage Terms</a>, and <a href="https://echoknows.com/privacy-policy" target="_blank" rel="noopener noreferrer">Privacy Policy</a>. I understand Echo uses subprocessors listed <a href="https://echoknows.com/subprocessor-list" target="_blank" rel="noopener noreferrer">here</a>.</span></label>' +
|
|
160
|
-
'</div>';
|
|
180
|
+
return '<label class="localAuthConsent">' +
|
|
181
|
+
'<input type="checkbox" id="localAuthConsent" ' + (localAuthAgeConfirmed && localAuthTermsAccepted ? "checked" : "") + ' />' +
|
|
182
|
+
'<span>I confirm that I am at least 18 years old and that I have read and agree to Echo\'s <a href="https://echoknows.com/terms-of-use" target="_blank" rel="noopener noreferrer">Terms of Use</a>, <a href="https://echoknows.com/memory-terms" target="_blank" rel="noopener noreferrer">Memory Usage Terms</a>, and <a href="https://echoknows.com/privacy-policy" target="_blank" rel="noopener noreferrer">Privacy Policy</a>. See our <a href="https://echoknows.com/subprocessor-list" target="_blank" rel="noopener noreferrer">Subprocessor List</a>.</span>' +
|
|
183
|
+
'</label>';
|
|
161
184
|
}
|
|
162
185
|
function captureLocalAuthConsents() {
|
|
186
|
+
var consent = document.getElementById("localAuthConsent");
|
|
187
|
+
if (consent) {
|
|
188
|
+
localAuthTermsAccepted = !!consent.checked;
|
|
189
|
+
localAuthAgeConfirmed = !!consent.checked;
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
163
192
|
var terms = document.getElementById("localAuthTerms");
|
|
164
193
|
var age = document.getElementById("localAuthAge");
|
|
165
194
|
localAuthTermsAccepted = !!(terms && terms.checked);
|
|
@@ -185,19 +214,21 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
185
214
|
setExtractMode(false);
|
|
186
215
|
setReadyMode(true);
|
|
187
216
|
setHead("Connect EchoMem", "Local login");
|
|
188
|
-
app.className = "localAuthStage";
|
|
217
|
+
app.className = "localAuthStage localAuthWelcomeStage";
|
|
189
218
|
app.innerHTML =
|
|
190
|
-
'<section class="
|
|
191
|
-
'<div class="
|
|
192
|
-
|
|
193
|
-
'<
|
|
194
|
-
'<
|
|
195
|
-
'<p>Echo sends a one-time code to your email. The browser stays on localhost; your device token and encryption key are stored only in the local EchoMem keystore.</p>' +
|
|
219
|
+
'<section class="localAuthWelcome" aria-labelledby="localAuthWelcomeTitle">' +
|
|
220
|
+
'<div class="localAuthOrbScene" aria-hidden="true"><span class="localAuthOrb"></span><span class="localAuthOrbShadow"></span></div>' +
|
|
221
|
+
'<div class="localAuthWelcomeCopy">' +
|
|
222
|
+
'<h2 id="localAuthWelcomeTitle">Welcome to Echo</h2>' +
|
|
223
|
+
'<p>Your memories, sovereign and shared.</p>' +
|
|
196
224
|
'</div>' +
|
|
197
|
-
'<form class="
|
|
198
|
-
'<
|
|
225
|
+
'<form class="localAuthWelcomeForm" id="localAuthEmailForm">' +
|
|
226
|
+
'<div class="localAuthEmailCapsule">' +
|
|
227
|
+
'<label class="srOnly" for="localAuthEmail">Email</label>' +
|
|
228
|
+
'<input id="localAuthEmail" type="email" autocomplete="email" placeholder="Enter your email" value="' + esc(localAuthEmail) + '" />' +
|
|
229
|
+
'<button id="localAuthSend" type="submit" aria-label="Send one-time code"><span aria-hidden="true">→</span></button>' +
|
|
230
|
+
'</div>' +
|
|
199
231
|
localAuthLegalHtml() +
|
|
200
|
-
'<button class="primary" id="localAuthSend" type="submit">Send code</button>' +
|
|
201
232
|
'<p class="localAuthStatus' + (message ? " is-error" : "") + '" id="localAuthStatus" role="status" aria-live="polite">' + esc(message || "") + '</p>' +
|
|
202
233
|
'</form>' +
|
|
203
234
|
'</section>';
|
|
@@ -208,12 +239,37 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
208
239
|
email.oninput = function () { localAuthEmail = String(email.value || ""); updateLocalAuthSendButton(); };
|
|
209
240
|
email.focus();
|
|
210
241
|
}
|
|
211
|
-
var
|
|
212
|
-
|
|
213
|
-
if (terms) terms.onchange = updateLocalAuthSendButton;
|
|
214
|
-
if (age) age.onchange = updateLocalAuthSendButton;
|
|
242
|
+
var consent = document.getElementById("localAuthConsent");
|
|
243
|
+
if (consent) consent.onchange = updateLocalAuthSendButton;
|
|
215
244
|
updateLocalAuthSendButton();
|
|
216
245
|
}
|
|
246
|
+
function renderLocalLoginComplete() {
|
|
247
|
+
setCityMode(false);
|
|
248
|
+
setScanMode(false);
|
|
249
|
+
setExtractMode(false);
|
|
250
|
+
setReadyMode(true);
|
|
251
|
+
setHead("EchoMem connected", "Done");
|
|
252
|
+
app.className = "notice";
|
|
253
|
+
app.innerHTML =
|
|
254
|
+
'<section class="localAuthCard localAuthComplete">' +
|
|
255
|
+
'<div class="localAuthLead">' +
|
|
256
|
+
'<img src="/hud-assets/echo-face-cutout.png" alt="" />' +
|
|
257
|
+
'<p class="consentEyebrow">This device is connected</p>' +
|
|
258
|
+
'<h2 class="siteHeadline">You\'re signed in.</h2>' +
|
|
259
|
+
'<p>Your local device token and encryption key are ready. Return to Terminal, or run <code>echomem-mcp init</code> when you want to start local-history onboarding.</p>' +
|
|
260
|
+
'</div>' +
|
|
261
|
+
'</section>';
|
|
262
|
+
}
|
|
263
|
+
async function finishLocalLogin() {
|
|
264
|
+
connected = true;
|
|
265
|
+
if (setupFlow === "login") {
|
|
266
|
+
renderLocalLoginComplete();
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
rememberSetupPlanChoice("");
|
|
270
|
+
try { await refreshBillingStatus(); } catch (_) {}
|
|
271
|
+
await waitForStats();
|
|
272
|
+
}
|
|
217
273
|
async function sendLocalOtp() {
|
|
218
274
|
var email = document.getElementById("localAuthEmail");
|
|
219
275
|
localAuthEmail = email && email.value ? String(email.value).trim().toLowerCase() : "";
|
|
@@ -224,7 +280,7 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
224
280
|
return;
|
|
225
281
|
}
|
|
226
282
|
var button = document.getElementById("localAuthSend");
|
|
227
|
-
if (button) { button.disabled = true; button.
|
|
283
|
+
if (button) { button.disabled = true; button.innerHTML = '<span class="localAuthSpinner" aria-hidden="true"></span>'; }
|
|
228
284
|
setLocalAuthStatus("Sending verification code...");
|
|
229
285
|
try {
|
|
230
286
|
var data = await postJson("/local-auth/send-otp", {
|
|
@@ -235,7 +291,7 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
235
291
|
localAuthEmail = data.email || localAuthEmail;
|
|
236
292
|
renderLocalOtp("Code sent. Check your inbox.");
|
|
237
293
|
} catch (error) {
|
|
238
|
-
if (button) { button.disabled = false; button.
|
|
294
|
+
if (button) { button.disabled = false; button.innerHTML = '<span aria-hidden="true">→</span>'; }
|
|
239
295
|
setLocalAuthStatus(error && error.message ? error.message : "Could not send the code.", "error");
|
|
240
296
|
}
|
|
241
297
|
}
|
|
@@ -245,18 +301,26 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
245
301
|
setExtractMode(false);
|
|
246
302
|
setReadyMode(true);
|
|
247
303
|
setHead("Check your email", "Local login");
|
|
248
|
-
app.className = "localAuthStage";
|
|
304
|
+
app.className = "localAuthStage localAuthWelcomeStage localAuthOtpStage";
|
|
249
305
|
app.innerHTML =
|
|
250
|
-
'<section class="
|
|
251
|
-
'<div class="
|
|
252
|
-
|
|
253
|
-
'<
|
|
254
|
-
'<
|
|
255
|
-
'<p>This code signs in this local EchoMem bridge only. The next step asks for your encryption passphrase.</p>' +
|
|
306
|
+
'<section class="localAuthWelcome localAuthOtpWelcome" aria-labelledby="localAuthOtpTitle">' +
|
|
307
|
+
'<div class="localAuthOrbScene" aria-hidden="true"><span class="localAuthOrb"></span><span class="localAuthOrbShadow"></span></div>' +
|
|
308
|
+
'<div class="localAuthWelcomeCopy">' +
|
|
309
|
+
'<h2 id="localAuthOtpTitle">Check your inbox</h2>' +
|
|
310
|
+
'<p>We sent a 6-digit code to <strong>' + esc(localAuthEmail) + '</strong></p>' +
|
|
256
311
|
'</div>' +
|
|
257
|
-
'<form class="
|
|
258
|
-
'<label class="
|
|
259
|
-
'<div class="
|
|
312
|
+
'<form class="localAuthWelcomeForm localAuthOtpForm" id="localAuthOtpForm">' +
|
|
313
|
+
'<label class="srOnly" for="localAuthOtp0">6-digit code</label>' +
|
|
314
|
+
'<div class="localAuthOtpCells" aria-label="6-digit verification code">' +
|
|
315
|
+
'<input id="localAuthOtp0" data-otp-cell type="text" inputmode="numeric" autocomplete="one-time-code" maxlength="1" />' +
|
|
316
|
+
'<input data-otp-cell type="text" inputmode="numeric" maxlength="1" />' +
|
|
317
|
+
'<input data-otp-cell type="text" inputmode="numeric" maxlength="1" />' +
|
|
318
|
+
'<input data-otp-cell type="text" inputmode="numeric" maxlength="1" />' +
|
|
319
|
+
'<input data-otp-cell type="text" inputmode="numeric" maxlength="1" />' +
|
|
320
|
+
'<input data-otp-cell type="text" inputmode="numeric" maxlength="1" />' +
|
|
321
|
+
'</div>' +
|
|
322
|
+
'<button class="primary localAuthVerifyWide" id="localAuthVerify" type="submit">Verify</button>' +
|
|
323
|
+
'<button class="secondary localAuthBackWide" id="localAuthBack" type="button">Use another email</button>' +
|
|
260
324
|
'<p class="localAuthStatus" id="localAuthStatus" role="status" aria-live="polite">' + esc(message || "") + '</p>' +
|
|
261
325
|
'</form>' +
|
|
262
326
|
'</section>';
|
|
@@ -264,12 +328,45 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
264
328
|
if (form) form.onsubmit = function (event) { event.preventDefault(); void verifyLocalOtp(); };
|
|
265
329
|
var back = document.getElementById("localAuthBack");
|
|
266
330
|
if (back) back.onclick = function () { renderLocalLogin(""); };
|
|
267
|
-
|
|
331
|
+
bindLocalOtpCells();
|
|
332
|
+
var otp = document.querySelector("[data-otp-cell]");
|
|
268
333
|
if (otp) otp.focus();
|
|
269
334
|
}
|
|
335
|
+
function localOtpCellValues() {
|
|
336
|
+
return Array.prototype.map.call(document.querySelectorAll("[data-otp-cell]"), function (node) {
|
|
337
|
+
return String(node.value || "").replace(/\\D/g, "").slice(0, 1);
|
|
338
|
+
}).join("");
|
|
339
|
+
}
|
|
340
|
+
function fillLocalOtpCells(value) {
|
|
341
|
+
var digits = String(value || "").replace(/\\D/g, "").slice(0, 6);
|
|
342
|
+
var cells = Array.prototype.slice.call(document.querySelectorAll("[data-otp-cell]"));
|
|
343
|
+
cells.forEach(function (cell, index) { cell.value = digits.charAt(index) || ""; });
|
|
344
|
+
var focusIndex = Math.min(digits.length, cells.length - 1);
|
|
345
|
+
if (cells[focusIndex]) cells[focusIndex].focus();
|
|
346
|
+
}
|
|
347
|
+
function bindLocalOtpCells() {
|
|
348
|
+
var cells = Array.prototype.slice.call(document.querySelectorAll("[data-otp-cell]"));
|
|
349
|
+
cells.forEach(function (cell, index) {
|
|
350
|
+
cell.oninput = function () {
|
|
351
|
+
var value = String(cell.value || "").replace(/\\D/g, "");
|
|
352
|
+
if (value.length > 1) { fillLocalOtpCells(value); return; }
|
|
353
|
+
cell.value = value;
|
|
354
|
+
if (value && cells[index + 1]) cells[index + 1].focus();
|
|
355
|
+
};
|
|
356
|
+
cell.onkeydown = function (event) {
|
|
357
|
+
if (event.key === "Backspace" && !cell.value && cells[index - 1]) cells[index - 1].focus();
|
|
358
|
+
};
|
|
359
|
+
cell.onpaste = function (event) {
|
|
360
|
+
var text = event.clipboardData && event.clipboardData.getData ? event.clipboardData.getData("text") : "";
|
|
361
|
+
if (text) {
|
|
362
|
+
event.preventDefault();
|
|
363
|
+
fillLocalOtpCells(text);
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
});
|
|
367
|
+
}
|
|
270
368
|
async function verifyLocalOtp() {
|
|
271
|
-
var
|
|
272
|
-
var otp = otpInput && otpInput.value ? String(otpInput.value).replace(/\\D/g, "") : "";
|
|
369
|
+
var otp = localOtpCellValues();
|
|
273
370
|
if (otp.length !== 6) { setLocalAuthStatus("Enter the 6-digit code.", "error"); return; }
|
|
274
371
|
var button = document.getElementById("localAuthVerify");
|
|
275
372
|
if (button) { button.disabled = true; button.textContent = "Verifying..."; }
|
|
@@ -285,8 +382,7 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
285
382
|
renderLocalPassphrase(data.mode || "unlock", data.email || localAuthEmail);
|
|
286
383
|
return;
|
|
287
384
|
}
|
|
288
|
-
|
|
289
|
-
await waitForStats();
|
|
385
|
+
await finishLocalLogin();
|
|
290
386
|
} catch (error) {
|
|
291
387
|
if (button) { button.disabled = false; button.textContent = "Verify code"; }
|
|
292
388
|
setLocalAuthStatus(error && error.message ? error.message : "Could not verify the code.", "error");
|
|
@@ -300,19 +396,19 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
300
396
|
setExtractMode(false);
|
|
301
397
|
setReadyMode(true);
|
|
302
398
|
setHead(setupMode ? "Create encrypted vault" : "Unlock encrypted vault", "Local passphrase");
|
|
303
|
-
app.className = "localAuthStage";
|
|
399
|
+
app.className = "localAuthStage localAuthWelcomeStage localAuthPassphraseStage";
|
|
304
400
|
app.innerHTML =
|
|
305
|
-
'<section class="
|
|
306
|
-
'<div class="
|
|
307
|
-
|
|
308
|
-
'<
|
|
309
|
-
'<h2 class="siteHeadline">' + (setupMode ? 'Create your local vault passphrase.' : 'Enter your vault passphrase.') + '</h2>' +
|
|
401
|
+
'<section class="localAuthWelcome localAuthPassphraseWelcome">' +
|
|
402
|
+
'<div class="localAuthOrbScene" aria-hidden="true"><span class="localAuthOrb"></span><span class="localAuthOrbShadow"></span></div>' +
|
|
403
|
+
'<div class="localAuthWelcomeCopy">' +
|
|
404
|
+
'<h2>' + (setupMode ? 'Create your local vault passphrase.' : 'Enter your vault passphrase.') + '</h2>' +
|
|
310
405
|
'<p>' + (setupMode ? 'Echo derives your encryption key on this device. The passphrase and key are never sent to EchoMem. If you forget it, encrypted memories cannot be recovered.' : 'Echo verifies this passphrase locally against your account encryption token. The passphrase is never sent to EchoMem.') + '</p>' +
|
|
311
406
|
'</div>' +
|
|
312
|
-
'<form class="
|
|
407
|
+
'<form class="localAuthWelcomeForm localAuthPassphraseForm" id="localAuthPassphraseForm">' +
|
|
313
408
|
'<label class="localAuthField"><span>Passphrase</span><input id="localAuthPassphrase" type="password" autocomplete="' + (setupMode ? "new-password" : "current-password") + '" placeholder="Encryption passphrase" /></label>' +
|
|
314
409
|
(setupMode ? '<label class="localAuthField"><span>Confirm passphrase</span><input id="localAuthPassphraseConfirm" type="password" autocomplete="new-password" placeholder="Confirm passphrase" /></label>' : '') +
|
|
315
|
-
'<
|
|
410
|
+
'<button class="primary localAuthPassphraseSubmit" id="localAuthUnlock" type="submit">' + (setupMode ? "Create vault" : "Unlock") + '</button>' +
|
|
411
|
+
'<button class="secondary localAuthBackWide" id="localAuthRestart" type="button">Use a different email</button>' +
|
|
316
412
|
'<p class="localAuthStatus' + (message ? " is-error" : "") + '" id="localAuthStatus" role="status" aria-live="polite">' + esc(message || "") + '</p>' +
|
|
317
413
|
'</form>' +
|
|
318
414
|
'</section>';
|
|
@@ -335,8 +431,7 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
335
431
|
setLocalAuthStatus(setupMode ? "Creating encrypted vault..." : "Unlocking vault...");
|
|
336
432
|
try {
|
|
337
433
|
await postJson("/local-auth/passphrase", { passphrase: passphrase }, 30000);
|
|
338
|
-
|
|
339
|
-
await waitForStats();
|
|
434
|
+
await finishLocalLogin();
|
|
340
435
|
} catch (error) {
|
|
341
436
|
if (button) { button.disabled = false; button.textContent = setupMode ? "Create vault" : "Unlock"; }
|
|
342
437
|
var msg = error && error.message ? error.message : "Could not unlock encrypted memory.";
|
|
@@ -350,6 +445,7 @@ export const SETUP_PAGE_CLIENT_CORE = String.raw ` var params = new URLSear
|
|
|
350
445
|
return;
|
|
351
446
|
}
|
|
352
447
|
if (connected) { void waitForStats(); return; }
|
|
448
|
+
rememberSetupPlanChoice("");
|
|
353
449
|
renderLocalLogin("");
|
|
354
450
|
}
|
|
355
451
|
function bindConnect() {
|