Multi-user servers: email and invite codes at sign-up and sign-in
Create account takes an email and an invite or setup code (none with open sign-up), joins servers that already have accounts, and Settings shows the account email (admins manage people from the web vault). Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
+12
-7
@@ -349,6 +349,7 @@ function finishSetup(body: HTMLElement, view: SetupView) {
|
||||
|
||||
function createPanel(body: HTMLElement, status: SyncStatus) {
|
||||
const url = serverInput(status);
|
||||
const email = input({ type: "email", autocomplete: "email", spellcheck: false });
|
||||
const code = input({ spellcheck: false });
|
||||
const pins = input({ placeholder: "base64, comma-separated", spellcheck: false }, true);
|
||||
const pw = input({ type: "password", autocomplete: "new-password" });
|
||||
@@ -366,7 +367,7 @@ function createPanel(body: HTMLElement, status: SyncStatus) {
|
||||
btn.disabled = true;
|
||||
btn.textContent = "Creating…";
|
||||
try {
|
||||
const secretKey = await invoke<string>("create_account", { serverUrl: url.value, pins: pins.value, setupCode: code.value, masterPassword: pw.value });
|
||||
const secretKey = await invoke<string>("create_account", { serverUrl: url.value, pins: pins.value, setupCode: code.value, email: email.value, masterPassword: pw.value });
|
||||
pw.value = pw2.value = "";
|
||||
await showSecretKey(secretKey);
|
||||
} catch (e) {
|
||||
@@ -380,9 +381,10 @@ function createPanel(body: HTMLElement, status: SyncStatus) {
|
||||
}
|
||||
};
|
||||
body.append(
|
||||
p("kv-muted", "For the first device on a new server. You'll get a Secret Key: keep it with your Emergency Kit."),
|
||||
p("kv-muted", "A new account on your Kestrove server. You'll get a Secret Key: keep it with your Emergency Kit."),
|
||||
field("Your Kestrove server", url),
|
||||
field("Setup code", code, "KV_SETUP_CODE in your server's .env."),
|
||||
field("Email", email, "You sign in with it on new devices."),
|
||||
field("Invite or setup code", code, "The invite from your server's admin, or KV_SETUP_CODE from its .env for the first account. Empty with open sign-up."),
|
||||
h("details", "", h("summary", "kv-small", "Certificate pins (advanced)"), field("SPKI pins", pins)),
|
||||
field("Master password", pw, "10 or more characters."),
|
||||
field("Repeat master password", pw2),
|
||||
@@ -737,6 +739,7 @@ function renderSyncSettings(box: HTMLElement, s: SyncStatus, reload: () => Promi
|
||||
// A vault from before sync (or whose registration failed): connect it.
|
||||
const url = input({ type: "url", placeholder: "https://kestrove.example.com", value: s.server_url ?? "" });
|
||||
const pins = input({ value: s.pins.join(", ") }, true);
|
||||
const email = input({ type: "email", autocomplete: "email", spellcheck: false });
|
||||
const code = input({});
|
||||
const err = errBox();
|
||||
const btn = button("Connect", "primary");
|
||||
@@ -745,9 +748,10 @@ function renderSyncSettings(box: HTMLElement, s: SyncStatus, reload: () => Promi
|
||||
err.replaceChildren();
|
||||
try {
|
||||
await invoke("configure_server", { serverUrl: url.value, pins: pins.value });
|
||||
if (await invoke<boolean>("server_setup_open")) {
|
||||
if (!code.value.trim()) throw new Error("This server has no account yet: enter its setup code to register this vault.");
|
||||
await invoke("register_server", { setupCode: code.value });
|
||||
const setupOpen = await invoke<boolean>("server_setup_open");
|
||||
if (setupOpen && !code.value.trim()) throw new Error("This server has no account yet: enter its setup code to register this vault.");
|
||||
if (setupOpen || email.value.trim()) {
|
||||
await invoke("register_server", { setupCode: code.value, email: email.value });
|
||||
} else {
|
||||
await invoke("sync_now");
|
||||
}
|
||||
@@ -758,7 +762,8 @@ function renderSyncSettings(box: HTMLElement, s: SyncStatus, reload: () => Promi
|
||||
}
|
||||
};
|
||||
box.append(h("div", "kv-card pad stack", field("Your Kestrove server", url), field("SPKI pins", pins, "Optional."),
|
||||
field("Setup code", code, "Only for a new server."), err, h("div", "actions", btn)));
|
||||
field("Email", email, "To register this vault as a new account."),
|
||||
field("Invite or setup code", code, "An admin's invite, or the setup code of a new server."), err, h("div", "actions", btn)));
|
||||
}
|
||||
|
||||
async function renderDevices(box: HTMLElement) {
|
||||
|
||||
Reference in New Issue
Block a user