mirror of
https://github.com/orbitdb/orbitdb.git
synced 2025-03-30 15:08:28 +00:00

Fix sync Fix linter Fix tests Clean up Set default references count to 0 Fix sync Use address instead of databaseId Sync protocol Keep references to open databases in OrbitDB Fix append benchmark Initial version of heads exchange Remove Feed Fix KeyValuePersisted iterator Refactor OrbitDBAddress a bit more Add rest of the database types Refactor OrbitDB addresses Initial version for the full circle Initial structure and tests for new OrbitDB Make sure KeyStore is open when a Database is created Re-organize OrbitDB Use new databases and Log More clean up Add 'drop' event to Database Clean up OrbitDB Remove id from OrbitDB Use new KeyStore and Identities Remove storage from OrbitDB Remove migrations from OrbitDB Remove caches from OrbitDB Remove pubsub from OrbitDB
338 lines
11 KiB
JavaScript
338 lines
11 KiB
JavaScript
import assert from 'assert'
|
|
import path from 'path'
|
|
import rmrf from 'rimraf'
|
|
import KeyStore, { signMessage, verifyMessage } from '../../src/key-store.js'
|
|
import Identities, { addIdentityProvider } from '../../src/identities/identities.js'
|
|
import Identity from '../../src/identities/identity.js'
|
|
import testKeysPath from '../fixtures/test-keys-path.js '
|
|
const savedKeysPath = path.resolve('./test/identities/fixtures/savedKeys')
|
|
const identityKeysPath = path.resolve('./test/identities/identityKeys')
|
|
const type = 'orbitdb'
|
|
|
|
describe('Identities', function () {
|
|
before(async () => {
|
|
rmrf.sync(identityKeysPath)
|
|
})
|
|
|
|
after(async () => {
|
|
rmrf.sync(identityKeysPath)
|
|
})
|
|
|
|
describe('Creating Identities', () => {
|
|
const id = 'userA'
|
|
|
|
let identities
|
|
let identity
|
|
|
|
afterEach(async () => {
|
|
if (identities) {
|
|
await identities.keystore.close()
|
|
}
|
|
})
|
|
|
|
it('has the correct id', async () => {
|
|
identities = await Identities({ identityKeysPath })
|
|
identity = await identities.createIdentity({ id })
|
|
const key = await identities.keystore.getKey(id)
|
|
const externalId = Buffer.from(key.public.marshal()).toString('hex')
|
|
assert.strictEqual(identity.id, externalId)
|
|
})
|
|
})
|
|
|
|
describe('Get Identity', () => {
|
|
const id = 'userA'
|
|
|
|
let identities
|
|
let identity
|
|
|
|
afterEach(async () => {
|
|
if (identities) {
|
|
await identities.keystore.close()
|
|
}
|
|
})
|
|
|
|
it('gets the identity from storage', async () => {
|
|
identities = await Identities({ identityKeysPath })
|
|
identity = await identities.createIdentity({ id })
|
|
const result = await identities.getIdentity(identity.hash)
|
|
assert.strictEqual(result.id, identity.id)
|
|
assert.strictEqual(result.hash, identity.hash)
|
|
assert.strictEqual(result.publicKey, identity.publicKey)
|
|
assert.strictEqual(result.type, identity.type)
|
|
assert.deepStrictEqual(result.signatures, identity.signatures)
|
|
assert.strictEqual(result.sign, undefined)
|
|
assert.strictEqual(result.verify, undefined)
|
|
})
|
|
})
|
|
|
|
describe.skip('Passing in custom keystore', async () => {
|
|
const id = 'userB'
|
|
|
|
let identity
|
|
let identities
|
|
let keystore
|
|
|
|
before(async () => {
|
|
keystore = await KeyStore({ path: testKeysPath })
|
|
identities = await Identities({ keystore })
|
|
})
|
|
|
|
after(async () => {
|
|
if (keystore) {
|
|
await keystore.close()
|
|
}
|
|
})
|
|
|
|
it('has the correct id', async () => {
|
|
identity = await identities.createIdentity({ id })
|
|
keystore = identities.keystore
|
|
const key = await keystore.getKey(id)
|
|
const externalId = Buffer.from(key.public.marshal()).toString('hex')
|
|
assert.strictEqual(identity.id, externalId)
|
|
})
|
|
|
|
it('created a key for id in identity-keystore', async () => {
|
|
const key = await keystore.getKey(id)
|
|
assert.notStrictEqual(key, undefined)
|
|
})
|
|
|
|
it('has the correct public key', async () => {
|
|
const key = await keystore.getKey(id)
|
|
const externalId = Buffer.from(key.public.marshal()).toString('hex')
|
|
const signingKey = await keystore.getKey(externalId)
|
|
assert.notStrictEqual(signingKey, undefined)
|
|
assert.strictEqual(identity.publicKey, keystore.getPublic(signingKey))
|
|
})
|
|
|
|
it('has a signature for the id', async () => {
|
|
const key = await keystore.getKey(id)
|
|
const externalId = Buffer.from(key.public.marshal()).toString('hex')
|
|
const signingKey = await keystore.getKey(externalId)
|
|
const idSignature = await signMessage(signingKey, externalId)
|
|
const publicKey = Buffer.from(signingKey.public.marshal()).toString('hex')
|
|
const verifies = await verifyMessage(idSignature, publicKey, externalId)
|
|
assert.strictEqual(verifies, true)
|
|
assert.strictEqual(identity.signatures.id, idSignature)
|
|
})
|
|
|
|
it('has a signature for the publicKey', async () => {
|
|
const key = await keystore.getKey(id)
|
|
const externalId = Buffer.from(key.public.marshal()).toString('hex')
|
|
const signingKey = await keystore.getKey(externalId)
|
|
const idSignature = await signMessage(signingKey, externalId)
|
|
const externalKey = await keystore.getKey(id)
|
|
const publicKeyAndIdSignature = await signMessage(externalKey, identity.publicKey + idSignature)
|
|
assert.strictEqual(identity.signatures.publicKey, publicKeyAndIdSignature)
|
|
})
|
|
})
|
|
|
|
describe('create an identity with saved keys', () => {
|
|
const id = 'userX'
|
|
|
|
const expectedPublicKey = '0442fa42a69135eade1e37ea520bc8ee9e240efd62cb0edf0516b21258b4eae656241c40da462c95189b1ade83419138ca59845beb90d29b1be8542bde388ca5f9'
|
|
const expectedIdSignature = '3044022068b4bc360d127e39164fbc3b5184f5bd79cc5976286f793d9b38d1f2818e0259022027b875dc8c73635b32db72177b9922038ec4b1eabc8f1fd0919806b0b2519419'
|
|
const expectedPkIdSignature = '304402206d1aeff3a874b7bd83300219badf68bbcb514e2c60a7b40cec5f78ff2b7ba0f20220085f5f138730603418a0570ba12720f0a46997527bb4a077cd26b545e7811c31'
|
|
|
|
let identities
|
|
let identity
|
|
let savedKeysKeyStore
|
|
|
|
before(async () => {
|
|
savedKeysKeyStore = await KeyStore({ path: testKeysPath })
|
|
|
|
identities = await Identities({ keystore: savedKeysKeyStore })
|
|
identity = await identities.createIdentity({ id })
|
|
})
|
|
|
|
after(async () => {
|
|
if (identities) {
|
|
await identities.keystore.close()
|
|
}
|
|
rmrf.sync(savedKeysPath)
|
|
})
|
|
|
|
it('has the correct id', async () => {
|
|
const key = await savedKeysKeyStore.getKey(id)
|
|
assert.strictEqual(identity.id, Buffer.from(key.public.marshal()).toString('hex'))
|
|
})
|
|
|
|
it('has the correct public key', async () => {
|
|
assert.strictEqual(identity.publicKey, expectedPublicKey)
|
|
})
|
|
|
|
it('has the correct identity type', async () => {
|
|
assert.strictEqual(identity.type, type)
|
|
})
|
|
|
|
it('has the correct idSignature', async () => {
|
|
assert.strictEqual(identity.signatures.id, expectedIdSignature)
|
|
})
|
|
|
|
it('has a publicKeyAndIdSignature for the publicKey', async () => {
|
|
assert.strictEqual(identity.signatures.publicKey, expectedPkIdSignature)
|
|
})
|
|
|
|
it('has the correct signatures', async () => {
|
|
const internalSigningKey = await savedKeysKeyStore.getKey(identity.id)
|
|
const externalSigningKey = await savedKeysKeyStore.getKey(id)
|
|
const idSignature = await signMessage(internalSigningKey, identity.id)
|
|
const publicKeyAndIdSignature = await signMessage(externalSigningKey, identity.publicKey + idSignature)
|
|
const expectedSignature = { id: idSignature, publicKey: publicKeyAndIdSignature }
|
|
assert.deepStrictEqual(identity.signatures, expectedSignature)
|
|
})
|
|
})
|
|
|
|
describe('verify identity\'s signature', () => {
|
|
const id = 'QmFoo'
|
|
|
|
let identities
|
|
let identity
|
|
let keystore
|
|
|
|
before(async () => {
|
|
keystore = await KeyStore({ path: testKeysPath })
|
|
})
|
|
|
|
after(async () => {
|
|
if (keystore) {
|
|
await keystore.close()
|
|
}
|
|
})
|
|
|
|
it('identity pkSignature verifies', async () => {
|
|
identities = await Identities({ keystore })
|
|
identity = await identities.createIdentity({ id, type })
|
|
const verified = await verifyMessage(identity.signatures.id, identity.publicKey, identity.id)
|
|
assert.strictEqual(verified, true)
|
|
})
|
|
|
|
it('identity signature verifies', async () => {
|
|
identities = await Identities({ keystore })
|
|
identity = await identities.createIdentity({ id, type })
|
|
const verified = await verifyMessage(identity.signatures.publicKey, identity.id, identity.publicKey + identity.signatures.id)
|
|
assert.strictEqual(verified, true)
|
|
})
|
|
|
|
it('false signature doesn\'t verify', async () => {
|
|
class IP {
|
|
async getId () { return 'pubKey' }
|
|
|
|
async signIdentity (data) { return `false signature '${data}'` }
|
|
|
|
static async verifyIdentity (data) { return false }
|
|
|
|
static get type () { return 'fake' }
|
|
}
|
|
|
|
addIdentityProvider(IP)
|
|
identity = await identities.createIdentity({ type: IP.type })
|
|
const verified = await identities.verifyIdentity(identity)
|
|
assert.strictEqual(verified, false)
|
|
})
|
|
})
|
|
|
|
describe('verify identity', () => {
|
|
const id = 'QmFoo'
|
|
|
|
let identities
|
|
let identity
|
|
let keystore
|
|
|
|
before(async () => {
|
|
keystore = await KeyStore({ path: testKeysPath })
|
|
identities = await Identities({ keystore })
|
|
})
|
|
|
|
after(async () => {
|
|
if (keystore) {
|
|
await keystore.close()
|
|
}
|
|
})
|
|
|
|
it('identity verifies', async () => {
|
|
identity = await identities.createIdentity({ id, type })
|
|
const verified = await identities.verifyIdentity(identity)
|
|
assert.strictEqual(verified, true)
|
|
})
|
|
})
|
|
|
|
describe('sign data with an identity', () => {
|
|
const id = '0x01234567890abcdefghijklmnopqrstuvwxyz'
|
|
const data = 'hello friend'
|
|
|
|
let identities
|
|
let identity
|
|
let keystore
|
|
|
|
before(async () => {
|
|
keystore = await KeyStore({ path: testKeysPath })
|
|
identities = await Identities({ keystore })
|
|
identity = await identities.createIdentity({ id })
|
|
})
|
|
|
|
after(async () => {
|
|
if (keystore) {
|
|
await keystore.close()
|
|
}
|
|
})
|
|
|
|
it('sign data', async () => {
|
|
const signingKey = await keystore.getKey(identity.id)
|
|
const expectedSignature = await signMessage(signingKey, data)
|
|
const signature = await identities.sign(identity, data, keystore)
|
|
assert.strictEqual(signature, expectedSignature)
|
|
})
|
|
|
|
it('throws an error if private key is not found from keystore', async () => {
|
|
// Remove the key from the keystore (we're using a mock storage in these tests)
|
|
const { publicKey, signatures, type } = identity
|
|
const modifiedIdentity = await Identity({ id: 'this id does not exist', publicKey, signatures, type })
|
|
let signature
|
|
let err
|
|
try {
|
|
signature = await identities.sign(modifiedIdentity, data, keystore)
|
|
} catch (e) {
|
|
err = e.toString()
|
|
}
|
|
assert.strictEqual(signature, undefined)
|
|
assert.strictEqual(err, 'Error: Private signing key not found from KeyStore')
|
|
})
|
|
})
|
|
|
|
describe('verify data signed by an identity', () => {
|
|
const id = '03602a3da3eb35f1148e8028f141ec415ef7f6d4103443edbfec2a0711d716f53f'
|
|
const data = 'hello friend'
|
|
|
|
let identities
|
|
let identity
|
|
let keystore
|
|
let signature
|
|
|
|
before(async () => {
|
|
keystore = await KeyStore({ path: testKeysPath })
|
|
})
|
|
|
|
after(async () => {
|
|
if (keystore) {
|
|
await keystore.close()
|
|
}
|
|
})
|
|
|
|
beforeEach(async () => {
|
|
identities = await Identities({ keystore })
|
|
identity = await identities.createIdentity({ id, type })
|
|
signature = await identities.sign(identity, data, keystore)
|
|
})
|
|
|
|
it('verifies that the signature is valid', async () => {
|
|
const verified = await identities.verify(signature, identity.publicKey, data)
|
|
assert.strictEqual(verified, true)
|
|
})
|
|
|
|
it('doesn\'t verify invalid signature', async () => {
|
|
const verified = await identities.verify('invalid', identity.publicKey, data)
|
|
assert.strictEqual(verified, false)
|
|
})
|
|
})
|
|
})
|