feat(users): add managed users role and status controls

This commit is contained in:
2026-02-12 22:57:30 +01:00
parent 473433b220
commit 7a82934fe7
3 changed files with 465 additions and 16 deletions

View File

@@ -375,6 +375,63 @@ export async function ensureSupportUserBootstrap(): Promise<void> {
}
}
const MANAGED_USER_ROLE_ALLOWLIST = new Set<Role>(["admin", "editor", "manager"])
export async function createManagedUserAccount(input: {
email: string
username?: string | null
name: string
password: string
role: string
}): Promise<{ id: string; email: string; username: string | null; role: string }> {
const normalizedEmail = input.email.trim().toLowerCase()
const normalizedRole = normalizeRole(input.role)
if (!normalizedRole || !MANAGED_USER_ROLE_ALLOWLIST.has(normalizedRole)) {
throw new Error("Unsupported role for managed user account")
}
const existing = await db.user.findUnique({
where: { email: normalizedEmail },
select: { id: true, isProtected: true, isSystem: true },
})
if (existing) {
if (existing.isProtected || existing.isSystem) {
throw new Error("Cannot mutate protected/system account via managed user provisioning")
}
throw new Error("A user with this email already exists")
}
const preferredUsername =
normalizeUsernameCandidate(input.username) ??
normalizeUsernameCandidate(extractEmailLocalPart(normalizedEmail)) ??
"user"
await ensureCredentialUser({
email: normalizedEmail,
username: preferredUsername,
name: input.name.trim(),
password: input.password,
role: normalizedRole,
isHidden: false,
isSystem: false,
isProtected: false,
})
const created = await db.user.findUnique({
where: { email: normalizedEmail },
select: { id: true, email: true, username: true, role: true },
})
if (!created) {
throw new Error("Managed user provisioning failed")
}
return created
}
const DEFAULT_E2E_ADMIN_EMAIL = "e2e-admin@cms.local"
const DEFAULT_E2E_ADMIN_USERNAME = "e2e-admin"
const DEFAULT_E2E_ADMIN_PASSWORD = "e2e-admin-password"