Merge family absence flows while preserving security hardening

This commit is contained in:
t.indorf
2026-10-10 07:08:41 +02:00
30 changed files with 2822 additions and 644 deletions
+3 -1
View File
@@ -163,6 +163,7 @@ test('database blocks cross-tenant child, user, RSVP and announcement links', as
await assert.rejects(prisma.child.create({ data: { firstName: 'Wrong', lastName: 'Tenant', kitaId: kitaA.id, familyId: familyB.id } }), error => error.code === 'P2003');
await assert.rejects(prisma.user.update({ where: { id: parentA.id }, data: { familyId: familyB.id } }), error => error.code === 'P2003');
await assert.rejects(prisma.announcement.create({ data: { kitaId: kitaA.id, authorId: parentB.id, title: 'Wrong', content: 'Wrong' } }), error => error.code === 'P2003');
await assert.rejects(prisma.invitation.create({ data: { kitaId: kitaA.id, userId: parentB.id, email: 'cross-' + prefix + '@example.invalid', token: randomUUID(), expiresAt: new Date(Date.now() + 60000), invitedById: adminA.id } }), error => error.code === 'P2003');
const event = await prisma.termin.create({ data: { kitaId: kitaA.id, title: 'Event', type: 'SONSTIGES', status: 'CONFIRMED', startDate: new Date(), endDate: new Date() } });
await assert.rejects(prisma.eventParticipation.create({ data: { kitaId: kitaA.id, eventId: event.id, childId: childB.id, status: 'ATTENDING' } }), error => error.code === 'P2003');
});
@@ -304,6 +305,7 @@ test('changing a parent email revokes sessions and requires fresh mailbox activa
assert.equal(await authConfig.callbacks.jwt({ token: oldToken }),null);
assert.equal(await authConfig.providers[0].authorize({ email: newEmail, password: 'Safe-test-password' }),null);
const initialInvite = emails.at(-1).react.props.inviteLink.split('/').at(-1);
await prisma.invitation.update({ where: { userId: parentA.id }, data: { sentAt: new Date(Date.now() - 61_000) } });
assert.equal((await actions.resendParentInvite(parentA.id)).success,true);
const renewedInvite = emails.at(-1).react.props.inviteLink.split('/').at(-1);
assert.notEqual(initialInvite,renewedInvite);
@@ -355,7 +357,7 @@ test('upload quota holds under concurrent writes and accepted MIME comes from fi
test('all supplemental database tenant constraints are present', async () => {
const [row] = await prisma.$queryRaw`SELECT count(*)::int AS count FROM pg_constraint WHERE conname LIKE '%_tenant_fkey'`;
assert.equal(row.count,41);
assert.equal(row.count,42);
});
test('role guard authenticates once and keeps role validation on that session', async () => {
let calls = 0;