carlos / contra Public

Clone
git clone https://amadan.net/carlos/contra

Plain git — no account needed to clone.

Download

Download this file

1// Sign in: one form, one ceremony.
2//
3// Signing in is not unlocking. This proves who you are to the server, which
4// then serves you ciphertext it cannot read; the vault asks for the
5// passphrase again to open it.
6
7import { signIn } from "../crypto/account.js";
8
9function say(form, text, kind = "working") {
10 const p = document.createElement("p");
11 p.setAttribute("data-kind", kind);
12 p.append(document.createTextNode(text));
13 form.querySelector("[data-status]").replaceChildren(p);
14}
15
16function busy(form, on) {
17 for (const c of form.querySelectorAll("input, button")) c.disabled = on;
18}
19
20const form = document.querySelector("[data-signin]");
21if (form) {
22 form.addEventListener("submit", async (e) => {
23 e.preventDefault();
24 busy(form, true);
25 let step = "start";
26 try {
27 await signIn(
28 form.querySelector("[name=email]").value,
29 form.querySelector("[name=passphrase]").value,
30 (m) => {
31 step = m;
32 say(form, m + "…");
33 });
34 window.location.assign("/vault");
35 } catch (err) {
36 // The full error goes to the console; the screen says one thing.
37 //
38 // An unknown address, a wrong passphrase and an expired challenge are
39 // three different facts, and telling them apart is the attacker's
40 // problem, not ours to solve for them. What the screen does say is
41 // which step it reached, because "it failed" with no location is what
42 // made the old signup impossible to report.
43 console.error("CONTRA sign-in failed while", step, err);
44 say(form, "Could not sign in. Check the address and passphrase. " +
45 `(Failed while: ${step}. The browser console has the detail.)`, "error");
46 busy(form, false);
47 }
48 });
49}
50