Skip to content

Commit

Permalink
Merge pull request #60 from orbitdb/pinner/new-refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
haydenyoung authored Jul 14, 2024
2 parents f9d8260 + 9ca1c7a commit 9d0efe5
Show file tree
Hide file tree
Showing 33 changed files with 360 additions and 286 deletions.
3 changes: 3 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

96 changes: 96 additions & 0 deletions src/daemon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { join } from 'path'
import { createLibp2p } from 'libp2p'
import { createHelia } from 'helia'
import { createOrbitDB, Identities, KeyStore } from '@orbitdb/core'
import { LevelBlockstore } from 'blockstore-level'
import { LevelDatastore } from 'datastore-level'
import { pipe } from 'it-pipe'
import Orbiter from './lib/orbiter.js'
import { voyagerRPCProtocol } from './rpc/protocol.js'
import { handleCommand } from './rpc/index.js'
import { Access } from './lib/authorization.js'
import { config as libp2pConfig } from './utils/libp2p-config.js'
import { rpc as rpcId, appPath, rpcPath, app, orbiter as orbiterId, orbiterPath } from './utils/id.js'
import { saveConfig } from './utils/config-manager.js'
import { createFromPrivKey } from '@libp2p/peer-id-factory'
import { logger, enable } from '@libp2p/logger'

export default async ({ options }) => {
options = options || {}

const log = logger('orbitdb:voyager:daemon')

if (options.verbose > 0) {
enable('orbitdb:voyager:daemon' + (options.verbose > 1 ? '*' : ':error'))
}

options.defaultAccess = options.defaultAccess || Access.ALLOW

options.verbose = options.verbose || 0

const id = orbiterId

log('id:', id)

const appDirectory = appPath(options.directory)
const orbiterDirectory = orbiterPath(options.directory)

log('app:', app)
log('directory:', orbiterDirectory)

const path = join(orbiterDirectory, '/', 'keystore')

const blockstore = new LevelBlockstore(join(orbiterDirectory, '/', 'ipfs', '/', 'blocks'))
const datastore = new LevelDatastore(join(orbiterDirectory, '/', 'ipfs', '/', 'data'))

const keystore = await KeyStore({ path })
const identities = await Identities({ keystore })
await identities.createIdentity({ id })

const peerId = await createFromPrivKey(await keystore.getKey(id))
const libp2p = await createLibp2p(await libp2pConfig({ peerId }))

log('peerid:', libp2p.peerId.toString())
for (const addr of libp2p.getMultiaddrs().map(e => e.toString())) {
log('listening on', addr)
}

const ipfs = await createHelia({ libp2p, datastore, blockstore })

const orbitdb = await createOrbitDB({ ipfs, directory: orbiterDirectory, identities, id })

const orbiter = await Orbiter({ defaultAccess: options.defaultAccess, verbose: options.verbose, orbitdb })

// TODO: we might want to separate the key init to a separate 'init' CLI command
const initRPCKey = async ({ directory }) => {
const id = rpcId
const rpcDirectory = rpcPath(directory)
const path = join(rpcDirectory, 'keystore')
const keystore = await KeyStore({ path })
const identities = await Identities({ keystore })
const identity = await identities.createIdentity({ id })

await keystore.close()

return identity.publicKey
}

const authorizedRPCKey = await initRPCKey({ directory: options.directory })

const config = { orbiter: {}, rpc: {} }
config.orbiter.peerId = orbiter.orbitdb.ipfs.libp2p.peerId
config.orbiter.api = orbiter.orbitdb.ipfs.libp2p.getMultiaddrs().shift() // get 127.0.0.1 address
config.rpc.publicKeys = [authorizedRPCKey]
await saveConfig({ path: appDirectory, config })

const handleRPCMessages = async ({ stream }) => {
await pipe(stream, handleCommand({ config, orbitdb: orbiter.orbitdb, pins: orbiter.pins, dbs: orbiter.dbs, auth: orbiter.auth }), stream)
}

await orbiter.orbitdb.ipfs.libp2p.handle(voyagerRPCProtocol, handleRPCMessages)

process.on('SIGINT', async () => {
await orbiter.stop()
process.exit(0)
})
}
43 changes: 34 additions & 9 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@

import yargs from 'yargs'
import { hideBin } from 'yargs/helpers'
import { daemon, authAdd, authDel, authList } from './lib/commands/index.js'
import daemon from './daemon.js'
import RPC from './rpc-client.js'
import { Responses } from './lib/messages/index.js'

