password-hash.test.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import assert from 'node:assert/strict';
  2. import { test } from 'node:test';
  3. import {
  4. hashPassword,
  5. hashPasswordAsync,
  6. isLegacyPasswordHash,
  7. verifyPassword,
  8. verifyPasswordAsync,
  9. verifyScryptPasswordAsync,
  10. verifyScryptPassword,
  11. verifyVestaPassword
  12. } from '../src/password-hash.js';
  13. test('hashes and verifies current scrypt passwords', () => {
  14. const stored = hashPassword('correct horse battery staple');
  15. assert.match(stored, /^scrypt\$[0-9a-f]{32}\$[0-9a-f]{128}$/);
  16. assert.equal(verifyScryptPassword('correct horse battery staple', stored), true);
  17. assert.equal(verifyPassword('correct horse battery staple', stored), true);
  18. assert.equal(verifyPassword('wrong password', stored), false);
  19. });
  20. test('hashes and verifies current scrypt passwords asynchronously', async () => {
  21. const stored = await hashPasswordAsync('correct horse battery staple');
  22. assert.match(stored, /^scrypt\$[0-9a-f]{32}\$[0-9a-f]{128}$/);
  23. assert.equal(await verifyScryptPasswordAsync('correct horse battery staple', stored), true);
  24. assert.equal(await verifyPasswordAsync('correct horse battery staple', stored), true);
  25. assert.equal(await verifyPasswordAsync('wrong password', stored), false);
  26. });
  27. test('verifies Vesta MD5-CRYPT passwords with known vectors', () => {
  28. const passwordVector = '$1$hfT7jp2q$G3yf0NUx7mUkX.LIFWQxN.';
  29. const unicodeVector = '$1$salt1234$VwTk0ScCcREDNl.8aCJCc0';
  30. assert.equal(verifyVestaPassword('password', `{MD5}${passwordVector}`), true);
  31. assert.equal(verifyVestaPassword('password', `{MD5-CRYPT}${passwordVector}`), true);
  32. assert.equal(verifyVestaPassword('pässwörd', unicodeVector), true);
  33. assert.equal(verifyPassword('password', `{MD5}${passwordVector}`), true);
  34. assert.equal(verifyVestaPassword('wrong password', `{MD5}${passwordVector}`), false);
  35. });
  36. test('detects only supported legacy password hashes', () => {
  37. assert.equal(isLegacyPasswordHash('{MD5}$1$12345678$xek.CpjQUVgdf/P2N9KQf/'), true);
  38. assert.equal(isLegacyPasswordHash('{MD5-CRYPT}$1$12345678$xek.CpjQUVgdf/P2N9KQf/'), true);
  39. assert.equal(isLegacyPasswordHash('$1$12345678$xek.CpjQUVgdf/P2N9KQf/'), true);
  40. assert.equal(isLegacyPasswordHash('{SHA256-CRYPT}$5$salt$hash'), false);
  41. assert.equal(isLegacyPasswordHash('{MD5}$1$toolongsalt$invalid'), false);
  42. assert.equal(verifyPassword('password', 'malformed'), false);
  43. });