feat(auth): block protected account deletion in auth endpoints
This commit is contained in:
@@ -452,6 +452,34 @@ export async function enforceOwnerInvariant(): Promise<OwnerInvariantState> {
|
||||
})
|
||||
}
|
||||
|
||||
export async function canDeleteUserAccount(userId: string): Promise<boolean> {
|
||||
const user = await db.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: { role: true, isProtected: true },
|
||||
})
|
||||
|
||||
if (!user) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Protected/system users (support + canonical owner) are never deletable
|
||||
// through self-service endpoints.
|
||||
if (user.isProtected) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (user.role !== "owner") {
|
||||
return true
|
||||
}
|
||||
|
||||
// Defensive fallback for drifted data; normal flow should already keep one owner.
|
||||
const ownerCount = await db.user.count({
|
||||
where: { role: "owner" },
|
||||
})
|
||||
|
||||
return ownerCount > 1
|
||||
}
|
||||
|
||||
export async function promoteFirstRegisteredUserToOwner(userId: string): Promise<boolean> {
|
||||
const promoted = await db.$transaction(async (tx) => {
|
||||
const existingOwner = await tx.user.findFirst({
|
||||
|
||||
Reference in New Issue
Block a user