mirror of
https://github.com/orbitdb/orbitdb.git
synced 2025-03-30 15:08:28 +00:00
feat: Encrypt oplog payload.
This commit is contained in:
parent
90f66cfe5d
commit
f272d3ee3c
@ -7,7 +7,6 @@
|
||||
* @augments module:Databases~Database
|
||||
*/
|
||||
import Database from '../database.js'
|
||||
import { toPayload, fromPayload } from './utils/payload.js'
|
||||
|
||||
const type = 'events'
|
||||
|
||||
@ -16,7 +15,7 @@ const type = 'events'
|
||||
* @return {module:Databases.Databases-Events} A Events function.
|
||||
* @memberof module:Databases
|
||||
*/
|
||||
const Events = () => async ({ ipfs, identity, address, name, access, directory, meta, headsStorage, entryStorage, indexStorage, referencesCount, syncAutomatically, onUpdate, encrypt }) => {
|
||||
const Events = () => async ({ ipfs, identity, address, name, access, directory, meta, headsStorage, entryStorage, indexStorage, referencesCount, syncAutomatically, onUpdate }) => {
|
||||
const database = await Database({ ipfs, identity, address, name, access, directory, meta, headsStorage, entryStorage, indexStorage, referencesCount, syncAutomatically, onUpdate })
|
||||
|
||||
const { addOperation, log } = database
|
||||
@ -30,8 +29,7 @@ const Events = () => async ({ ipfs, identity, address, name, access, directory,
|
||||
* @instance
|
||||
*/
|
||||
const add = async (value) => {
|
||||
const payload = await toPayload('ADD', null, value, { encrypt })
|
||||
return addOperation(payload)
|
||||
return addOperation({ op: 'ADD', key: null, value })
|
||||
}
|
||||
|
||||
/**
|
||||
@ -44,9 +42,7 @@ const Events = () => async ({ ipfs, identity, address, name, access, directory,
|
||||
*/
|
||||
const get = async (hash) => {
|
||||
const entry = await log.get(hash)
|
||||
const { value } = await fromPayload(entry.payload, { encrypt })
|
||||
|
||||
return value
|
||||
return entry.payload.value
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,8 +66,7 @@ const Events = () => async ({ ipfs, identity, address, name, access, directory,
|
||||
const it = log.iterator({ gt, gte, lt, lte, amount })
|
||||
for await (const event of it) {
|
||||
const hash = event.hash
|
||||
const payload = await fromPayload(event.payload, { encrypt })
|
||||
const value = payload.value
|
||||
const value = event.payload.value
|
||||
yield { hash, value }
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
/**
|
||||
|
||||
*/
|
||||
const toPayload = async (op, key, value, { encrypt }) => {
|
||||
let payload = { op, key, value }
|
||||
|
||||
if (encrypt) {
|
||||
if (encrypt.data) {
|
||||
payload.value = await encrypt.data.encryptFn(value)
|
||||
}
|
||||
|
||||
if (encrypt.op) {
|
||||
payload = await encrypt.op.encryptFn(JSON.stringify(payload))
|
||||
}
|
||||
}
|
||||
|
||||
return payload
|
||||
}
|
||||
|
||||
const fromPayload = async (payload, { encrypt }) => {
|
||||
if (encrypt) {
|
||||
if (encrypt.op) {
|
||||
payload = JSON.parse(await encrypt.op.decryptFn(payload))
|
||||
}
|
||||
|
||||
if (encrypt.data) {
|
||||
payload.value = await encrypt.data.decryptFn(payload.value)
|
||||
}
|
||||
}
|
||||
|
||||
const { op, key, value } = payload
|
||||
|
||||
return { op, key, value }
|
||||
}
|
||||
|
||||
export {
|
||||
toPayload,
|
||||
fromPayload
|
||||
}
|
@ -56,7 +56,7 @@ const DefaultAccessController = async () => {
|
||||
* @memberof module:Log
|
||||
* @instance
|
||||
*/
|
||||
const Log = async (identity, { logId, logHeads, access, entryStorage, headsStorage, indexStorage, sortFn } = {}) => {
|
||||
const Log = async (identity, { logId, logHeads, access, entryStorage, headsStorage, indexStorage, sortFn, encryption } = {}) => {
|
||||
/**
|
||||
* @namespace Log
|
||||
* @description The instance returned by {@link module:Log}
|
||||
@ -83,6 +83,9 @@ const Log = async (identity, { logId, logHeads, access, entryStorage, headsStora
|
||||
// Conflict-resolution sorting function
|
||||
sortFn = NoZeroes(sortFn || LastWriteWins)
|
||||
|
||||
encryption = encryption || {}
|
||||
const { encryptPayloadFn, decryptPayloadFn } = encryption
|
||||
|
||||
// Internal queues for processing appends and joins in their call-order
|
||||
const appendQueue = new PQueue({ concurrency: 1 })
|
||||
const joinQueue = new PQueue({ concurrency: 1 })
|
||||
@ -139,6 +142,10 @@ const Log = async (identity, { logId, logHeads, access, entryStorage, headsStora
|
||||
if (bytes) {
|
||||
const entry = await Entry.decode(bytes)
|
||||
|
||||
if (decryptPayloadFn) {
|
||||
entry.payload = JSON.parse(await decryptPayloadFn(entry.payload))
|
||||
}
|
||||
|
||||
return entry
|
||||
}
|
||||
}
|
||||
@ -172,6 +179,10 @@ const Log = async (identity, { logId, logHeads, access, entryStorage, headsStora
|
||||
// (skips the heads which are covered by the next field)
|
||||
const refs = await getReferences(heads_, options.referencesCount + heads_.length)
|
||||
|
||||
if (encryptPayloadFn) {
|
||||
data = await encryptPayloadFn(JSON.stringify(data))
|
||||
}
|
||||
|
||||
// Create the entry
|
||||
const entry = await Entry.create(
|
||||
identity,
|
||||
|
@ -3,6 +3,7 @@ import { rimraf } from 'rimraf'
|
||||
import { copy } from 'fs-extra'
|
||||
import { Log, Entry, Identities, KeyStore, MemoryStorage } from '../../src/index.js'
|
||||
import testKeysPath from '../fixtures/test-keys-path.js'
|
||||
import { encrypt, decrypt } from '../utils/encrypt.js'
|
||||
|
||||
const { create } = Entry
|
||||
|
||||
@ -142,5 +143,34 @@ describe('Log', function () {
|
||||
strictEqual(values[1].payload, 'hello2')
|
||||
strictEqual(values[2].payload, 'hello3')
|
||||
})
|
||||
|
||||
it('encrypts a log entry when the payload is a string', async () => {
|
||||
const keys = await keystore.createKey('hello1')
|
||||
|
||||
const privateKey = await keystore.getKey('hello1')
|
||||
const publicKey = await keystore.getPublic(keys)
|
||||
|
||||
const encryptPayloadFn = encrypt({ publicKey })
|
||||
const decryptPayloadFn = decrypt({ privateKey })
|
||||
const log = await Log(testIdentity, { encryption: { encryptPayloadFn, decryptPayloadFn } })
|
||||
const entry = await log.append('hello1')
|
||||
const value = await log.get(entry.hash)
|
||||
strictEqual(value.payload, 'hello1')
|
||||
})
|
||||
|
||||
it('encrypts a log entry when the payload is an object', async () => {
|
||||
const keys = await keystore.createKey('hello1')
|
||||
|
||||
const privateKey = await keystore.getKey('hello1')
|
||||
const publicKey = await keystore.getPublic(keys)
|
||||
|
||||
const encryptPayloadFn = encrypt({ publicKey })
|
||||
const decryptPayloadFn = decrypt({ privateKey })
|
||||
const log = await Log(testIdentity, { encryption: { encryptPayloadFn, decryptPayloadFn } })
|
||||
const entry = await log.append({ test: 'hello1' })
|
||||
const value = await log.get(entry.hash)
|
||||
|
||||
deepStrictEqual(value.payload, { test: 'hello1' })
|
||||
})
|
||||
})
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user