import { verifyPassword } from '../../utils/password.js'; import { getDummyHash, usersRegistry } from '../../auth/users.registry.js'; import { InvalidCredentialsError } from '../../utils/errors.js'; export interface AuthenticatedUser { id: string; username: string; slug: string; displayName: string; } export async function verifyCredentials( username: string, password: string, ): Promise { const user = usersRegistry.findByUsername(username); // Always run bcrypt.compare to keep response time stable regardless of whether // the username exists. Otherwise an attacker could enumerate usernames by timing. const hash = user?.passwordHash ?? (await getDummyHash()); const ok = await verifyPassword(password, hash); if (!user || !ok) { throw new InvalidCredentialsError(); } return { id: user.id, username: user.username, slug: user.slug, displayName: user.displayName }; }