pl / src /password.ts
ghuser1's picture
Upload password.ts
9ccc46a verified
Raw
History Blame Contribute Delete
1.08 kB
import { timingSafeEqual, randomBytes, scryptSync } from 'node:crypto';
const PREFIX = 'scrypt';
const KEY_LENGTH = 64;
function hashWithSalt(password: string, salt: string): string {
return scryptSync(password, salt, KEY_LENGTH).toString('base64');
}
export function isPasswordHash(value: string): boolean {
return value.startsWith(`${PREFIX}$`);
}
export function hashPassword(password: string): string {
const salt = randomBytes(16).toString('base64');
const hash = hashWithSalt(password, salt);
return `${PREFIX}$${salt}$${hash}`;
}
export function verifyPassword(password: string, stored: string): boolean {
if (!stored) return true;
if (!isPasswordHash(stored)) return password === stored;
const [, salt, expected] = stored.split('$');
if (!salt || !expected) return false;
const actual = hashWithSalt(password, salt);
const expectedBytes = Buffer.from(expected, 'base64');
const actualBytes = Buffer.from(actual, 'base64');
if (expectedBytes.length !== actualBytes.length) return false;
return timingSafeEqual(expectedBytes, actualBytes);
}