Basis: Certvia dev@a48c5fb als Fundament für Craftvia
Unveränderter Stand von certvia/dev (a48c5fb) plus Craftvia-Spezifikation und Brandbook unter docs/craftvia/. ISMS-Module werden im Folgecommit entfernt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
// WS1-Abnahmetest (Option C) — Mandanten-Login gegen die globale Identity.
|
||||
//
|
||||
// Prüft `authorizeTenantCredentials` (src/server/auth.ts) gegen die Seed-DB:
|
||||
// 1. Single-Membership: admin@demo (ohne Slug) landet in seinem Mandanten.
|
||||
// 2. Falsches Passwort → null (kein Login).
|
||||
// 3. Multi-Membership OHNE Slug → null (Auswahlseite /select-tenant = WS2).
|
||||
// 4. Multi-Membership MIT Slug → richtiger Mandant + mandantenspezifische Rechte.
|
||||
// 5. Falscher/fremder Slug → null.
|
||||
// 6. Unbekannte E-Mail → null.
|
||||
// 7. Session-Shape trägt identityId, activeMembershipId und memberships[].
|
||||
//
|
||||
// Lauf: npx tsx scripts/test-identity-login.ts (setzt den Demo-Seed voraus)
|
||||
|
||||
import "dotenv/config";
|
||||
import { prisma } from "../src/server/db";
|
||||
import { authorizeTenantCredentials } from "../src/server/auth";
|
||||
|
||||
const PW = "Demo1234!";
|
||||
let failures = 0;
|
||||
const ok = (cond: boolean, msg: string) => {
|
||||
console.log(`${cond ? "✓" : "✗ FEHLER"} ${msg}`);
|
||||
if (!cond) failures++;
|
||||
};
|
||||
|
||||
async function main() {
|
||||
console.log("\n— 1) Single-Membership: admin@demo ohne Slug —");
|
||||
const admin = await authorizeTenantCredentials({ email: "admin@demo.example", password: PW });
|
||||
ok(!!admin, "admin@demo meldet sich an");
|
||||
ok(admin?.tenantSlug === "demo", `aktiver Mandant = demo (${admin?.tenantSlug})`);
|
||||
ok(!!admin?.identityId, "Session trägt identityId");
|
||||
ok(admin?.activeMembershipId === admin?.id, "activeMembershipId = User.id der Mitgliedschaft");
|
||||
ok((admin?.memberships?.length ?? 0) === 1, `memberships-Liste = 1 (${admin?.memberships?.length})`);
|
||||
ok(admin?.roles.includes("tenant-admin") ?? false, "Rolle tenant-admin im aktiven Mandanten");
|
||||
|
||||
console.log("\n— 2) Falsches Passwort → null —");
|
||||
const wrong = await authorizeTenantCredentials({ email: "admin@demo.example", password: "falsch!!" });
|
||||
ok(wrong === null, "falsches Passwort ⇒ null");
|
||||
// Zähler zurücksetzen, damit wiederholte Läufe die Identity nicht sperren.
|
||||
await prisma.identity.update({ where: { email: "admin@demo.example" }, data: { failedLogins: 0, lockedUntil: null } });
|
||||
|
||||
console.log("\n— 3) Multi-Membership ohne Slug → Session ohne aktiven Mandanten (WS2) —");
|
||||
const noTenant = await authorizeTenantCredentials({ email: "multi@demo.example", password: PW });
|
||||
ok(!!noTenant && noTenant.tenantId === "", "multi@ ohne Slug ⇒ Session ohne aktiven Mandanten (tenantId leer → /select-tenant)");
|
||||
ok((noTenant?.memberships?.length ?? 0) === 2, `memberships-Liste = 2 im No-Tenant-State (${noTenant?.memberships?.length})`);
|
||||
|
||||
console.log("\n— 4) Multi-Membership mit Slug → korrekter Mandant + Rechte —");
|
||||
const inDemo2 = await authorizeTenantCredentials({ email: "multi@demo.example", password: PW, tenant: "demo2" });
|
||||
ok(inDemo2?.tenantSlug === "demo2", `Slug demo2 ⇒ aktiver Mandant demo2 (${inDemo2?.tenantSlug})`);
|
||||
ok(inDemo2?.roles.includes("tenant-admin") ?? false, "in demo2: Rolle tenant-admin");
|
||||
ok((inDemo2?.memberships?.length ?? 0) === 2, `memberships-Liste = 2 (${inDemo2?.memberships?.length})`);
|
||||
|
||||
const inDemo = await authorizeTenantCredentials({ email: "multi@demo.example", password: PW, tenant: "demo" });
|
||||
ok(inDemo?.tenantSlug === "demo", `Slug demo ⇒ aktiver Mandant demo (${inDemo?.tenantSlug})`);
|
||||
ok(inDemo?.roles.includes("user") ?? false, "in demo: Rolle user");
|
||||
// Rechte je aktivem Mandant verschieden (tenant-admin demo2 ≠ user demo).
|
||||
ok(
|
||||
JSON.stringify([...(inDemo?.permissions ?? [])].sort()) !== JSON.stringify([...(inDemo2?.permissions ?? [])].sort()),
|
||||
"Rechte je aktivem Mandant verschieden (demo user ≠ demo2 admin)"
|
||||
);
|
||||
|
||||
console.log("\n— 5) Fremder/falscher Slug → null —");
|
||||
const wrongSlug = await authorizeTenantCredentials({ email: "admin@demo.example", password: PW, tenant: "gibtsnicht" });
|
||||
ok(wrongSlug === null, "unbekannter Slug ⇒ null");
|
||||
|
||||
console.log("\n— 6) Unbekannte E-Mail → null —");
|
||||
const unknown = await authorizeTenantCredentials({ email: "gibtsnicht@demo.example", password: PW });
|
||||
ok(unknown === null, "unbekannte E-Mail ⇒ null");
|
||||
}
|
||||
|
||||
main()
|
||||
.then(async () => {
|
||||
await prisma.$disconnect();
|
||||
if (failures > 0) {
|
||||
console.error(`\n✗ ${failures} Testfall/-fälle fehlgeschlagen.`);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log("\nOK");
|
||||
})
|
||||
.catch(async (e) => {
|
||||
console.error(e);
|
||||
await prisma.$disconnect();
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user