Tests: vollständige Suite auch mit RLS_ENFORCED=true grün
- test-tenant-isolation: Compound-Key mit fremdem Mandanten – im Owner-Betrieb Throw (Tenant-Guard), unter scharfer RLS liefert die DB null; beides = kein Datenabfluss - run-tests.ts: lädt .env und leitet RLS_DATABASE_URL (Rolle craftvia_app) aus DATABASE_URL ab, wenn RLS_ENFORCED=true und keine URL gesetzt ist Nachweis: RLS_ENFORCED=true npm run test → 52/52; npm run gate → 52/52. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,21 @@ async function expectThrow(fn: () => Promise<unknown>, msg: string) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compound keys with a foreign tenantId: in owner mode the tenant guard throws (fail-closed);
|
||||
* with RLS_ENFORCED=true the database already hides the row, so the query returns null.
|
||||
* Both outcomes mean "no data leak" — anything else fails.
|
||||
*/
|
||||
async function expectThrowOrNullUnderRls(fn: () => Promise<unknown>, msg: string) {
|
||||
if (process.env.RLS_ENFORCED !== "true") return expectThrow(fn, msg);
|
||||
try {
|
||||
const r = await fn();
|
||||
ok(r === null, `${msg} (RLS: null)${r === null ? "" : ` — statt null: ${JSON.stringify(r)}`}`);
|
||||
} catch {
|
||||
ok(true, `${msg} (RLS: Throw)`);
|
||||
}
|
||||
}
|
||||
|
||||
/** Erwartet, dass `fn` `null` liefert (kein Datensatz, kein Abfluss). */
|
||||
async function expectNull(fn: () => Promise<unknown>, msg: string) {
|
||||
const r = await fn();
|
||||
@@ -98,7 +113,7 @@ async function main() {
|
||||
);
|
||||
|
||||
// (6) Compound-Unique-Key (tenantId_key) mit fremdem tenantId, select ohne tenantId.
|
||||
await expectThrow(
|
||||
await expectThrowOrNullUnderRls(
|
||||
() =>
|
||||
dbA.role.findUnique({
|
||||
where: { tenantId_key: { tenantId: tenantB.id, key: roleB.key } },
|
||||
@@ -108,7 +123,7 @@ async function main() {
|
||||
);
|
||||
|
||||
// (7) Compound-Unique-Key mit fremdem tenantId, ohne select.
|
||||
await expectThrow(
|
||||
await expectThrowOrNullUnderRls(
|
||||
() =>
|
||||
dbA.role.findUnique({
|
||||
where: { tenantId_key: { tenantId: tenantB.id, key: roleB.key } },
|
||||
|
||||
Reference in New Issue
Block a user