OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-identity / test / identity-manager.test.js

126 lines · javascript ref:
import test from 'brittle'
import { createTestDb } from './helpers.js'
import { IdentityManager } from '../lib/identity-manager.js'

test('ready() generates persistent keypair', async (t) => {
  const { db, cleanup } = await createTestDb()
  const mgr = new IdentityManager(db)
  await mgr.ready()

  t.ok(mgr.getPublicKey(), 'has public key')
  t.is(mgr.getPublicKey().length, 32, 'public key is 32 bytes')
  t.ok(mgr.getKeypair(), 'has keypair')
  t.is(mgr.getKeypair().secretKey.length, 64, 'secret key is 64 bytes')

  mgr.destroy()
  await cleanup()
})

test('ready() loads existing keypair on re-init', async (t) => {
  const { db, cleanup } = await createTestDb()

  const mgr1 = new IdentityManager(db)
  await mgr1.ready()
  const pk1 = mgr1.getPublicKeyBase64()
  mgr1.destroy()

  const mgr2 = new IdentityManager(db)
  await mgr2.ready()
  const pk2 = mgr2.getPublicKeyBase64()
  mgr2.destroy()

  t.is(pk1, pk2, 'same keypair on re-init')

  await cleanup()
})

test('getPublicKeyBase64 returns 44-char base64', async (t) => {
  const { db, cleanup } = await createTestDb()
  const mgr = new IdentityManager(db)
  await mgr.ready()

  const pk = mgr.getPublicKeyBase64()
  t.is(typeof pk, 'string')
  t.is(pk.length, 44, '44-char base64')

  mgr.destroy()
  await cleanup()
})

test('getKeypairString returns 132-char base64', async (t) => {
  const { db, cleanup } = await createTestDb()
  const mgr = new IdentityManager(db)
  await mgr.ready()

  const kp = mgr.getKeypairString()
  t.is(typeof kp, 'string')
  t.is(kp.length, 132, '132-char keypair')
  t.is(kp.substring(0, 44), mgr.getPublicKeyBase64(), 'first 44 chars = pubkey')

  mgr.destroy()
  await cleanup()
})

test('getPublicKeyHex returns hex string', async (t) => {
  const { db, cleanup } = await createTestDb()
  const mgr = new IdentityManager(db)
  await mgr.ready()

  const hex = mgr.getPublicKeyHex()
  t.is(typeof hex, 'string')
  t.is(hex.length, 64, '64-char hex (32 bytes)')

  mgr.destroy()
  await cleanup()
})

test('sign and verify', async (t) => {
  const { db, cleanup } = await createTestDb()
  const mgr = new IdentityManager(db)
  await mgr.ready()

  const data = Buffer.from('test data to sign')
  const sig = mgr.sign(data)
  t.ok(sig, 'produces signature')
  t.is(sig.length, 64, 'signature is 64 bytes')

  t.ok(mgr.verify(data, sig), 'valid signature verifies')
  t.absent(mgr.verify(Buffer.from('wrong data'), sig), 'wrong data fails')

  mgr.destroy()
  await cleanup()
})

test('setMnemonic and getMnemonic', async (t) => {
  const { db, cleanup } = await createTestDb()
  const mgr = new IdentityManager(db)
  await mgr.ready()

  t.absent(mgr.getMnemonic(), 'no mnemonic initially')

  await mgr.setMnemonic('test word list here for mnemonic storage')
  t.is(mgr.getMnemonic(), 'test word list here for mnemonic storage')

  mgr.destroy()
  await cleanup()
})

test('destroy zeros secret key', async (t) => {
  const { db, cleanup } = await createTestDb()
  const mgr = new IdentityManager(db)
  await mgr.ready()

  const secretKey = mgr.getKeypair().secretKey
  mgr.destroy()

  // After destroy, the buffer should be zeroed
  let allZero = true
  for (let i = 0; i < secretKey.length; i++) {
    if (secretKey[i] !== 0) { allZero = false; break }
  }
  t.ok(allZero, 'secret key zeroed after destroy')
  t.absent(mgr.getKeypair(), 'keypair is null after destroy')

  await cleanup()
})