ssb-keyring
Version:
A persistence store for encryption keys for scuttlebutt. It's purpose is to make easy to answer box2 encryption/ decryption questions.
85 lines (73 loc) • 2.13 kB
JavaScript
const pull = require('pull-stream')
const { read } = require('pull-level')
const URI = require('ssb-uri2')
function normalise (id) {
if (id.startsWith('@')) return URI.fromFeedSigil(id)
else return id
}
const SIGNING_KEYS = 'signing'
module.exports = function Signing (db) {
let cache = new Map() // Map: `id` => SSBKeys object
const api = {
load (cb) {
readPersisted((err, pairs) => {
if (err) return cb(err)
cache = new Map(pairs)
cb(null)
})
},
add (keys, cb) {
if (!cache) throw new Error('keyring not ready')
if (!keys.id) throw new Error('keys.id is not defined')
if (!keys.curve) throw new Error('keys.curve is not defined')
if (!keys.public) throw new Error('keys.public key is not defined')
if (!keys.private) throw new Error('keys.private key is not defined')
const id = normalise(keys.id)
if (cache.has(id)) {
if (cb) cb()
return false
}
cache.set(id, keys)
db.put([SIGNING_KEYS, id], keys, cb)
return true
},
addNamed (name, keys, cb) {
if (!cache) throw new Error('keyring not ready')
if (!keys.id) throw new Error('keys.id is not defined')
if (!keys.curve) throw new Error('keys.curve is not defined')
if (!keys.public) throw new Error('keys.public key is not defined')
if (!keys.private) throw new Error('keys.private key is not defined')
if (cache.has(name)) {
if (cb) cb()
return false
}
cache.set(name, keys)
db.put([SIGNING_KEYS, name], keys, cb)
return true
},
get (id) {
id = normalise(id)
return cache.get(id)
},
has (id) {
id = normalise(id)
return cache.has(id)
}
}
return api
function readPersisted (cb) {
pull(
read(db, {
gt: [SIGNING_KEYS, null],
lt: [SIGNING_KEYS + '~']
}),
pull.map(({ key, value: info }) => {
return [normalise(key[1]), info]
}),
pull.collect((err, pairs) => {
if (err) return cb(err)
cb(null, pairs)
})
)
}
}