feat: Grundgerüst mit Anmeldung, Layout und Design-Tokens
Next.js 16, Prisma 7, Tailwind 4 und Vitest/Playwright, Konfiguration aus Laufzettel übernommen, weil dort derselbe Stack erprobt ist. Die Farben der Branding-Vorgabe stehen als Tokens in globals.css, das helle Theme setzt dieselben Namen neu. Amber und Rot sind dort abgedunkelt, sonst reicht der Kontrast nicht – ein Test prüft beide Themes gegen 4,5:1. Anmeldung mit lokalem Benutzer, Rolle je Anfrage aus der Datenbank, Audit-Log per Trigger nur anhängbar. Geprüft im gebauten Stand auf 1440 px und 390 px. Closes #001 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { entschluesseln, GeheimnisFehler, verschluesseln } from "@/lib/geheimnisse";
|
||||
|
||||
const ursprung = process.env["PROXDEPLOY_SCHLUESSEL"];
|
||||
afterEach(() => {
|
||||
process.env["PROXDEPLOY_SCHLUESSEL"] = ursprung;
|
||||
});
|
||||
|
||||
describe("Geheimnisse (AES-256-GCM)", () => {
|
||||
it("verschlüsselt und entschlüsselt verlustfrei, auch Umlaute und Zeilenumbrüche", () => {
|
||||
const klar = "-----BEGIN OPENSSH PRIVATE KEY-----\nÄÖÜ ß\n-----END-----\n";
|
||||
expect(entschluesseln(verschluesseln(klar))).toBe(klar);
|
||||
});
|
||||
|
||||
it("erzeugt bei gleichem Klartext jedes Mal einen anderen Geheimtext (neuer IV)", () => {
|
||||
expect(verschluesseln("geheim")).not.toBe(verschluesseln("geheim"));
|
||||
});
|
||||
|
||||
it("trägt das Versionspräfix v1", () => {
|
||||
expect(verschluesseln("x").startsWith("v1.")).toBe(true);
|
||||
});
|
||||
|
||||
it("wirft bei verändertem Geheimtext", () => {
|
||||
const teile = verschluesseln("geheim").split(".");
|
||||
const daten = Buffer.from(teile[3]!, "base64");
|
||||
daten[0] = daten[0]! ^ 0xff;
|
||||
teile[3] = daten.toString("base64");
|
||||
expect(() => entschluesseln(teile.join("."))).toThrow(GeheimnisFehler);
|
||||
});
|
||||
|
||||
it("wirft mit anderem Schlüssel", () => {
|
||||
const geheim = verschluesseln("geheim");
|
||||
process.env["PROXDEPLOY_SCHLUESSEL"] = Buffer.alloc(32, 9).toString("base64");
|
||||
expect(() => entschluesseln(geheim)).toThrow(/nicht mehr derselbe/);
|
||||
});
|
||||
|
||||
it("verlangt genau 32 Byte Schlüssel und nennt den Befehl zum Erzeugen", () => {
|
||||
process.env["PROXDEPLOY_SCHLUESSEL"] = Buffer.alloc(16).toString("base64");
|
||||
expect(() => verschluesseln("x")).toThrow(/openssl rand -base64 32/);
|
||||
});
|
||||
|
||||
it("lehnt unbekannte Formate und Versionen ab", () => {
|
||||
expect(() => entschluesseln("klartext")).toThrow(/unbekanntes Format/);
|
||||
expect(() => entschluesseln("v9.a.b.c")).toThrow(/unbekannte Version/);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user