mirror of
https://github.com/orbitdb/orbitdb.git
synced 2025-10-07 22:57:07 +00:00
103 lines
3.1 KiB
JavaScript
103 lines
3.1 KiB
JavaScript
/**
|
|
* @namespace AccessControllers-IPFS
|
|
* @memberof module:AccessControllers
|
|
*/
|
|
import { IPFSBlockStorage, LRUStorage, ComposedStorage } from '../storage/index.js'
|
|
import * as Block from 'multiformats/block'
|
|
import * as dagCbor from '@ipld/dag-cbor'
|
|
import { sha256 } from 'multiformats/hashes/sha2'
|
|
import { base58btc } from 'multiformats/bases/base58'
|
|
import pathJoin from '../utils/path-join.js'
|
|
|
|
const codec = dagCbor
|
|
const hasher = sha256
|
|
const hashStringEncoding = base58btc
|
|
|
|
const AccessControlList = async ({ storage, type, params }) => {
|
|
const manifest = {
|
|
type,
|
|
...params
|
|
}
|
|
const { cid, bytes } = await Block.encode({ value: manifest, codec, hasher })
|
|
const hash = cid.toString(hashStringEncoding)
|
|
await storage.put(hash, bytes)
|
|
return hash
|
|
}
|
|
|
|
const type = 'ipfs'
|
|
|
|
/**
|
|
* Creates an instance of IPFSAccessController.
|
|
* @callback IPFSAccessController
|
|
* @param {Object} params Various parameters for configuring the access
|
|
* controller.
|
|
* @param {module:OrbitDB} params.orbitdb An OrbitDB instance.
|
|
* @param {module:Identities} params.identities An Identities instance.
|
|
* @param {string} [params.address] The address of the database.
|
|
* @function
|
|
* @instance
|
|
* @async
|
|
* @memberof module:AccessControllers.AccessControllers-IPFS
|
|
* @private
|
|
*/
|
|
|
|
/**
|
|
* Defines an IPFS access controller.
|
|
* @param {Object} options Various options for configuring the
|
|
* IPFSAccessController.
|
|
* @param {Array} [params.write] An array of identity ids who can write to the
|
|
* database.
|
|
* @param {module:Storage} [params.storage] An instance of a compatible storage.
|
|
* @return {module:AccessControllers.AccessControllers-IPFS} An
|
|
* IPFSAccessController function.
|
|
* @memberof module:AccessControllers
|
|
*/
|
|
const IPFSAccessController = ({ write, storage } = {}) => async ({ orbitdb, identities, address }) => {
|
|
storage = storage || await ComposedStorage(
|
|
await LRUStorage({ size: 1000 }),
|
|
await IPFSBlockStorage({ ipfs: orbitdb.ipfs, pin: true })
|
|
)
|
|
write = write || [orbitdb.identity.id]
|
|
|
|
if (address) {
|
|
const manifestBytes = await storage.get(address.replaceAll('/ipfs/', ''))
|
|
const { value } = await Block.decode({ bytes: manifestBytes, codec, hasher })
|
|
write = value.write
|
|
} else {
|
|
address = await AccessControlList({ storage, type, params: { write } })
|
|
address = pathJoin('/', type, address)
|
|
}
|
|
|
|
/**
|
|
* Verifies the write permission of an entry.
|
|
* @param {module:Log~Entry} entry An entry to verify.
|
|
* @return {boolean} True if the entry's identity has write permission,
|
|
* false otherwise.
|
|
* @memberof module:AccessControllers.AccessControllers-IPFS
|
|
*/
|
|
const canAppend = async (entry) => {
|
|
const writerIdentity = await identities.getIdentity(entry.identity)
|
|
if (!writerIdentity) {
|
|
return false
|
|
}
|
|
const { id } = writerIdentity
|
|
// Allow if the write access list contain the writer's id or is '*'
|
|
if (write.includes(id) || write.includes('*')) {
|
|
// Check that the identity is valid
|
|
return await identities.verifyIdentity(writerIdentity)
|
|
}
|
|
return false
|
|
}
|
|
|
|
return {
|
|
type,
|
|
address,
|
|
write,
|
|
canAppend
|
|
}
|
|
}
|
|
|
|
IPFSAccessController.type = type
|
|
|
|
export default IPFSAccessController
|