Files
homarr/packages/auth/providers/credentials/authorization/basic-authorization.ts
T
ajnart 4ff2c9a7fb 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
2026-07-06 02:55:39 +02:00

46 lines
1.3 KiB
TypeScript

import type { z } from "zod/v4";
import { createLogger } from "@homarr/core/infrastructure/logs";
import type { Database } from "@homarr/db";
import { and, eq } from "@homarr/db";
import { users } from "@homarr/db/schema";
import type { userSignInSchema } from "@homarr/validation/user";
import { comparePasswordsAsync } from "../../../security";
const logger = createLogger({ module: "basicAuthorization" });
export const authorizeWithBasicCredentialsAsync = async (
db: Database,
credentials: z.infer<typeof userSignInSchema>,
) => {
const user = await db.query.users.findFirst({
where: and(eq(users.name, credentials.name.toLowerCase()), eq(users.provider, "credentials")),
});
if (!user?.password) {
logger.info("User not found", { userName: credentials.name });
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);
if (!isValidPassword) {
logger.warn("Password for user was incorrect", { userName: user.name });
return null;
}
logger.info("User successfully authorized", { userName: user.name });
return {
id: user.id,
name: user.name,
};
};