feat(users): add ability to disable users without deleting them

- Add disabled boolean field to user schema (PostgreSQL, MySQL, SQLite)
- Block disabled users from logging in via any auth provider (credentials, LDAP, OIDC)
- Check disabled status in session callback to prevent session replay
- Add changeDisabled API endpoint (admin-only)
- Include disabled field in getById and getAll user endpoints
- Add disable/enable user toggle in admin UI with status badge in user list
This commit is contained in:
ajnart committed 2026-07-06 02:55:39 +02:00
1 parent a55dc98487
commit 4ff2c9a7fb
13 files changed
+125 -1

No files matched your search

+5
View File
@@ -47,9 +47,14 @@ export const createSessionCallback = (db: Database): NextAuthCallbackOf<"session
where: eq(users.id, user.id),
columns: {
colorScheme: true,
disabled: true,
},
});
if (additionalProperties?.disabled) {
return null;
}
return {
...session,
user: {
@@ -23,6 +23,11 @@ export const authorizeWithBasicCredentialsAsync = async (
return null;
}
if (user.disabled) {
logger.warn("User is disabled", { userName: user.name });
return null;
}
logger.info("User is trying to log in. Checking password...", { userName: user.name });
const isValidPassword = await comparePasswordsAsync(credentials.password, user.password);
@@ -107,6 +107,7 @@ export const authorizeWithLdapCredentialsAsync = async (
email: true,
emailVerified: true,
provider: true,
disabled: true,
},
where: and(eq(users.email, mailResult.data), eq(users.provider, "ldap")),
});
@@ -130,6 +131,11 @@ export const authorizeWithLdapCredentialsAsync = async (
logger.info("User created successfully", { userName: credentials.name });
}
if (user.disabled) {
logger.warn("User is disabled", { userName: credentials.name });
throw new CredentialsSignin("User is disabled");
}
return {
id: user.id,
name: credentials.name,