yargs(hideBin(process.argv))
.scriptName('voyager')
.command(
'daemon',
'Launch Voyager',
() => {},
argv => {
daemon(argv)
async (argv) => {
await daemon({ options: argv })
})
.command('auth', 'Add/remove authorized addresses', yargs => {
yargs
Expand All @@ -25,8 +27,15 @@ yargs(hideBin(process.argv))
})
},
async argv => {
await authAdd(argv)
process.exit(0)
const { authAdd } = await RPC(argv)
const res = await authAdd(argv)
if (res.type === Responses.OK) {
console.log('ok')
process.exit(0)
} else {
console.error(res)
process.exit(1)
}
})
.command(
'del <id>',
Expand All @@ -38,16 +47,32 @@ yargs(hideBin(process.argv))
})
},
async argv => {
await authDel(argv)
process.exit(0)
const { authDel } = await RPC(argv)
const res = await authDel(argv)
if (res.type === Responses.OK) {
console.log('ok')
process.exit(0)
} else {
console.error(res)
process.exit(1)
}
})
.command(
'list',
'List authorized addresses',
() => {},
async argv => {
await authList(argv)
process.exit(0)
const { authList } = await RPC(argv)
const res = await authList()
if (res.type === Responses.OK) {
for (const id of res.message) {
console.log(id)
}
process.exit(0)
} else {
console.error(res)
process.exit(1)
}
})
.demandCommand(1, 'Error: use add or remove')
})
Expand Down
26 changes: 12 additions & 14 deletions src/lib/authorization.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,19 @@ export const Access = Object.freeze({
DENY: 2
})

export default ({ orbitdb, defaultAccess }) => {
export default async ({ orbitdb, defaultAccess }) => {
defaultAccess = defaultAccess || Access.DENY

useDatabaseType(Set)

const access = await orbitdb.open('access', { type: 'set' })

const add = async (id) => {
const access = await orbitdb.open('access', { type: 'set' })
await access.add(id)
await access.close()
}

const del = async (id) => {
const access = await orbitdb.open('access', { type: 'set' })
await access.del(id)
await access.close()
}

const hasAccess = async (id) => {
Expand All @@ -30,31 +28,31 @@ export default ({ orbitdb, defaultAccess }) => {

// @TODO is there a database which stores unique values + can get by value?
// @TODO add has(value) function to SetDB
for await (const a of access.iterator()) {
if (a.value === id) {
for await (const { value } of access.iterator()) {
if (value === id) {
found = true
break
}
}

await access.close()

return defaultAccess === Access.DENY ? found : !found
}

const all = async () => {
const access = await orbitdb.open('access', { type: 'set' })
const all = await access.all()
await access.close()

const all = (await access.all()).map(e => e.value)
return all
}

const close = async () => {
await access.close()
}

return {
defaultAccess,
add,
del,
hasAccess,
all
all,
close
}
}
6 changes: 0 additions & 6 deletions src/lib/commands/auth-add.js

This file was deleted.

6 changes: 0 additions & 6 deletions src/lib/commands/auth-del.js

This file was deleted.

8 changes: 0 additions & 8 deletions src/lib/commands/auth-list.js

This file was deleted.

54 changes: 0 additions & 54 deletions src/lib/commands/controller.js

This file was deleted.

22 changes: 0 additions & 22 deletions src/lib/commands/daemon.js

This file was deleted.

11 changes: 0 additions & 11 deletions src/lib/commands/index.js

This file was deleted.

8 changes: 4 additions & 4 deletions src/lib/handlers/index.js → src/lib/handle-request.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import handlePinRequest from './pin.js'
import handleUnpinRequest from './unpin.js'
import { createResponseMessage, parseMessage, Requests, Responses } from '../messages/index.js'
import handlePinRequest from './handlers/pin.js'
import handleUnpinRequest from './handlers/unpin.js'
import { createResponseMessage, parseMessage, Requests, Responses } from './messages/index.js'

export const handleRequest = (orbiter) => source => {
return (async function * () {
Expand All @@ -16,7 +16,7 @@ export const handleRequest = (orbiter) => source => {
}

// verify that the params have come from the user who owns the pubkey.
if (!await orbiter.orbitdb.identity.verify(signature, pubkey, addresses)) {
if (!await orbiter.orbitdb.identity.verify(signature, pubkey, JSON.stringify(addresses))) {
throw Object.assign(new Error('invalid signature'), { type: Responses.E_INVALID_SIGNATURE })
}

Expand Down
Loading

0 comments on commit 9d0efe5

Please sign in to comment.