orbitdb/test/oplog/signed-log.test.js
2023-09-18 14:12:43 +01:00

174 lines
5.8 KiB
JavaScript

import { notStrictEqual, strictEqual } from 'assert'
import { rimraf } from 'rimraf'
import { copy } from 'fs-extra'
import { Log, Identities, KeyStore } from '../../src/index.js'
import testKeysPath from '../fixtures/test-keys-path.js'
const keysPath = './testkeys'
describe('Signed Log', function () {
this.timeout(5000)
let keystore
let identities
let testIdentity1, testIdentity2
before(async () => {
await copy(testKeysPath, keysPath)
keystore = await KeyStore({ path: keysPath })
identities = await Identities({ keystore })
testIdentity1 = await identities.createIdentity({ id: 'userB' })
testIdentity2 = await identities.createIdentity({ id: 'userA' })
})
after(async () => {
if (keystore) {
await keystore.close()
}
await rimraf(keysPath)
})
it('creates a signed log', async () => {
const logId = 'A'
const log = await Log(testIdentity1, { logId })
notStrictEqual(log.id, null)
strictEqual(log.id, logId)
})
// it('has the correct identity', () => {
// const log = await Log(testIdentity, { logId: 'A' })
// notStrictEqual(log.id, null)
// strictEqual(log.id, 'A')
// strictEqual(log.identity.id, '03e0480538c2a39951d054e17ff31fde487cb1031d0044a037b53ad2e028a3e77c')
// strictEqual(log.identity.publicKey, '048bef2231e64d5c7147bd4b8afb84abd4126ee8d8335e4b069ac0a65c7be711cea5c1b8d47bc20ebaecdca588600ddf2894675e78b2ef17cf49e7bbaf98080361')
// strictEqual(log.identity.signatures.id, '3045022100f5f6f10571d14347aaf34e526ce3419fd64d75ffa7aa73692cbb6aeb6fbc147102203a3e3fa41fa8fcbb9fc7c148af5b640e2f704b20b3a4e0b93fc3a6d44dffb41e')
// strictEqual(log.identity.signatures.publicKey, '3044022020982b8492be0c184dc29de0a3a3bd86a86ba997756b0bf41ddabd24b47c5acf02203745fda39d7df650a5a478e52bbe879f0cb45c074025a93471414a56077640a4')
// })
it('has the correct public key', async () => {
const log = await Log(testIdentity1, { logId: 'A' })
strictEqual(log.identity.publicKey, testIdentity1.publicKey)
})
it('has the correct pkSignature', async () => {
const log = await Log(testIdentity1, { logId: 'A' })
strictEqual(log.identity.signatures.id, testIdentity1.signatures.id)
})
it('has the correct signature', async () => {
const log = await Log(testIdentity1, { logId: 'A' })
strictEqual(log.identity.signatures.publicKey, testIdentity1.signatures.publicKey)
})
// it('entries contain an identity', async () => {
// const log = await Log(testIdentity, { logId: 'A' })
// await log.append('one')
// const values = await log.values()
// notStrictEqual(values[0].sig, null)
// deepStrictEqual(values[0].identity, testIdentity.toJSON())
// })
it('doesn\'t sign entries when identity is not defined', async () => {
let err
try {
await Log(null)
} catch (e) {
err = e
}
strictEqual(err.message, 'Identity is required')
})
it('throws an error if log is signed but trying to merge with an entry that doesn\'t have public signing key', async () => {
const log1 = await Log(testIdentity1, { logId: 'A' })
const log2 = await Log(testIdentity2, { logId: 'A' })
let err
try {
await log1.append('one')
const entry = await log2.append('two')
delete entry.key
await log1.joinEntry(entry)
} catch (e) {
err = e.toString()
}
strictEqual(err, 'Error: Entry doesn\'t have a key')
})
it('throws an error if log is signed but trying to merge an entry that doesn\'t have a signature', async () => {
const log1 = await Log(testIdentity1, { logId: 'A' })
const log2 = await Log(testIdentity2, { logId: 'A' })
let err
try {
await log1.append('one')
const entry = await log2.append('two')
delete entry.sig
await log1.joinEntry(entry)
} catch (e) {
err = e.toString()
}
strictEqual(err, 'Error: Entry doesn\'t have a signature')
})
it('throws an error if log is signed but the signature doesn\'t verify', async () => {
const log1 = await Log(testIdentity1, { logId: 'A' })
const log2 = await Log(testIdentity2, { logId: 'A' })
let err
try {
const entry1 = await log1.append('one')
const entry2 = await log2.append('two')
entry2.sig = entry1.sig
await log1.joinEntry(entry2)
} catch (e) {
err = e.toString()
}
const entry = (await log2.values())[0]
const values = await log1.values()
strictEqual(err, `Error: Could not validate signature for entry "${entry.hash}"`)
strictEqual(values.length, 1)
strictEqual(values[0].payload, 'one')
})
it('throws an error if entry doesn\'t have append access', async () => {
const denyAccess = { canAppend: () => false }
const log1 = await Log(testIdentity1, { logId: 'A' })
const log2 = await Log(testIdentity2, { logId: 'A', access: denyAccess })
let err
try {
await log1.append('one')
await log2.append('two')
await log1.join(log2)
} catch (e) {
err = e.toString()
}
strictEqual(err, `Error: Could not append entry:\nKey "${testIdentity2.hash}" is not allowed to write to the log`)
})
it('throws an error upon join if entry doesn\'t have append access', async () => {
const testACL = {
canAppend: async (entry) => {
const identity = await identities.getIdentity(entry.identity)
return identity && identity.id !== testIdentity2.id
}
}
const log1 = await Log(testIdentity1, { logId: 'A', access: testACL })
const log2 = await Log(testIdentity2, { logId: 'A' })
let err
try {
await log1.append('one')
await log2.append('two')
await log1.join(log2)
} catch (e) {
err = e.toString()
}
strictEqual(err, `Error: Could not append entry:\nKey "${testIdentity2.hash}" is not allowed to write to the log`)
})
})