mirror of
https://github.com/orbitdb/orbitdb.git
synced 2025-10-07 22:57:07 +00:00
Rework identity storage and usage of identity hash
This commit is contained in:
@@ -48,10 +48,8 @@ const create = async (identity, id, payload, clock = null, next = [], refs = [])
|
||||
const { bytes } = await Block.encode({ value: entry, codec, hasher })
|
||||
const signature = await identity.provider.sign(identity, bytes)
|
||||
|
||||
const { cid } = await Block.encode({ value: identity.toJSON(), codec, hasher })
|
||||
|
||||
entry.key = identity.publicKey
|
||||
entry.identity = cid.toString(hashStringEncoding)
|
||||
entry.identity = identity.hash
|
||||
entry.sig = signature
|
||||
|
||||
return _encodeEntry(entry)
|
||||
|
||||
180
src/identities/identities.js
Normal file
180
src/identities/identities.js
Normal file
@@ -0,0 +1,180 @@
|
||||
import Identity from './identity.js'
|
||||
import IdentityProvider from './identity-providers/interface.js'
|
||||
import OrbitDBIdentityProvider from './identity-providers/orbitdb.js'
|
||||
// import DIDIdentityProvider from './identity-providers/did.js'
|
||||
// import EthIdentityProvider from './identity-providers/ethereum.js'
|
||||
import Keystore from '../Keystore.js'
|
||||
import IdentityStorage from '../identity-storage.js'
|
||||
import LRU from 'lru'
|
||||
import path from 'path'
|
||||
|
||||
const defaultType = 'orbitdb'
|
||||
const identityKeysPath = path.join('./orbitdb', 'identity', 'identitykeys')
|
||||
|
||||
const supportedTypes = {
|
||||
orbitdb: OrbitDBIdentityProvider,
|
||||
// [DIDIdentityProvider.type]: DIDIdentityProvider,
|
||||
// [EthIdentityProvider.type]: EthIdentityProvider
|
||||
}
|
||||
|
||||
const getHandlerFor = (type) => {
|
||||
if (!Identities.isSupported(type)) {
|
||||
throw new Error(`IdentityProvider type '${type}' is not supported`)
|
||||
}
|
||||
return supportedTypes[type]
|
||||
}
|
||||
|
||||
class Identities {
|
||||
constructor (options) {
|
||||
this._keystore = options.keystore
|
||||
this._signingKeystore = options.signingKeystore || this._keystore
|
||||
this._knownIdentities = options.cache || new LRU(options.cacheSize || 100)
|
||||
this._storage = options.identityStore
|
||||
}
|
||||
|
||||
static get IdentityProvider () { return IdentityProvider }
|
||||
|
||||
get keystore () { return this._keystore }
|
||||
|
||||
get signingKeystore () { return this._signingKeystore }
|
||||
|
||||
async sign (identity, data) {
|
||||
const signingKey = await this.keystore.getKey(identity.id)
|
||||
if (!signingKey) {
|
||||
throw new Error('Private signing key not found from Keystore')
|
||||
}
|
||||
const sig = await this.keystore.sign(signingKey, data)
|
||||
return sig
|
||||
}
|
||||
|
||||
async verify (signature, publicKey, data, verifier = 'v1') {
|
||||
return this.keystore.verify(signature, publicKey, data, verifier)
|
||||
}
|
||||
|
||||
async createIdentity (options = {}) {
|
||||
const keystore = options.keystore || this.keystore
|
||||
const type = options.type || defaultType
|
||||
const identityProvider = type === defaultType ? new OrbitDBIdentityProvider(options.signingKeystore || keystore) : new (getHandlerFor(type))(options)
|
||||
const id = await identityProvider.getId(options)
|
||||
|
||||
if (options.migrate) {
|
||||
await options.migrate({ targetStore: keystore._store, targetId: id })
|
||||
}
|
||||
const { publicKey, idSignature } = await this.signId(id)
|
||||
const pubKeyIdSignature = await identityProvider.signIdentity(publicKey + idSignature, options)
|
||||
// return new Identity(id, publicKey, idSignature, pubKeyIdSignature, type, this)
|
||||
const identity = new Identity(id, publicKey, idSignature, pubKeyIdSignature, type, this)
|
||||
await identity.store()
|
||||
// const hash = options.identityStore.put(identity.toJSON())
|
||||
return identity
|
||||
}
|
||||
|
||||
async get (hash) {
|
||||
return this._storage.get(hash)
|
||||
}
|
||||
|
||||
async signId (id) {
|
||||
const keystore = this.keystore
|
||||
const key = await keystore.getKey(id) || await keystore.createKey(id)
|
||||
const publicKey = keystore.getPublic(key)
|
||||
const idSignature = await keystore.sign(key, id)
|
||||
return { publicKey, idSignature }
|
||||
}
|
||||
|
||||
async verifyIdentity (identity) {
|
||||
if (!Identity.isIdentity(identity)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const knownID = this._knownIdentities.get(identity.signatures.id)
|
||||
if (knownID) {
|
||||
return identity.id === knownID.id &&
|
||||
identity.publicKey === knownID.publicKey &&
|
||||
identity.signatures.id === knownID.signatures.id &&
|
||||
identity.signatures.publicKey === knownID.signatures.publicKey
|
||||
}
|
||||
|
||||
const verifyIdSig = await this.keystore.verify(
|
||||
identity.signatures.id,
|
||||
identity.publicKey,
|
||||
identity.id
|
||||
)
|
||||
if (!verifyIdSig) return false
|
||||
|
||||
const IdentityProvider = getHandlerFor(identity.type)
|
||||
const verified = await IdentityProvider.verifyIdentity(identity)
|
||||
if (verified) {
|
||||
this._knownIdentities.set(identity.signatures.id, Identity.toJSON(identity))
|
||||
}
|
||||
|
||||
return verified
|
||||
}
|
||||
|
||||
static async verifyIdentity (identity) {
|
||||
if (!Identity.isIdentity(identity)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const verifyIdSig = await Keystore.verify(
|
||||
identity.signatures.id,
|
||||
identity.publicKey,
|
||||
identity.id
|
||||
)
|
||||
|
||||
if (!verifyIdSig) return false
|
||||
|
||||
const IdentityProvider = getHandlerFor(identity.type)
|
||||
return IdentityProvider.verifyIdentity(identity)
|
||||
}
|
||||
|
||||
static async createIdentity (options = {}) {
|
||||
if (!options.keystore) {
|
||||
options.keystore = new Keystore(options.identityKeysPath || identityKeysPath)
|
||||
}
|
||||
if (!options.signingKeystore) {
|
||||
if (options.signingKeysPath) {
|
||||
options.signingKeystore = new Keystore(options.signingKeysPath)
|
||||
} else {
|
||||
options.signingKeystore = options.keystore
|
||||
}
|
||||
}
|
||||
await options.keystore.open()
|
||||
await options.signingKeystore.open()
|
||||
|
||||
let identityStore
|
||||
if (options.storage) {
|
||||
identityStore = await IdentityStorage({ storage: options.storage })
|
||||
} else if (options.ipfs) {
|
||||
identityStore = await IdentityStorage({ ipfs: options.ipfs })
|
||||
} else {
|
||||
identityStore = await IdentityStorage()
|
||||
}
|
||||
|
||||
options = Object.assign({}, { type: defaultType, identityStore }, options)
|
||||
const identities = new Identities(options)
|
||||
return identities.createIdentity(options)
|
||||
}
|
||||
|
||||
static isSupported (type) {
|
||||
return Object.keys(supportedTypes).includes(type)
|
||||
}
|
||||
|
||||
static addIdentityProvider (IdentityProvider) {
|
||||
if (!IdentityProvider) {
|
||||
throw new Error('IdentityProvider class needs to be given as an option')
|
||||
}
|
||||
|
||||
if (!IdentityProvider.type ||
|
||||
typeof IdentityProvider.type !== 'string') {
|
||||
throw new Error('Given IdentityProvider class needs to implement: static get type() { /* return a string */ }.')
|
||||
}
|
||||
|
||||
supportedTypes[IdentityProvider.type] = IdentityProvider
|
||||
}
|
||||
|
||||
static removeIdentityProvider (type) {
|
||||
delete supportedTypes[type]
|
||||
}
|
||||
}
|
||||
|
||||
export default Identities
|
||||
58
src/identities/identity-providers/did.js
Normal file
58
src/identities/identity-providers/did.js
Normal file
@@ -0,0 +1,58 @@
|
||||
import IdentityProvider from './interface.js'
|
||||
import * as u8a from 'uint8arrays'
|
||||
import { DID } from 'dids'
|
||||
|
||||
const TYPE = 'DID'
|
||||
|
||||
class DIDIdentityProvider extends IdentityProvider {
|
||||
constructor ({ didProvider }) {
|
||||
super()
|
||||
this.did = new DID({
|
||||
resolver: DIDIdentityProvider.did._resolver,
|
||||
provider: didProvider
|
||||
})
|
||||
}
|
||||
|
||||
static get type () {
|
||||
return TYPE
|
||||
}
|
||||
|
||||
async getId ({ space }) {
|
||||
if (!this.did.authenticated) await this.did.authenticate()
|
||||
return this.did.id
|
||||
}
|
||||
|
||||
async signIdentity (data, { space }) {
|
||||
if (!this.did.authenticated) await this.did.authenticate()
|
||||
const payload = u8a.toString(u8a.fromString(data, 'base16'), 'base64url')
|
||||
const jws = await this.did.createJWS(payload)
|
||||
// encode as JWS with detached payload
|
||||
return `${jws.signatures[0].protected}..${jws.signatures[0].signature}`
|
||||
}
|
||||
|
||||
static setDIDResolver (resolver) {
|
||||
if (!this.did) {
|
||||
this.did = new DID({ resolver })
|
||||
} else {
|
||||
this.did.setResolver(resolver)
|
||||
}
|
||||
}
|
||||
|
||||
static async verifyIdentity (identity) {
|
||||
if (!this.did) {
|
||||
throw new Error('The DID resolver must first be set with setDIDResolver()')
|
||||
}
|
||||
const data = identity.publicKey + identity.signatures.id
|
||||
try {
|
||||
const payload = u8a.toString(u8a.fromString(data, 'base16'), 'base64url')
|
||||
const [header, signature] = identity.signatures.publicKey.split('..')
|
||||
const jws = [header, payload, signature].join('.')
|
||||
await this.did.verifyJWS(jws)
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export default DIDIdentityProvider
|
||||
56
src/identities/identity-providers/ethereum.js
Normal file
56
src/identities/identity-providers/ethereum.js
Normal file
@@ -0,0 +1,56 @@
|
||||
import IdentityProvider from './interface.js'
|
||||
import { Wallet, verifyMessage } from '@ethersproject/wallet'
|
||||
const type = 'ethereum'
|
||||
|
||||
class EthIdentityProvider extends IdentityProvider {
|
||||
constructor (options = {}) {
|
||||
super()
|
||||
this.wallet = options.wallet
|
||||
}
|
||||
|
||||
// Returns the type of the identity provider
|
||||
static get type () { return type }
|
||||
|
||||
// Returns the signer's id
|
||||
async getId (options = {}) {
|
||||
if (!this.wallet) {
|
||||
this.wallet = await this._createWallet(options)
|
||||
}
|
||||
return this.wallet.getAddress()
|
||||
}
|
||||
|
||||
// Returns a signature of pubkeysignature
|
||||
async signIdentity (data, options = {}) {
|
||||
const wallet = this.wallet
|
||||
if (!wallet) { throw new Error('wallet is required') }
|
||||
|
||||
return wallet.signMessage(data)
|
||||
}
|
||||
|
||||
static async verifyIdentity (identity) {
|
||||
// Verify that identity was signed by the id
|
||||
const signerAddress = verifyMessage(identity.publicKey + identity.signatures.id, identity.signatures.publicKey)
|
||||
return (signerAddress === identity.id)
|
||||
}
|
||||
|
||||
async _createWallet (options = {}) {
|
||||
if (options.mnemonicOpts) {
|
||||
if (!options.mnemonicOpts.mnemonic) {
|
||||
throw new Error('mnemonic is required')
|
||||
}
|
||||
return Wallet.fromMnemonic(options.mnemonicOpts.mnemonic, options.mnemonicOpts.path, options.mnemonicOpts.wordlist)
|
||||
}
|
||||
if (options.encryptedJsonOpts) {
|
||||
if (!options.encryptedJsonOpts.json) {
|
||||
throw new Error('encrypted json is required')
|
||||
}
|
||||
if (!options.encryptedJsonOpts.password) {
|
||||
throw new Error('password for encrypted json is required')
|
||||
}
|
||||
return Wallet.fromEncryptedJson(options.encryptedJsonOpts.json, options.encryptedJsonOpts.password, options.encryptedJsonOpts.progressCallback)
|
||||
}
|
||||
return Wallet.createRandom()
|
||||
}
|
||||
}
|
||||
|
||||
export default EthIdentityProvider
|
||||
26
src/identities/identity-providers/interface.js
Normal file
26
src/identities/identity-providers/interface.js
Normal file
@@ -0,0 +1,26 @@
|
||||
class IdentityProvider {
|
||||
/* Return id of identity (to be signed by orbit-db public key) */
|
||||
async getId (options) {}
|
||||
|
||||
/* Return signature of OrbitDB public key signature */
|
||||
async signIdentity (data, options) {}
|
||||
|
||||
/* Verify a signature of OrbitDB public key signature */
|
||||
static async verifyIdentity (identity) {}
|
||||
|
||||
/* Return the type for this identity provider */
|
||||
static get type () {
|
||||
throw new Error('\'static get type ()\' needs to be defined in the inheriting class')
|
||||
}
|
||||
|
||||
/*
|
||||
Return the type for this identity-procider
|
||||
NOTE! This is the only property of the interface that
|
||||
shouldn't be overridden in the inherited IdentityProvider
|
||||
*/
|
||||
get type () {
|
||||
return this.constructor.type
|
||||
}
|
||||
}
|
||||
|
||||
export default IdentityProvider
|
||||
52
src/identities/identity-providers/orbitdb.js
Normal file
52
src/identities/identity-providers/orbitdb.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import IdentityProvider from './interface.js'
|
||||
import Keystore from '../../Keystore.js'
|
||||
const type = 'orbitdb'
|
||||
|
||||
class OrbitDBIdentityProvider extends IdentityProvider {
|
||||
constructor (keystore) {
|
||||
super()
|
||||
if (!keystore) {
|
||||
throw new Error('OrbitDBIdentityProvider requires a keystore')
|
||||
}
|
||||
this._keystore = keystore
|
||||
}
|
||||
|
||||
// Returns the type of the identity provider
|
||||
static get type () { return type }
|
||||
|
||||
async getId (options = {}) {
|
||||
const id = options.id
|
||||
if (!id) {
|
||||
throw new Error('id is required')
|
||||
}
|
||||
|
||||
const keystore = this._keystore
|
||||
const key = await keystore.getKey(id) || await keystore.createKey(id)
|
||||
return Buffer.from(key.public.marshal()).toString('hex')
|
||||
}
|
||||
|
||||
async signIdentity (data, options = {}) {
|
||||
const id = options.id
|
||||
if (!id) {
|
||||
throw new Error('id is required')
|
||||
}
|
||||
const keystore = this._keystore
|
||||
const key = await keystore.getKey(id)
|
||||
if (!key) {
|
||||
throw new Error(`Signing key for '${id}' not found`)
|
||||
}
|
||||
|
||||
return keystore.sign(key, data)
|
||||
}
|
||||
|
||||
static async verifyIdentity (identity) {
|
||||
// Verify that identity was signed by the ID
|
||||
return Keystore.verify(
|
||||
identity.signatures.publicKey,
|
||||
identity.id,
|
||||
identity.publicKey + identity.signatures.id
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default OrbitDBIdentityProvider
|
||||
94
src/identities/identity.js
Normal file
94
src/identities/identity.js
Normal file
@@ -0,0 +1,94 @@
|
||||
import isDefined from './is-defined.js'
|
||||
|
||||
class Identity {
|
||||
constructor (id, publicKey, idSignature, pubKeyIdSignature, type, provider) {
|
||||
if (!isDefined(id)) {
|
||||
throw new Error('Identity id is required')
|
||||
}
|
||||
|
||||
if (!isDefined(publicKey)) {
|
||||
throw new Error('Invalid public key')
|
||||
}
|
||||
|
||||
if (!isDefined(idSignature)) {
|
||||
throw new Error('Signature of the id (idSignature) is required')
|
||||
}
|
||||
|
||||
if (!isDefined(pubKeyIdSignature)) {
|
||||
throw new Error('Signature of (publicKey + idSignature) is required')
|
||||
}
|
||||
|
||||
if (!isDefined(type)) {
|
||||
throw new Error('Identity type is required')
|
||||
}
|
||||
|
||||
if (!isDefined(provider)) {
|
||||
throw new Error('Identity provider is required')
|
||||
}
|
||||
|
||||
this._id = id
|
||||
this._publicKey = publicKey
|
||||
this._signatures = Object.assign({}, { id: idSignature }, { publicKey: pubKeyIdSignature })
|
||||
this._type = type
|
||||
this._provider = provider
|
||||
this.hash = null
|
||||
}
|
||||
|
||||
async store () {
|
||||
const value = this.toJSON()
|
||||
this.hash = await this._provider._storage.put(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* This is only used as a fallback to the clock id when necessary
|
||||
* @return {string} public key hex encoded
|
||||
*/
|
||||
get id () {
|
||||
return this._id
|
||||
}
|
||||
|
||||
get publicKey () {
|
||||
return this._publicKey
|
||||
}
|
||||
|
||||
get signatures () {
|
||||
return this._signatures
|
||||
}
|
||||
|
||||
get type () {
|
||||
return this._type
|
||||
}
|
||||
|
||||
get provider () {
|
||||
return this._provider
|
||||
}
|
||||
|
||||
toJSON () {
|
||||
return {
|
||||
id: this.id,
|
||||
publicKey: this.publicKey,
|
||||
signatures: this.signatures,
|
||||
type: this.type
|
||||
}
|
||||
}
|
||||
|
||||
static isIdentity (identity) {
|
||||
return identity.id !== undefined &&
|
||||
identity.publicKey !== undefined &&
|
||||
identity.signatures !== undefined &&
|
||||
identity.signatures.id !== undefined &&
|
||||
identity.signatures.publicKey !== undefined &&
|
||||
identity.type !== undefined
|
||||
}
|
||||
|
||||
static toJSON (identity) {
|
||||
return {
|
||||
id: identity.id,
|
||||
publicKey: identity.publicKey,
|
||||
signatures: identity.signatures,
|
||||
type: identity.type
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Identity
|
||||
1
src/identities/is-defined.js
Normal file
1
src/identities/is-defined.js
Normal file
@@ -0,0 +1 @@
|
||||
export default (arg) => arg !== undefined && arg !== null
|
||||
@@ -1,5 +1,6 @@
|
||||
import Entry from './entry.js'
|
||||
import IPFSBlockStorage from './ipfs-block-storage.js'
|
||||
import MemoryStorage from './memory-storage.js'
|
||||
import * as dagCbor from '@ipld/dag-cbor'
|
||||
import { sha256 } from 'multiformats/hashes/sha2'
|
||||
import { base58btc } from 'multiformats/bases/base58'
|
||||
@@ -8,10 +9,18 @@ import * as Block from 'multiformats/block'
|
||||
const codec = dagCbor
|
||||
const hasher = sha256
|
||||
|
||||
const IdentityStorage = async ({ storage }) => {
|
||||
const put = async (identity) => {
|
||||
const { cid, bytes } = await Block.encode({ value: identity.toJSON(), codec, hasher })
|
||||
await storage.put(cid.toString(base58btc), bytes)
|
||||
const IdentityStorage = async ({ ipfs, storage } = {}) => {
|
||||
storage = storage
|
||||
? storage
|
||||
: ipfs
|
||||
? await IPFSBlockStorage({ ipfs, pin: true })
|
||||
: await MemoryStorage()
|
||||
|
||||
const put = async (value) => {
|
||||
const { cid, bytes } = await Block.encode({ value, codec, hasher })
|
||||
const hash = cid.toString(base58btc)
|
||||
await storage.put(hash, bytes)
|
||||
return hash
|
||||
}
|
||||
|
||||
const get = async (hash) => {
|
||||
|
||||
@@ -8,7 +8,6 @@ import MemoryStorage from './memory-storage.js'
|
||||
import LRUStorage from './lru-storage.js'
|
||||
import LevelStorage from './level-storage.js'
|
||||
import ComposedStorage from './composed-storage.js'
|
||||
import IdentityStorage from './identity-storage.js'
|
||||
import { isDefined } from './utils/index.js'
|
||||
|
||||
const { LastWriteWins, NoZeroes } = Sorting
|
||||
@@ -156,7 +155,7 @@ const Log = async (identity, { logId, logHeads, access, entryStorage, headsStora
|
||||
// Authorize the entry
|
||||
const canAppend = await access.canAppend(entry, identity.provider)
|
||||
if (!canAppend) {
|
||||
throw new Error(`Could not append entry:\nKey "${identity.id}" is not allowed to write to the log`)
|
||||
throw new Error(`Could not append entry:\nKey "${identity.hash}" is not allowed to write to the log`)
|
||||
}
|
||||
|
||||
// The appended entry is now the latest head
|
||||
@@ -217,7 +216,7 @@ const Log = async (identity, { logId, logHeads, access, entryStorage, headsStora
|
||||
// Verify if entry is allowed to be added to the log
|
||||
const canAppend = await access.canAppend(entry, identityProvider)
|
||||
if (!canAppend) {
|
||||
throw new Error(`Could not append entry:\nKey "${entry.identity.id}" is not allowed to write to the log`)
|
||||
throw new Error(`Could not append entry:\nKey "${entry.identity}" is not allowed to write to the log`)
|
||||
}
|
||||
// Verify signature for the entry
|
||||
const isValid = await Entry.verify(identityProvider, entry)
|
||||
@@ -465,4 +464,4 @@ export { Log }
|
||||
export { Sorting }
|
||||
export { Entry }
|
||||
export { DefaultAccessController }
|
||||
export { IPFSBlockStorage, MemoryStorage, LRUStorage, LevelStorage, ComposedStorage, IdentityStorage }
|
||||
export { IPFSBlockStorage, MemoryStorage, LRUStorage, LevelStorage, ComposedStorage }
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import { deepStrictEqual, strictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import * as Log from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
|
||||
import Documents from '../src/documents.js'
|
||||
import Database from '../src/database.js'
|
||||
|
||||
// Test utils
|
||||
import { config, testAPIs, getIpfsPeerId, waitForPeers, startIpfs, stopIpfs } from 'orbit-db-test-utils'
|
||||
// import { config, testAPIs, getIpfsPeerId, waitForPeers, startIpfs, stopIpfs } from 'orbit-db-test-utils'
|
||||
import { config, testAPIs, startIpfs, stopIpfs } from 'orbit-db-test-utils'
|
||||
import connectPeers from './utils/connect-nodes.js'
|
||||
import waitFor from './utils/wait-for.js'
|
||||
import { identityKeys, signingKeys } from './fixtures/orbit-db-identity-keys.js'
|
||||
import { identityKeys, signingKeys, createTestIdentities, cleanUpTestIdentities } from './fixtures/orbit-db-identity-keys.js'
|
||||
|
||||
const { sync: rmrf } = rimraf
|
||||
const { createIdentity } = IdentityProvider
|
||||
@@ -23,16 +23,13 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
let ipfsd1, ipfsd2
|
||||
let ipfs1, ipfs2
|
||||
let keystore, signingKeystore
|
||||
let peerId1, peerId2
|
||||
// let peerId1, peerId2
|
||||
let testIdentity1, testIdentity2
|
||||
let db1, db2
|
||||
|
||||
const databaseId = 'documents-AAA'
|
||||
|
||||
before(async () => {
|
||||
rmrf('./keys_1')
|
||||
rmrf('./keys_2')
|
||||
|
||||
// Start two IPFS instances
|
||||
ipfsd1 = await startIpfs(IPFS, config.daemon1)
|
||||
ipfsd2 = await startIpfs(IPFS, config.daemon2)
|
||||
@@ -42,27 +39,42 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
await connectPeers(ipfs1, ipfs2)
|
||||
|
||||
// Get the peer IDs
|
||||
peerId1 = await getIpfsPeerId(ipfs1)
|
||||
peerId2 = await getIpfsPeerId(ipfs2)
|
||||
// peerId1 = await getIpfsPeerId(ipfs1)
|
||||
// peerId2 = await getIpfsPeerId(ipfs2)
|
||||
|
||||
keystore = new Keystore('./keys_1')
|
||||
await keystore.open()
|
||||
for (const [key, value] of Object.entries(identityKeys)) {
|
||||
await keystore.addKey(key, value)
|
||||
const testIdentities = await createTestIdentities(ipfs1, ipfs2)
|
||||
testIdentity1 = testIdentities[0]
|
||||
testIdentity2 = testIdentities[1]
|
||||
|
||||
rmrf(testIdentity1.id)
|
||||
rmrf(testIdentity2.id)
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
const accessController = {
|
||||
canAppend: async (entry) => {
|
||||
const identity = await testIdentity1.provider.get(entry.identity)
|
||||
return identity.id === testIdentity1.id
|
||||
}
|
||||
}
|
||||
|
||||
signingKeystore = new Keystore('./keys_2')
|
||||
await signingKeystore.open()
|
||||
for (const [key, value] of Object.entries(signingKeys)) {
|
||||
await signingKeystore.addKey(key, value)
|
||||
}
|
||||
db1 = await Documents({ OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController })
|
||||
})
|
||||
|
||||
// Create an identity for each peers
|
||||
testIdentity1 = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
||||
testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore })
|
||||
afterEach(async () => {
|
||||
if (db1) {
|
||||
await db1.drop()
|
||||
await db1.close()
|
||||
}
|
||||
if (db2) {
|
||||
await db2.drop()
|
||||
await db2.close()
|
||||
}
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
await cleanUpTestIdentities([testIdentity1, testIdentity2])
|
||||
|
||||
if (ipfsd1) {
|
||||
await stopIpfs(ipfsd1)
|
||||
}
|
||||
@@ -86,30 +98,7 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
rmrf('./keys_2')
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
if (db1) {
|
||||
await db1.close()
|
||||
}
|
||||
if (db2) {
|
||||
await db2.close()
|
||||
}
|
||||
})
|
||||
|
||||
describe('using database', () => {
|
||||
beforeEach(async () => {
|
||||
const accessController = {
|
||||
canAppend: (entry) => entry.identity.id === testIdentity1.id
|
||||
}
|
||||
|
||||
db1 = await Documents({ OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController })
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
if (db1) {
|
||||
await db1.drop()
|
||||
}
|
||||
})
|
||||
|
||||
it('gets a document', async () => {
|
||||
const key = 'hello world 1'
|
||||
|
||||
@@ -158,139 +147,5 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
deepStrictEqual(await db1.query(findFn), [expected])
|
||||
})
|
||||
})
|
||||
|
||||
describe('replicate database', () => {
|
||||
it('returns all entries in the database', async () => {
|
||||
let updateCount = 0
|
||||
|
||||
const accessController = {
|
||||
canAppend: (entry) => entry.identity.id === testIdentity1.id
|
||||
}
|
||||
|
||||
const onUpdate = (entry) => {
|
||||
++updateCount
|
||||
}
|
||||
|
||||
const onError = () => {
|
||||
}
|
||||
|
||||
db1 = await Documents({ OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController })
|
||||
db2 = await Documents({ OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController })
|
||||
|
||||
db2.events.on('update', onUpdate)
|
||||
db2.events.on('error', onError)
|
||||
|
||||
strictEqual(db1.type, 'documents')
|
||||
strictEqual(db2.type, 'documents')
|
||||
|
||||
await waitForPeers(ipfs1, [peerId2], databaseId)
|
||||
await waitForPeers(ipfs2, [peerId1], databaseId)
|
||||
|
||||
await db1.put({ _id: "init", value: true })
|
||||
await db1.put({ _id: "init", value: false })
|
||||
await db1.put({ _id: "hello", text: "friend" })
|
||||
await db1.del("hello")
|
||||
await db1.put({ _id: "hello", text: "friend2" })
|
||||
await db1.put({ _id: "empty" })
|
||||
await db1.del("empty")
|
||||
await db1.put({ _id: "hello", text: "friend3" })
|
||||
|
||||
await waitFor(() => updateCount, () => 8)
|
||||
|
||||
strictEqual(updateCount, 8)
|
||||
|
||||
const documents2 = []
|
||||
console.time('documents2')
|
||||
for await (const event of db2.iterator()) {
|
||||
documents2.unshift(event)
|
||||
}
|
||||
console.timeEnd('documents2')
|
||||
deepStrictEqual(documents2, [
|
||||
{ _id: "init", value: false },
|
||||
{ _id: "hello", text: "friend3" }
|
||||
])
|
||||
|
||||
const documents1 = []
|
||||
console.time('documents1')
|
||||
for await (const event of db1.iterator()) {
|
||||
documents1.unshift(event)
|
||||
}
|
||||
console.timeEnd('documents1')
|
||||
deepStrictEqual(documents1, [
|
||||
{ _id: "init", value: false },
|
||||
{ _id: "hello", text: "friend3" }
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
describe('load database', () => {
|
||||
it('returns all entries in the database', async () => {
|
||||
let updateCount = 0
|
||||
|
||||
const accessController = {
|
||||
canAppend: (entry) => entry.identity.id === testIdentity1.id
|
||||
}
|
||||
|
||||
const onUpdate = (entry) => {
|
||||
++updateCount
|
||||
}
|
||||
|
||||
const onError = () => {
|
||||
}
|
||||
|
||||
db1 = await Documents({ OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController })
|
||||
db2 = await Documents({ OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController })
|
||||
|
||||
db2.events.on('update', onUpdate)
|
||||
db2.events.on('error', onError)
|
||||
|
||||
strictEqual(db1.type, 'documents')
|
||||
strictEqual(db2.type, 'documents')
|
||||
|
||||
await waitForPeers(ipfs1, [peerId2], databaseId)
|
||||
await waitForPeers(ipfs2, [peerId1], databaseId)
|
||||
|
||||
await db1.put({ _id: "init", value: true })
|
||||
await db1.put({ _id: "init", value: false })
|
||||
await db1.put({ _id: "hello", text: "friend" })
|
||||
await db1.del("hello")
|
||||
await db1.put({ _id: "hello", text: "friend2" })
|
||||
await db1.put({ _id: "empty" })
|
||||
await db1.del("empty")
|
||||
await db1.put({ _id: "hello", text: "friend3" })
|
||||
|
||||
await waitFor(() => updateCount, () => 8)
|
||||
|
||||
strictEqual(updateCount, 8)
|
||||
|
||||
await db1.close()
|
||||
await db2.close()
|
||||
|
||||
db1 = await Documents({ OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController })
|
||||
db2 = await Documents({ OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController })
|
||||
|
||||
const documents2 = []
|
||||
console.time('documents2')
|
||||
for await (const event of db2.iterator()) {
|
||||
documents2.unshift(event)
|
||||
}
|
||||
console.timeEnd('documents2')
|
||||
deepStrictEqual(documents2, [
|
||||
{ _id: "init", value: false },
|
||||
{ _id: "hello", text: "friend3" }
|
||||
])
|
||||
|
||||
const documents1 = []
|
||||
console.time('documents1')
|
||||
for await (const event of db1.iterator()) {
|
||||
documents1.unshift(event)
|
||||
}
|
||||
console.timeEnd('documents1')
|
||||
deepStrictEqual(documents1, [
|
||||
{ _id: "init", value: false },
|
||||
{ _id: "hello", text: "friend3" }
|
||||
])
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2,11 +2,11 @@ import { strictEqual, deepStrictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import { copy } from 'fs-extra'
|
||||
import Entry from '../src/entry.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
import { config, testAPIs, startIpfs, stopIpfs } from 'orbit-db-test-utils'
|
||||
import IdentityStorage from '../src/identity-storage.js'
|
||||
import IPFSBlockStorage from '../src/ipfs-block-storage.js'
|
||||
// import IdentityStorage from '../src/identity-storage.js'
|
||||
// import IPFSBlockStorage from '../src/ipfs-block-storage.js'
|
||||
|
||||
const { sync: rmrf } = rimraf
|
||||
const { createIdentity } = IdentityProvider
|
||||
@@ -32,10 +32,7 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
keystore = new Keystore(identityKeysPath)
|
||||
signingKeystore = new Keystore(signingKeysPath)
|
||||
|
||||
ipfsBlockStore = await IPFSBlockStorage({ ipfs, pin: true })
|
||||
identityStore = await IdentityStorage({ storage: ipfsBlockStore })
|
||||
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore, identityStore })
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore, ipfs })
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
@@ -79,7 +76,7 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
// strictEqual(entry.hash, expectedHash)
|
||||
})
|
||||
|
||||
it('retrieves the identity from an entry', async() => {
|
||||
it.skip('retrieves the identity from an entry', async() => {
|
||||
const expected = testIdentity.toJSON()
|
||||
const payload = 'hello world'
|
||||
const entry = await create(testIdentity, 'A', payload)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { deepStrictEqual, strictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import * as Log from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
|
||||
import EventStore from '../src/events.js'
|
||||
@@ -11,7 +11,7 @@ import Database from '../src/database.js'
|
||||
import { config, testAPIs, startIpfs, stopIpfs, getIpfsPeerId, waitForPeers } from 'orbit-db-test-utils'
|
||||
import connectPeers from './utils/connect-nodes.js'
|
||||
import waitFor from './utils/wait-for.js'
|
||||
import { identityKeys, signingKeys } from './fixtures/orbit-db-identity-keys.js'
|
||||
import { identityKeys, signingKeys, createTestIdentities, cleanUpTestIdentities } from './fixtures/orbit-db-identity-keys.js'
|
||||
|
||||
const { sync: rmrf } = rimraf
|
||||
const { createIdentity } = IdentityProvider
|
||||
@@ -30,9 +30,6 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
const databaseId = 'events-AAA'
|
||||
|
||||
before(async () => {
|
||||
rmrf('./keys_1')
|
||||
rmrf('./keys_2')
|
||||
|
||||
// Start two IPFS instances
|
||||
ipfsd1 = await startIpfs(IPFS, config.daemon1)
|
||||
ipfsd2 = await startIpfs(IPFS, config.daemon2)
|
||||
@@ -45,21 +42,9 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
peerId1 = await getIpfsPeerId(ipfs1)
|
||||
peerId2 = await getIpfsPeerId(ipfs2)
|
||||
|
||||
keystore = new Keystore('./keys_1')
|
||||
await keystore.open()
|
||||
for (const [key, value] of Object.entries(identityKeys)) {
|
||||
await keystore.addKey(key, value)
|
||||
}
|
||||
|
||||
signingKeystore = new Keystore('./keys_2')
|
||||
await signingKeystore.open()
|
||||
for (const [key, value] of Object.entries(signingKeys)) {
|
||||
await signingKeystore.addKey(key, value)
|
||||
}
|
||||
|
||||
// Create an identity for each peers
|
||||
testIdentity1 = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
||||
testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore })
|
||||
const testIdentities = await createTestIdentities(ipfs1, ipfs2)
|
||||
testIdentity1 = testIdentities[0]
|
||||
testIdentity2 = testIdentities[1]
|
||||
|
||||
rmrf(testIdentity1.id)
|
||||
rmrf(testIdentity2.id)
|
||||
@@ -77,6 +62,8 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
await cleanUpTestIdentities([testIdentity1, testIdentity2])
|
||||
|
||||
if (ipfsd1) {
|
||||
await stopIpfs(ipfsd1)
|
||||
}
|
||||
@@ -106,7 +93,10 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
// let syncCount = 0
|
||||
|
||||
const accessController = {
|
||||
canAppend: (entry) => entry.identity.id === testIdentity1.id
|
||||
canAppend: async (entry) => {
|
||||
const identity = await testIdentity1.provider.get(entry.identity)
|
||||
return identity.id === testIdentity1.id
|
||||
}
|
||||
}
|
||||
|
||||
const onUpdate = (entry) => {
|
||||
@@ -214,7 +204,10 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
// let syncCount = 0
|
||||
|
||||
const accessController = {
|
||||
canAppend: (entry) => entry.identity.id === testIdentity1.id
|
||||
canAppend: async (entry) => {
|
||||
const identity = await testIdentity1.provider.get(entry.identity)
|
||||
return identity.id === testIdentity1.id
|
||||
}
|
||||
}
|
||||
|
||||
const onUpdate = (entry) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { deepStrictEqual, strictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import * as Log from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
|
||||
import Feed from '../src/feed.js'
|
||||
@@ -11,7 +11,7 @@ import Database from '../src/database.js'
|
||||
import { config, testAPIs, getIpfsPeerId, waitForPeers, startIpfs, stopIpfs } from 'orbit-db-test-utils'
|
||||
import connectPeers from './utils/connect-nodes.js'
|
||||
import waitFor from './utils/wait-for.js'
|
||||
import { identityKeys, signingKeys } from './fixtures/orbit-db-identity-keys.js'
|
||||
import { identityKeys, signingKeys, createTestIdentities, cleanUpTestIdentities } from './fixtures/orbit-db-identity-keys.js'
|
||||
|
||||
const { sync: rmrf } = rimraf
|
||||
const { createIdentity } = IdentityProvider
|
||||
@@ -42,21 +42,9 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
peerId1 = await getIpfsPeerId(ipfs1)
|
||||
peerId2 = await getIpfsPeerId(ipfs2)
|
||||
|
||||
keystore = new Keystore('./keys_1')
|
||||
await keystore.open()
|
||||
for (const [key, value] of Object.entries(identityKeys)) {
|
||||
await keystore.addKey(key, value)
|
||||
}
|
||||
|
||||
signingKeystore = new Keystore('./keys_2')
|
||||
await signingKeystore.open()
|
||||
for (const [key, value] of Object.entries(signingKeys)) {
|
||||
await signingKeystore.addKey(key, value)
|
||||
}
|
||||
|
||||
// Create an identity for each peers
|
||||
testIdentity1 = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
||||
testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore })
|
||||
const testIdentities = await createTestIdentities(ipfs1, ipfs2)
|
||||
testIdentity1 = testIdentities[0]
|
||||
testIdentity2 = testIdentities[1]
|
||||
|
||||
rmrf(testIdentity1.id)
|
||||
rmrf(testIdentity2.id)
|
||||
@@ -74,6 +62,8 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
await cleanUpTestIdentities([testIdentity1, testIdentity2])
|
||||
|
||||
if (ipfsd1) {
|
||||
await stopIpfs(ipfsd1)
|
||||
}
|
||||
@@ -103,7 +93,10 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
// let syncCount = 0
|
||||
|
||||
const accessController = {
|
||||
canAppend: (entry) => entry.identity.id === testIdentity1.id
|
||||
canAppend: async (entry) => {
|
||||
const identity = await testIdentity1.provider.get(entry.identity)
|
||||
return identity.id === testIdentity1.id
|
||||
}
|
||||
}
|
||||
|
||||
const onUpdate = (entry) => {
|
||||
@@ -210,7 +203,10 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
// let syncCount = 0
|
||||
|
||||
const accessController = {
|
||||
canAppend: (entry) => entry.identity.id === testIdentity1.id
|
||||
canAppend: async (entry) => {
|
||||
const identity = await testIdentity1.provider.get(entry.identity)
|
||||
return identity.id === testIdentity1.id
|
||||
}
|
||||
}
|
||||
|
||||
const onUpdate = (entry) => {
|
||||
|
||||
64
test/fixtures/orbit-db-identity-keys.js
vendored
64
test/fixtures/orbit-db-identity-keys.js
vendored
@@ -1,3 +1,10 @@
|
||||
import Keystore from '../../src/Keystore.js'
|
||||
import IdentityProvider from '../../src/identities/identities.js'
|
||||
import rimraf from 'rimraf'
|
||||
|
||||
const { createIdentity } = IdentityProvider
|
||||
const { sync: rmrf } = rimraf
|
||||
|
||||
import userA from "./keys/identity-keys/03e0480538c2a39951d054e17ff31fde487cb1031d0044a037b53ad2e028a3e77c.json" assert { type: "json" }
|
||||
import userB from "./keys/identity-keys/0358df8eb5def772917748fdf8a8b146581ad2041eae48d66cc6865f11783499a6.json" assert { type: "json" }
|
||||
import userC from "./keys/identity-keys/032f7b6ef0432b572b45fcaf27e7f6757cd4123ff5c5266365bec82129b8c5f214.json" assert { type: "json" }
|
||||
@@ -22,7 +29,62 @@ const signingKeys = {
|
||||
userD: userD_,
|
||||
}
|
||||
|
||||
const createTestIdentities = async (ipfs1, ipfs2) => {
|
||||
rmrf('./keys_1')
|
||||
rmrf('./keys_2')
|
||||
|
||||
const keystore = new Keystore('./keys_1')
|
||||
await keystore.open()
|
||||
for (const [key, value] of Object.entries(identityKeys)) {
|
||||
await keystore.addKey(key, value)
|
||||
}
|
||||
|
||||
const signingKeystore = new Keystore('./keys_2')
|
||||
await signingKeystore.open()
|
||||
for (const [key, value] of Object.entries(signingKeys)) {
|
||||
await signingKeystore.addKey(key, value)
|
||||
}
|
||||
|
||||
// Create an identity for each peers
|
||||
const testIdentity1 = await createIdentity({ id: 'userA', keystore, signingKeystore, ipfs: ipfs1 })
|
||||
const testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore, ipfs: ipfs2 })
|
||||
|
||||
return [testIdentity1, testIdentity2]
|
||||
}
|
||||
|
||||
const createTestIdentitiesInMemory = async (ipfs1 = null, ipfs2 = null) => {
|
||||
rmrf('./keys_1')
|
||||
rmrf('./keys_2')
|
||||
|
||||
const keystore = new Keystore('./keys_1')
|
||||
// await keystore.open()
|
||||
for (const [key, value] of Object.entries(identityKeys)) {
|
||||
await keystore.addKey(key, value)
|
||||
}
|
||||
|
||||
const signingKeystore = new Keystore('./keys_2')
|
||||
// await signingKeystore.open()
|
||||
for (const [key, value] of Object.entries(signingKeys)) {
|
||||
await signingKeystore.addKey(key, value)
|
||||
}
|
||||
|
||||
// Create an identity for each peers
|
||||
const testIdentity1 = await createIdentity({ id: 'userA', keystore, signingKeystore, ipfs: ipfs1 })
|
||||
const testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore, ipfs: ipfs2 })
|
||||
|
||||
return [testIdentity1, testIdentity2]
|
||||
}
|
||||
|
||||
const cleanUpTestIdentities = async (identities) => {
|
||||
for (let identity of identities) {
|
||||
await identity.provider._keystore.close()
|
||||
await identity.provider._signingKeystore.close()
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
identityKeys,
|
||||
signingKeys
|
||||
signingKeys,
|
||||
createTestIdentities,
|
||||
cleanUpTestIdentities
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { deepStrictEqual, strictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import * as Log from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
|
||||
import KeyValueStore from '../src/kv.js'
|
||||
@@ -12,7 +12,7 @@ import Database from '../src/database.js'
|
||||
import { config, testAPIs, getIpfsPeerId, waitForPeers, startIpfs, stopIpfs } from 'orbit-db-test-utils'
|
||||
import connectPeers from './utils/connect-nodes.js'
|
||||
import waitFor from './utils/wait-for.js'
|
||||
import { identityKeys, signingKeys } from './fixtures/orbit-db-identity-keys.js'
|
||||
import { identityKeys, signingKeys, createTestIdentities, cleanUpTestIdentities } from './fixtures/orbit-db-identity-keys.js'
|
||||
|
||||
const { sync: rmrf } = rimraf
|
||||
const { createIdentity } = IdentityProvider
|
||||
@@ -43,27 +43,17 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
peerId1 = await getIpfsPeerId(ipfs1)
|
||||
peerId2 = await getIpfsPeerId(ipfs2)
|
||||
|
||||
keystore = new Keystore('./keys_1')
|
||||
await keystore.open()
|
||||
for (const [key, value] of Object.entries(identityKeys)) {
|
||||
await keystore.addKey(key, value)
|
||||
}
|
||||
|
||||
signingKeystore = new Keystore('./keys_2')
|
||||
await signingKeystore.open()
|
||||
for (const [key, value] of Object.entries(signingKeys)) {
|
||||
await signingKeystore.addKey(key, value)
|
||||
}
|
||||
|
||||
// Create an identity for each peers
|
||||
testIdentity1 = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
||||
testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore })
|
||||
const testIdentities = await createTestIdentities(ipfs1, ipfs2)
|
||||
testIdentity1 = testIdentities[0]
|
||||
testIdentity2 = testIdentities[1]
|
||||
|
||||
rmrf(testIdentity1.id)
|
||||
rmrf(testIdentity2.id)
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
await cleanUpTestIdentities([testIdentity1, testIdentity2])
|
||||
|
||||
if (ipfsd1) {
|
||||
await stopIpfs(ipfsd1)
|
||||
}
|
||||
@@ -105,7 +95,10 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
// const syncCount = 0
|
||||
|
||||
const accessController = {
|
||||
canAppend: (entry) => entry.identity.id === testIdentity1.id
|
||||
canAppend: async (entry) => {
|
||||
const identity = await testIdentity1.provider.get(entry.identity)
|
||||
return identity.id === testIdentity1.id
|
||||
}
|
||||
}
|
||||
|
||||
const onUpdate = (entry) => {
|
||||
@@ -231,7 +224,10 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
// let syncCount = 0
|
||||
|
||||
const accessController = {
|
||||
canAppend: (entry) => entry.identity.id === testIdentity1.id
|
||||
canAppend: async (entry) => {
|
||||
const identity = await testIdentity1.provider.get(entry.identity)
|
||||
return identity.id === testIdentity1.id
|
||||
}
|
||||
}
|
||||
|
||||
const onUpdate = (entry) => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { strictEqual, deepStrictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import { copy } from 'fs-extra'
|
||||
import { Log } from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import { Log, MemoryStorage } from '../src/log.js'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
|
||||
// Test utils
|
||||
@@ -29,8 +29,9 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
|
||||
keystore = new Keystore(identityKeysPath)
|
||||
signingKeystore = new Keystore(signingKeysPath)
|
||||
const storage = await MemoryStorage()
|
||||
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore, storage })
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { strictEqual, deepStrictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import { copy } from 'fs-extra'
|
||||
import { Log } from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import { Log, MemoryStorage } from '../src/log.js'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
|
||||
// Test utils
|
||||
@@ -29,10 +29,11 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
|
||||
keystore = new Keystore(identityKeysPath)
|
||||
signingKeystore = new Keystore(signingKeysPath)
|
||||
const storage = await MemoryStorage()
|
||||
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
||||
testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore })
|
||||
testIdentity3 = await createIdentity({ id: 'userC', keystore, signingKeystore })
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore, storage })
|
||||
testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore, storage })
|
||||
testIdentity3 = await createIdentity({ id: 'userC', keystore, signingKeystore, storage })
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { strictEqual, deepStrictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import { copy } from 'fs-extra'
|
||||
import { Log } from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import { Log, MemoryStorage } from '../src/log.js'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
|
||||
// Test utils
|
||||
@@ -33,8 +33,9 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
|
||||
keystore = new Keystore(identityKeysPath)
|
||||
signingKeystore = new Keystore(signingKeysPath)
|
||||
const storage = await MemoryStorage()
|
||||
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore, storage })
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { strictEqual, deepStrictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import { Log } from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import { Log, MemoryStorage } from '../src/log.js'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
import LogCreator from './utils/log-creator.js'
|
||||
import all from 'it-all'
|
||||
@@ -36,9 +36,12 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
await signingKeystore.addKey(key, value)
|
||||
}
|
||||
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
||||
testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore })
|
||||
testIdentity3 = await createIdentity({ id: 'userC', keystore, signingKeystore })
|
||||
const storage = await MemoryStorage()
|
||||
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore, storage })
|
||||
testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore, storage })
|
||||
testIdentity3 = await createIdentity({ id: 'userC', keystore, signingKeystore, storage })
|
||||
|
||||
ipfsd = await startIpfs(IPFS, config.defaultIpfsConfig)
|
||||
ipfs = ipfsd.api
|
||||
})
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { strictEqual, deepStrictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import { copy } from 'fs-extra'
|
||||
import { Log } from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import { Log, MemoryStorage } from '../src/log.js'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
|
||||
// Test utils
|
||||
@@ -30,8 +30,10 @@ Object.keys(testAPIs).forEach(IPFS => {
|
||||
keystore = new Keystore(identityKeysPath)
|
||||
signingKeystore = new Keystore(signingKeysPath)
|
||||
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
||||
testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore })
|
||||
const storage = await MemoryStorage()
|
||||
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore, storage })
|
||||
testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore, storage })
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { strictEqual, notStrictEqual, deepStrictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import Clock from '../src/lamport-clock.js'
|
||||
import { Log } from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import { Log, MemoryStorage } from '../src/log.js'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
|
||||
// Test utils
|
||||
@@ -37,10 +37,12 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
await signingKeystore.addKey(key, value)
|
||||
}
|
||||
|
||||
testIdentity = await createIdentity({ id: 'userC', keystore, signingKeystore })
|
||||
testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore })
|
||||
testIdentity3 = await createIdentity({ id: 'userD', keystore, signingKeystore })
|
||||
testIdentity4 = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
||||
const storage = await MemoryStorage()
|
||||
|
||||
testIdentity = await createIdentity({ id: 'userC', keystore, signingKeystore, storage })
|
||||
testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore, storage })
|
||||
testIdentity3 = await createIdentity({ id: 'userD', keystore, signingKeystore, storage })
|
||||
testIdentity4 = await createIdentity({ id: 'userA', keystore, signingKeystore, storage })
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
|
||||
@@ -5,8 +5,8 @@ import Sorting from '../src/log-sorting.js'
|
||||
import bigLogString from './fixtures/big-log.fixture.js'
|
||||
import Entry from '../src/entry.js'
|
||||
import { Log } from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import Keystore from 'orbit-db-keystore'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
import LogCreator from './utils/log-creator.js'
|
||||
|
||||
// Test utils
|
||||
|
||||
@@ -2,7 +2,7 @@ import { strictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import { copy } from 'fs-extra'
|
||||
import { Log, MemoryStorage } from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
|
||||
// Test utils
|
||||
@@ -30,7 +30,9 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
keystore = new Keystore(identityKeysPath)
|
||||
signingKeystore = new Keystore(signingKeysPath)
|
||||
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
||||
const storage = await MemoryStorage()
|
||||
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore, storage })
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { notStrictEqual, deepStrictEqual, strictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import Entry from '../src/entry.js'
|
||||
import { Log, MemoryStorage } from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
import { copy } from 'fs-extra'
|
||||
|
||||
@@ -30,7 +30,9 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
keystore = new Keystore(identityKeysPath)
|
||||
signingKeystore = new Keystore(signingKeysPath)
|
||||
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
||||
const storage = await MemoryStorage()
|
||||
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore, storage })
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { strictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import { copy } from 'fs-extra'
|
||||
import { Log, Entry, IPFSBlockStorage } from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import { Log, Entry, MemoryStorage, IPFSBlockStorage } from '../src/log.js'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
|
||||
// Test utils
|
||||
@@ -43,9 +43,11 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
keystore = new Keystore(identityKeysPath)
|
||||
signingKeystore = new Keystore(signingKeysPath)
|
||||
|
||||
const storage = await MemoryStorage()
|
||||
|
||||
// Create an identity for each peers
|
||||
testIdentity = await createIdentity({ id: 'userB', keystore, signingKeystore })
|
||||
testIdentity2 = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
||||
testIdentity = await createIdentity({ id: 'userB', keystore, signingKeystore, storage })
|
||||
testIdentity2 = await createIdentity({ id: 'userA', keystore, signingKeystore, storage })
|
||||
|
||||
storage1 = await IPFSBlockStorage({ ipfs: ipfs1 })
|
||||
storage2 = await IPFSBlockStorage({ ipfs: ipfs2 })
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { notStrictEqual, strictEqual, deepStrictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import { Log } from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
|
||||
// Test utils
|
||||
import { config, testAPIs } from 'orbit-db-test-utils'
|
||||
import { identityKeys, signingKeys } from './fixtures/orbit-db-identity-keys.js'
|
||||
import { identityKeys, signingKeys, createTestIdentities, cleanUpTestIdentities } from './fixtures/orbit-db-identity-keys.js'
|
||||
|
||||
const { sync: rmrf } = rimraf
|
||||
const { createIdentity } = IdentityProvider
|
||||
@@ -19,23 +19,14 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
let testIdentity, testIdentity2
|
||||
|
||||
before(async () => {
|
||||
keystore = new Keystore('./keys_1')
|
||||
await keystore.open()
|
||||
for (const [key, value] of Object.entries(identityKeys)) {
|
||||
await keystore.addKey(key, value)
|
||||
}
|
||||
|
||||
signingKeystore = new Keystore('./keys_2')
|
||||
await signingKeystore.open()
|
||||
for (const [key, value] of Object.entries(signingKeys)) {
|
||||
await signingKeystore.addKey(key, value)
|
||||
}
|
||||
|
||||
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
||||
testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore })
|
||||
const testIdentities = await createTestIdentities()
|
||||
testIdentity = testIdentities[0]
|
||||
testIdentity2 = testIdentities[1]
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
await cleanUpTestIdentities([testIdentity, testIdentity2])
|
||||
|
||||
if (keystore) {
|
||||
await keystore.close()
|
||||
}
|
||||
@@ -78,13 +69,13 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
strictEqual(log.identity.signatures.publicKey, testIdentity.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('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
|
||||
@@ -163,13 +154,16 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
err = e.toString()
|
||||
}
|
||||
|
||||
strictEqual(err, `Error: Could not append entry:\nKey "${testIdentity2.id}" is not allowed to write to the log`)
|
||||
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: (entry) => entry.identity.id !== testIdentity2.id
|
||||
}
|
||||
const testACL = {
|
||||
canAppend: async (entry) => {
|
||||
const identity = await testIdentity.provider.get(entry.identity)
|
||||
return identity && identity.id !== testIdentity2.id
|
||||
}
|
||||
}
|
||||
const log1 = await Log(testIdentity, { logId: 'A', access: testACL })
|
||||
const log2 = await Log(testIdentity2, { logId: 'A' })
|
||||
|
||||
@@ -182,7 +176,7 @@ Object.keys(testAPIs).forEach((IPFS) => {
|
||||
err = e.toString()
|
||||
}
|
||||
|
||||
strictEqual(err, `Error: Could not append entry:\nKey "${testIdentity2.id}" is not allowed to write to the log`)
|
||||
strictEqual(err, `Error: Could not append entry:\nKey "${testIdentity2.hash}" is not allowed to write to the log`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as IPFS from 'ipfs'
|
||||
import { strictEqual, notStrictEqual } from 'assert'
|
||||
import rimraf from 'rimraf'
|
||||
import { Log, IPFSBlockStorage, MemoryStorage, LRUStorage, ComposedStorage } from '../src/log.js'
|
||||
import IdentityProvider from 'orbit-db-identity-provider'
|
||||
import IdentityProvider from '../src/identities/identities.js'
|
||||
import Keystore from '../src/Keystore.js'
|
||||
import { copy } from 'fs-extra'
|
||||
|
||||
@@ -37,8 +37,9 @@ Object.keys(testAPIs).forEach((_) => {
|
||||
keystore = new Keystore(identityKeysPath)
|
||||
signingKeystore = new Keystore(signingKeysPath)
|
||||
|
||||
// Create an identity for each peers
|
||||
testIdentity1 = await createIdentity({ id: 'userA', keystore, signingKeystore })
|
||||
const storage = await MemoryStorage()
|
||||
|
||||
testIdentity1 = await createIdentity({ id: 'userA', keystore, signingKeystore, storage })
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
|
||||
Reference in New Issue
Block a user