feat: first-time setup screen for creating a new passphrase

UX fix from user feedback: previously the app only showed an "Entsperren"
form, leaving first-time users without any passphrase confused. The page
now loads with two distinct pre-screens decided by an initial API call:

- empty DB -> "Willkommen" setup form: new passphrase, typed twice,
  minimum 8 characters, with no-reset warning
- existing ciphertext records -> unlock form as before

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
This commit is contained in:
2026-10-11 00:30:51 +02:00
parent 6bb6a38040
commit 863cd1fd3a
+39 -10
View File
@@ -12,18 +12,47 @@
<section id="flash" class="flash" aria-live="polite"></section>
<!-- unlock screen: passphrase stays in memory only -->
<!-- First visit: NO records exist yet → user chooses a new passphrase -->
<section id="setup" hidden>
<form id="setup-form" autocomplete="off">
<h2>Willkommen bei crushdb!</h2>
<p class="intro">
Du benutzt crushdb zum ersten Mal. Wähle jetzt eine Passphrase –
sie ist das Master-Passwort für alle deine Daten. Es gibt keine
Zurücksetzung, speichere sie sicher!
</p>
<label>Neue Passphrase
<input type="password" id="setup-pass1" autocomplete="new-password"
required minlength="8" placeholder="mindestens 8 Zeichen" />
</label>
<label>Passphrase wiederholen
<input type="password" id="setup-pass2" autocomplete="new-password"
required placeholder="gleiche Passphrase nochmal" />
</label>
<button type="submit" id="setup-btn">Konto einrichten →</button>
<p id="setup-progress" class="hint" hidden>Schlüssel wird abgeleitet …</p>
<p class="hint">
Wichtig: Die Passphrase wird <strong>nicht am Server gespeichert</strong>.
Sie bleibt nur in deinem Browser-Arbeitsspeicher. Wer sie vergisst,
verliert Zugriff auf alle Daten (absichtlich so).
</p>
</form>
</section>
<!-- Returning user: records exist but are undecryptable → enter passphrase -->
<section id="unlock">
<form id="unlock-form" autocomplete="off">
<label for="passphrase">Passphrase</label>
<input
type="password"
id="passphrase"
autocomplete="off"
required
placeholder="Passphrase eingeben …"
/>
<button type="submit">Entsperren</button>
<h2>Entsperren</h2>
<p class="intro">
Du hast bereits verschlüsselte Datensätze hinterlegt.
Gib deine Passphrase ein, um sie zu lesen.
</p>
<label>Passphrase
<input type="password" id="passphrase" autocomplete="current-password"
required placeholder="deine Passphrase …" />
</label>
<button type="submit" id="unlock-btn">Entsperren</button>
<p id="unlock-progress" class="hint" hidden>Schlüssel wird abgeleitet …</p>
<p class="hint">
Die Passphrase verlässt niemals deinen Browser. Sie wird per
Argon2id lokal abgeleitet und nur im Arbeitsspeicher gehalten.