fix: Leere Schluesselvariable legte die Verschluesselung lahm
docker-compose.yml reicht ENC_KEY_V2 immer an den Behaelter durch - mit leerem Wert, wenn in der .env keiner steht. src/lib/env.ts erkannte Schluessel aber am Variablennamen statt am Inhalt, fand also ein leeres ENC_KEY_V2 und brach ab mit "Umgebungsvariable ENC_KEY_V2 fehlt". Die Meldung war doppelt irrefuehrend: Sie nannte einen Schluessel, den niemand wollte, und sie erschien an einer Stelle, die damit nichts zu tun hat - beim Einrichten des zweiten Faktors, als Serverfehler ohne Text. Betroffen war jede Stelle, die verschluesselte Felder schreibt oder liest, also praktisch alles ausser der Anmeldung selbst. Die kam durch, weil sie ohne Verschluesselung auskommt - der Fehler trat deshalb erst auf der naechsten Seite auf, und der Zusammenhang war nicht zu sehen. Leere Schluesselvariablen werden jetzt uebersprungen. Sieben Tests decken die Auswertung ab, darunter genau diese Konstellation. Die Meldung beim Schluesselwechsel nennt jetzt ausserdem, welche Versionen vorhanden sind, und die richtige Reihenfolge: erst den neuen Schluessel eintragen, dann ENC_KEY_AKTIV umstellen. Dazu scripts/anmeldung-pruefen.mjs. Das Anmeldeformular sagt bewusst nicht, woran eine Anmeldung scheiterte - sonst liesse sich daran ablesen, welche Adressen es gibt. Auf dem Server darf man es wissen: Jeder Versuch wird mit Grund protokolliert, und das Skript liest ihn vor, zusammen mit dem Zustand des Zugangs, dem Stand der Sperre und der AUTH_URL. Etappe: 8 Phase: Haertung
This commit is contained in:
+19
-5
@@ -58,14 +58,25 @@ function einmal<T>(fn: () => T): () => T {
|
||||
|
||||
const holeVerschluesselungsschluessel = einmal((): Map<number, Buffer> => {
|
||||
const schluessel = new Map<number, Buffer>()
|
||||
|
||||
// ENC_KEY_V1, ENC_KEY_V2, ... - alte Versionen bleiben zum Entschluesseln
|
||||
// stehen, verschluesselt wird immer mit der aktiven Version.
|
||||
for (const [name] of Object.entries(process.env)) {
|
||||
for (const [name, wert] of Object.entries(process.env)) {
|
||||
const treffer = name.match(/^ENC_KEY_V(\d+)$/)
|
||||
if (treffer) {
|
||||
schluessel.set(Number.parseInt(treffer[1]!, 10), schluessel32(name))
|
||||
}
|
||||
if (!treffer) continue
|
||||
|
||||
// Eine LEERE Variable ist kein Schluessel.
|
||||
//
|
||||
// docker compose reicht ENC_KEY_V2 immer durch - mit leerem Wert, wenn
|
||||
// in der .env keiner steht. Wuerde hier allein der Name zaehlen, waere
|
||||
// jede Installation ohne zweiten Schluessel kaputt, und zwar mit der
|
||||
// irrefuehrenden Meldung "ENC_KEY_V2 fehlt" - obwohl niemand einen
|
||||
// zweiten Schluessel wollte.
|
||||
if (!wert || wert.trim() === '') continue
|
||||
|
||||
schluessel.set(Number.parseInt(treffer[1]!, 10), schluessel32(name))
|
||||
}
|
||||
|
||||
if (schluessel.size === 0) {
|
||||
throw new Error(
|
||||
'Kein Verschluesselungsschluessel gefunden. Es muss mindestens ENC_KEY_V1 ' +
|
||||
@@ -78,8 +89,11 @@ const holeVerschluesselungsschluessel = einmal((): Map<number, Buffer> => {
|
||||
const holeAktiveVersion = einmal((): number => {
|
||||
const version = zahl('ENC_KEY_AKTIV', 1)
|
||||
if (!holeVerschluesselungsschluessel().has(version)) {
|
||||
const vorhanden = [...holeVerschluesselungsschluessel().keys()].sort().join(', ')
|
||||
throw new Error(
|
||||
`ENC_KEY_AKTIV=${version}, aber ENC_KEY_V${version} ist nicht gesetzt.`,
|
||||
`ENC_KEY_AKTIV=${version}, aber ENC_KEY_V${version} ist nicht gesetzt oder leer. ` +
|
||||
`Vorhanden sind die Versionen: ${vorhanden}. Beim Rotieren zuerst den ` +
|
||||
`neuen Schluessel eintragen, danach ENC_KEY_AKTIV umstellen.`,
|
||||
)
|
||||
}
|
||||
return version
|
||||
|
||||
Reference in New Issue
Block a user