import assert from 'node:assert/strict'; import { test } from 'node:test'; import { hashPassword, hashPasswordAsync, isLegacyPasswordHash, verifyPassword, verifyPasswordAsync, verifyScryptPasswordAsync, verifyScryptPassword, verifyVestaPassword } from '../src/password-hash.js'; test('hashes and verifies current scrypt passwords', () => { const stored = hashPassword('correct horse battery staple'); assert.match(stored, /^scrypt\$[0-9a-f]{32}\$[0-9a-f]{128}$/); assert.equal(verifyScryptPassword('correct horse battery staple', stored), true); assert.equal(verifyPassword('correct horse battery staple', stored), true); assert.equal(verifyPassword('wrong password', stored), false); }); test('hashes and verifies current scrypt passwords asynchronously', async () => { const stored = await hashPasswordAsync('correct horse battery staple'); assert.match(stored, /^scrypt\$[0-9a-f]{32}\$[0-9a-f]{128}$/); assert.equal(await verifyScryptPasswordAsync('correct horse battery staple', stored), true); assert.equal(await verifyPasswordAsync('correct horse battery staple', stored), true); assert.equal(await verifyPasswordAsync('wrong password', stored), false); }); test('verifies Vesta MD5-CRYPT passwords with known vectors', () => { const passwordVector = '$1$hfT7jp2q$G3yf0NUx7mUkX.LIFWQxN.'; const unicodeVector = '$1$salt1234$VwTk0ScCcREDNl.8aCJCc0'; assert.equal(verifyVestaPassword('password', `{MD5}${passwordVector}`), true); assert.equal(verifyVestaPassword('password', `{MD5-CRYPT}${passwordVector}`), true); assert.equal(verifyVestaPassword('pässwörd', unicodeVector), true); assert.equal(verifyPassword('password', `{MD5}${passwordVector}`), true); assert.equal(verifyVestaPassword('wrong password', `{MD5}${passwordVector}`), false); }); test('detects only supported legacy password hashes', () => { assert.equal(isLegacyPasswordHash('{MD5}$1$12345678$xek.CpjQUVgdf/P2N9KQf/'), true); assert.equal(isLegacyPasswordHash('{MD5-CRYPT}$1$12345678$xek.CpjQUVgdf/P2N9KQf/'), true); assert.equal(isLegacyPasswordHash('$1$12345678$xek.CpjQUVgdf/P2N9KQf/'), true); assert.equal(isLegacyPasswordHash('{SHA256-CRYPT}$5$salt$hash'), false); assert.equal(isLegacyPasswordHash('{MD5}$1$toolongsalt$invalid'), false); assert.equal(verifyPassword('password', 'malformed'), false); });