UNPKG

@orbitdb/core

Version:

Distributed p2p database on IPFS

103 lines (92 loc) 3.23 kB
/** * @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