Die Sicherheitsschicht, auf der alles Weitere aufsetzt. Feldverschluesselung (AES-256-GCM): - Umschlagformat bc1.<version>.<iv>.<tag>.<ct>. Die Schluesselversion erlaubt Rotation, ohne alte Daten unlesbar zu machen. - Der Feldname wird als AAD mitauthentifiziert. Ein Geheimtext laesst sich damit nicht von diagnosen nach notizen umhaengen. - Leere Werte werden zu NULL statt zu einem Umschlag - sonst verriete die Datenbank, dass ueberhaupt etwas eingetragen war. - VERSCHLUESSELTE_FELDER ist der einzige Ort, an dem steht, was verschluesselt gehoert. sealen()/oeffnen() arbeiten darauf. Argon2id nach OWASP-Empfehlung (19 MiB, t=2, p=1), mit hashVeraltet() fuer spaetere Parametererhoehung ohne Migration. Blindindex per HMAC-SHA256 mit eigenem Schluessel: erlaubt die Frage "kenne ich diese IBAN schon?", ohne sie im Klartext zu halten. Derselbe Mechanismus pseudonymisiert IP-Adressen fuers Audit-Log. TOTP mit otpauth, QR-Code serverseitig als Data-URI - kein externer QR-Dienst, kein CDN. Wiederherstellungscodes aus einem Alphabet ohne 0/O und 1/I, einzeln Argon2id-gehasht, Pruefung ohne fruehen Abbruch. 37 Tests decken Rundlauf, Manipulation, Feldbindung, Rotation, Salzung und Normalisierung ab. Etappe: 1 Phase: Fundament
21 lines
578 B
TypeScript
21 lines
578 B
TypeScript
import { defineConfig } from 'vitest/config'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
export default defineConfig({
|
|
test: {
|
|
environment: 'node',
|
|
include: ['tests/**/*.test.ts'],
|
|
setupFiles: ['./tests/setup/umgebung.ts'],
|
|
},
|
|
resolve: {
|
|
alias: [
|
|
{ find: '@', replacement: fileURLToPath(new URL('./src', import.meta.url)) },
|
|
// "server-only" wirft absichtlich beim Import ausserhalb des Servers.
|
|
{
|
|
find: /^server-only$/,
|
|
replacement: fileURLToPath(new URL('./tests/setup/leer.ts', import.meta.url)),
|
|
},
|
|
],
|
|
},
|
|
})
|