Interner Zugang auffindbar + Owner kann eigenen Code selbst aendern

- Footer hat jetzt einen eigenen Block "Intern" mit Links zum
  Bewerbungs-Postfach und zu Zugaenge & Rollen (vorher nur ein
  winziger Link ganz unten)
- Postfach-Login verlinkt auf die Zugaenge-Seite
- Neue Tabelle app_settings + Endpunkt /admin/owner/set-code:
  der Hauptadministrator kann seinen Code selbst aendern, mit
  Bestaetigung des aktuellen Codes; gespeichert wird nur der Hash
- Neuer Tab "Mein Zugang" in zugaenge.html (nur fuer den Owner)

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-07-31 02:19:36 +02:00
co-authored by Claude Opus 5
parent 0e1f2fbdc4
commit 597988a9a2
8 changed files with 140 additions and 5 deletions
+16 -2
View File
@@ -59,10 +59,24 @@ export async function clearAttempts(env, key) {
/** Prüft einen eingegebenen Code gegen Owner-Secret und Team-Datenbank. */
export async function verifyCode(env, code) {
if (env.POSTFACH_CODE && timingSafeEqual(code, env.POSTFACH_CODE)) {
const hash = await sha256Hex(code);
// 1) Owner-Code aus der Datenbank — den kann Dogi selbst ändern.
// Sobald hier einer hinterlegt ist, gilt NUR noch dieser (kein Zweitschlüssel).
const ownerRow = await env.DB.prepare(
`SELECT value FROM app_settings WHERE key = 'owner_code_hash'`
)
.first()
.catch(() => null);
if (ownerRow && ownerRow.value) {
if (timingSafeEqual(hash, ownerRow.value)) return { ok: true, isOwner: true };
} else if (env.POSTFACH_CODE && timingSafeEqual(code, env.POSTFACH_CODE)) {
// 2) Erstzugang: solange noch kein eigener Code gesetzt wurde, gilt das Worker-Secret.
return { ok: true, isOwner: true };
}
const hash = await sha256Hex(code);
// 3) Normale Teammitglieder
const user = await env.DB.prepare(
`SELECT id, name, username, role_id, status, expires_at FROM users WHERE code_hash = ?`
)