import crypto from 'node:crypto' const SCRYPT_KEY_LENGTH = 64 function scryptAsync(password, salt) { return new Promise((resolve, reject) => { crypto.scrypt(password, salt, SCRYPT_KEY_LENGTH, (error, derivedKey) => { if (error) { reject(error) return } resolve(derivedKey) }) }) } export async function hashPassword(password) { const salt = crypto.randomBytes(16).toString('hex') const derivedKey = await scryptAsync(password, salt) return `${salt}:${derivedKey.toString('hex')}` } export async function verifyPassword(password, storedHash) { const [salt, originalHash] = storedHash.split(':') if (!salt || !originalHash) { return false } const derivedKey = await scryptAsync(password, salt) const originalBuffer = Buffer.from(originalHash, 'hex') if (originalBuffer.length !== derivedKey.length) { return false } return crypto.timingSafeEqual(originalBuffer, derivedKey) } export function createSessionToken() { return crypto.randomBytes(32).toString('hex') } export function hashSessionToken(token) { return crypto.createHash('sha256').update(token).digest('hex') }