Harden authentication, tenant isolation and security boundaries
This commit is contained in:
@@ -170,6 +170,7 @@ model Family {
|
||||
|
||||
@@index([kitaId])
|
||||
@@map("families")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
@@ -217,6 +218,8 @@ model User {
|
||||
lastLoginAt DateTime?
|
||||
failedLoginAttempts Int @default(0)
|
||||
lockedUntil DateTime?
|
||||
disabledAt DateTime?
|
||||
sessionVersion Int @default(0)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
@@ -244,6 +247,7 @@ model User {
|
||||
@@index([familyId])
|
||||
@@index([kitaId, role])
|
||||
@@map("users")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
@@ -276,6 +280,7 @@ model Child {
|
||||
@@index([kitaId])
|
||||
@@index([familyId])
|
||||
@@map("children")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
@@ -298,6 +303,7 @@ model Educator {
|
||||
|
||||
@@index([kitaId])
|
||||
@@map("educators")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
@@ -321,6 +327,7 @@ model ParentDuty {
|
||||
@@unique([kitaId, name])
|
||||
@@index([kitaId])
|
||||
@@map("parent_duties")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
model ParentDutyAssignment {
|
||||
@@ -360,6 +367,7 @@ model DutyType {
|
||||
@@unique([kitaId, name])
|
||||
@@index([kitaId])
|
||||
@@map("duty_types")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
model DutyAssignment {
|
||||
@@ -435,6 +443,7 @@ model Announcement {
|
||||
|
||||
@@index([kitaId, createdAt])
|
||||
@@index([authorId])
|
||||
@@unique([id, kitaId])
|
||||
@@map("announcements")
|
||||
}
|
||||
|
||||
@@ -446,12 +455,14 @@ model Attachment {
|
||||
fileName String
|
||||
fileUrl String
|
||||
fileType String
|
||||
sizeBytes Int?
|
||||
|
||||
@@index([announcementId])
|
||||
@@map("attachments")
|
||||
}
|
||||
|
||||
model AnnouncementRead {
|
||||
kitaId String
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
@@ -462,6 +473,7 @@ model AnnouncementRead {
|
||||
|
||||
@@unique([userId, announcementId])
|
||||
@@index([announcementId])
|
||||
@@index([kitaId])
|
||||
@@map("announcement_reads")
|
||||
}
|
||||
|
||||
@@ -536,6 +548,7 @@ model Termin {
|
||||
@@index([kitaId, startDate])
|
||||
@@index([kitaId, status])
|
||||
@@map("termine")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
model EventParticipation {
|
||||
@@ -612,6 +625,7 @@ model NotdienstPlan {
|
||||
@@unique([kitaId, year, month])
|
||||
@@index([kitaId])
|
||||
@@map("notdienst_plans")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
/// Verfügbarkeits-Eintrag eines Elternteils für ein Kind an einem Tag.
|
||||
@@ -664,6 +678,7 @@ model NotdienstAssignment {
|
||||
@@unique([planId, date])
|
||||
@@index([kitaId, date])
|
||||
@@map("notdienst_assignments")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
/// Tauschanfrage zwischen Eltern fuer zwei bereits veroeffentlichte
|
||||
@@ -786,3 +801,21 @@ model VerificationToken {
|
||||
@@unique([identifier, token])
|
||||
@@map("verification_tokens")
|
||||
}
|
||||
|
||||
model RateLimitBucket {
|
||||
key String @id
|
||||
count Int
|
||||
resetAt DateTime
|
||||
@@index([resetAt])
|
||||
@@map("rate_limit_buckets")
|
||||
}
|
||||
|
||||
model PendingRegistration {
|
||||
email String @id
|
||||
firstName String
|
||||
lastName String
|
||||
tokenHash String @unique
|
||||
expiresAt DateTime
|
||||
@@index([expiresAt])
|
||||
@@map("pending_registrations")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user