Skip to content

Commit

Permalink
fix: support storing ArrayBuffers in conf (#1236)
Browse files Browse the repository at this point in the history
I made a change to use ArrayBuffers in AgentDataExport, which was not
supported by our JSON.stringify function. Tweak the stringify replacer
to handle this cleanly and add a test to verify it works as expected.
  • Loading branch information
travis authored Dec 13, 2023
1 parent ddb413f commit 9b1aafb
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 2 deletions.
4 changes: 2 additions & 2 deletions packages/access-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
"lint": "tsc --build && eslint '**/*.{js,ts}' && prettier --check '**/*.{js,ts,yml,json}' --ignore-path ../../.gitignore",
"build": "tsc --build",
"check": "tsc --build",
"test": "pnpm -r run build && npm run test:node && npm run test:browser",
"test": "pnpm -r run build && pnpm run test:node && pnpm run test:browser",
"test:node": "mocha 'test/**/!(*.browser).test.js' -n experimental-vm-modules -n no-warnings",
"test:browser": "playwright-test 'test/**/!(*.node).test.js'",
"testw": "watch 'pnpm test' src test --interval 1",
"rc": "npm version prerelease --preid rc"
"rc": "pnpm version prerelease --preid rc"
},
"exports": {
".": {
Expand Down
2 changes: 2 additions & 0 deletions packages/access-client/src/utils/json.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export const replacer = (k, v) => {
return { $map: [...v.entries()] }
} else if (v instanceof Uint8Array) {
return { $bytes: [...v.values()] }
} else if (v instanceof ArrayBuffer) {
return { $bytes: [...new Uint8Array(v).values()] }
} else if (v?.type === 'Buffer' && Array.isArray(v.data)) {
return { $bytes: v.data }
}
Expand Down
78 changes: 78 additions & 0 deletions packages/access-client/test/stores/store-conf.node.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import assert from 'assert'
import { top } from '@web3-storage/capabilities/top'
import { Signer as EdSigner } from '@ucanto/principal/ed25519'
import * as RSASigner from '@ucanto/principal/rsa'
import { AgentData } from '../../src/agent-data.js'
import { StoreConf } from '../../src/stores/store-conf.js'

describe('Conf store', () => {
it('should create and load data', async () => {
const data = await AgentData.create({
principal: await RSASigner.generate({ extractable: false }),
})

const store = new StoreConf({ profile: 'test-access-db-' + Date.now() })
await store.open()
await store.save(data.export())

const exportData = await store.load()
assert(exportData)

// no accounts or delegations yet
assert.equal(exportData.spaces.size, 0)
assert.equal(exportData.delegations.size, 0)

// default meta
assert.equal(exportData.meta.name, 'agent')
assert.equal(exportData.meta.type, 'device')
})

it('should round trip delegations', async () => {
const store = new StoreConf({ profile: 'test-access-db-' + Date.now() })
await store.open()

const data0 = await AgentData.create()
const signer = await EdSigner.generate()
const del0 = await top.delegate({
issuer: signer,
audience: data0.principal,
with: signer.did(),
expiration: Infinity,
})

await data0.addDelegation(del0, {
audience: { name: 'test', type: 'device' },
})
await store.save(data0.export())

const exportData1 = await store.load()
assert(exportData1)

const data1 = AgentData.fromExport(exportData1)

const { delegation: del1 } =
data1.delegations.get(del0.cid.toString()) ?? {}
assert(del1)
assert.equal(del1.cid.toString(), del0.cid.toString())
assert.equal(del1.issuer.did(), del0.issuer.did())
assert.equal(del1.audience.did(), del0.audience.did())
assert.equal(del1.capabilities[0].can, del0.capabilities[0].can)
assert.equal(del1.capabilities[0].with, del0.capabilities[0].with)
})

it('should be resettable', async () => {
const principal = await RSASigner.generate({ extractable: false })
const data = await AgentData.create({ principal })

const store = new StoreConf({ profile: 'test-access-db-' + Date.now() })
await store.open()
await store.save(data.export())

const exportData = await store.load()
assert.equal(exportData?.principal.id, principal.did())

await store.reset()
const resetExportData = await store.load()
assert.equal(resetExportData?.principal.id, undefined)
})
})

0 comments on commit 9b1aafb

Please sign in to comment.