orbitdb/test/orbitdb-write-access.test.js
2023-09-18 14:12:43 +01:00

308 lines
7.4 KiB
JavaScript

import { strictEqual, notStrictEqual } from 'assert'
import { rimraf } from 'rimraf'
import path from 'path'
import * as IPFS from 'ipfs-core'
import OrbitDB from '../src/orbitdb.js'
import config from './config.js'
import waitFor from './utils/wait-for.js'
import connectPeers from './utils/connect-nodes.js'
import IPFSAccessController from '../src/access-controllers/ipfs.js'
import OrbitDBAccessController from '../src/access-controllers/orbitdb.js'
const dbPath = './orbitdb/tests/write-permissions'
describe('Write Permissions', function () {
this.timeout(20000)
let ipfs1, ipfs2
let orbitdb1, orbitdb2
before(async () => {
ipfs1 = await IPFS.create({ ...config.daemon1, repo: './ipfs1' })
ipfs2 = await IPFS.create({ ...config.daemon2, repo: './ipfs2' })
await connectPeers(ipfs1, ipfs2)
orbitdb1 = await OrbitDB({ ipfs: ipfs1, id: 'user1', directory: path.join(dbPath, '1') })
orbitdb2 = await OrbitDB({ ipfs: ipfs2, id: 'user2', directory: path.join(dbPath, '2') })
})
after(async () => {
if (orbitdb1) {
await orbitdb1.stop()
}
if (orbitdb2) {
await orbitdb2.stop()
}
if (ipfs1) {
await ipfs1.stop()
}
if (ipfs2) {
await ipfs2.stop()
}
await rimraf('./orbitdb')
await rimraf('./ipfs1')
await rimraf('./ipfs2')
})
it('throws an error if another peer writes to a log with default write access', async () => {
let err
let connected = false
const onConnected = async (peerId, heads) => {
connected = true
}
const db1 = await orbitdb1.open('write-test')
const db2 = await orbitdb2.open(db1.address)
db2.events.on('join', onConnected)
await waitFor(() => connected, () => true)
await db1.add('record 1')
try {
await db2.add('record 2')
} catch (e) {
err = e.toString()
}
strictEqual(err, `Error: Could not append entry:\nKey "${db2.identity.hash}" is not allowed to write to the log`)
await db1.close()
await db2.close()
})
it('allows anyone to write to the log', async () => {
let connected = false
let updateCount = 0
const onConnected = async (peerId, heads) => {
connected = true
}
const onUpdate = async (entry) => {
++updateCount
}
const db1 = await orbitdb1.open('write-test', { AccessController: IPFSAccessController({ write: ['*'] }) })
const db2 = await orbitdb2.open(db1.address)
db2.events.on('join', onConnected)
db2.events.on('update', onUpdate)
await waitFor(() => connected, () => true)
await db1.add('record 1')
await db2.add('record 2')
await waitFor(() => updateCount === 2, () => true)
strictEqual((await db1.all()).length, (await db2.all()).length)
await db1.close()
await db2.close()
})
it('allows specific peers to write to the log', async () => {
let connected = false
let updateCount = 0
const options = {
AccessController: IPFSAccessController({
// Set write access for both clients
write: [
orbitdb1.identity.id,
orbitdb2.identity.id
]
})
}
const onConnected = async (peerId, heads) => {
connected = true
}
const onUpdate = async (entry) => {
++updateCount
}
const db1 = await orbitdb1.open('write-test', options)
const db2 = await orbitdb2.open(db1.address)
db2.events.on('join', onConnected)
db2.events.on('update', onUpdate)
await waitFor(() => connected, () => true)
await db1.add('record 1')
await db2.add('record 2')
await waitFor(() => updateCount === 2, () => true)
strictEqual((await db1.all()).length, (await db2.all()).length)
await db1.close()
await db2.close()
})
it('throws an error if peer does not have write access', async () => {
let err
let connected = false
const options = {
AccessController: IPFSAccessController({
write: [
orbitdb1.identity.id
]
})
}
const onConnected = async (peerId, heads) => {
connected = true
}
const db1 = await orbitdb1.open('write-test', options)
const db2 = await orbitdb2.open(db1.address)
db2.events.on('join', onConnected)
await waitFor(() => connected, () => true)
await db1.add('record 1')
try {
await db2.add('record 2')
} catch (e) {
err = e.toString()
}
strictEqual(err, `Error: Could not append entry:\nKey "${db2.identity.hash}" is not allowed to write to the log`)
await db1.close()
await db2.close()
})
it('uses an OrbitDB access controller to manage access - one writer', async () => {
let connected = false
let updateCount = 0
const onConnected = async (peerId, heads) => {
connected = true
}
const onUpdate = async (entry) => {
++updateCount
}
const db1 = await orbitdb1.open('write-test', { AccessController: OrbitDBAccessController() })
const db2 = await orbitdb2.open(db1.address)
db2.events.on('join', onConnected)
db2.events.on('update', onUpdate)
await waitFor(() => connected, () => true)
await db1.add('record 1')
let err
try {
await db2.add('record 2')
} catch (e) {
err = e
}
await waitFor(() => updateCount === 1, () => true)
strictEqual((await db1.all()).length, (await db2.all()).length)
notStrictEqual(err, undefined)
strictEqual(err.toString().endsWith('is not allowed to write to the log'), true)
await db1.close()
await db2.close()
})
it('uses an OrbitDB access controller to manage access - two writers', async () => {
let connected = false
let updateCount = 0
let accessUpdated = false
const onConnected = async (peerId, heads) => {
connected = true
}
const onUpdate = async (entry) => {
++updateCount
}
const onAccessUpdated = async (entry) => {
accessUpdated = true
}
const db1 = await orbitdb1.open('write-test', { AccessController: OrbitDBAccessController() })
const db2 = await orbitdb2.open(db1.address)
db2.events.on('join', onConnected)
db2.events.on('update', onUpdate)
await waitFor(() => connected, () => true)
db2.access.events.on('update', onAccessUpdated)
await db1.access.grant('write', db2.identity.id)
await waitFor(() => accessUpdated, () => true)
await db1.add('record 1')
await db2.add('record 2')
await waitFor(() => updateCount === 2, () => true)
strictEqual((await db1.all()).length, (await db2.all()).length)
await db1.close()
await db2.close()
})
it('OrbitDB access controller address is deterministic', async () => {
let connected = false
let updateCount = 0
const onConnected = async (peerId, heads) => {
connected = true
}
const onUpdate = async (entry) => {
++updateCount
}
let db1 = await orbitdb1.open('write-test', { AccessController: OrbitDBAccessController() })
let db2 = await orbitdb2.open(db1.address)
const addr = db1.address
db2.events.on('join', onConnected)
db2.events.on('update', onUpdate)
await waitFor(() => connected, () => true)
await db1.add('record 1')
await waitFor(() => updateCount === 1, () => true)
strictEqual((await db1.all()).length, (await db2.all()).length)
await db1.close()
await db2.close()
db1 = await orbitdb1.open('write-test', { AccessController: OrbitDBAccessController() })
db2 = await orbitdb2.open(db1.address)
strictEqual(db1.address, addr)
})
})