Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

feat: encoding key's name to base32 #2410

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/core/components/pre-start.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const mergeOptions = require('merge-options')
const NoKeychain = require('./no-keychain')
const callbackify = require('callbackify')
const promisify = require('promisify-es6')
const KeyTransformDatastore = require('datastore-core').KeytransformDatastore
const keychainTransformer = require('../../utils/keychain-encoder')

/*
* Load stuff from Repo into memory
Expand Down Expand Up @@ -36,7 +38,8 @@ module.exports = function preStart (self) {
// most likely an init or upgrade has happened
} else if (pass) {
const keychainOptions = Object.assign({ passPhrase: pass }, config.Keychain)
self._keychain = new Keychain(self._repo.keys, keychainOptions)
const keychainTransformedDatastore = new KeyTransformDatastore(self._repo.keys, keychainTransformer)
self._keychain = new Keychain(keychainTransformedDatastore, keychainOptions)
self.log('keychain constructed')
} else {
self._keychain = new NoKeychain()
Expand Down
47 changes: 47 additions & 0 deletions src/utils/keychain-encoder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict'
const base32 = require('base32.js')
const Key = require('interface-datastore').Key
const KEY_PREFIX = 'key_'

module.exports = {
/**
* Encode baseNamespace of a Key to base32
*
* @param {Key} key
* @returns {Key}
*
* @example convert(new Key('/info/self.data'))
* // => Key('/info/key_onswyzq.data')
*/
convert (key) {
const encoder = new base32.Encoder({ type: 'rfc4648' })
const baseNameBuff = Buffer.from(key.baseNamespace())
const encodedBaseNamespace = KEY_PREFIX + encoder.finalize(baseNameBuff).toLowerCase()
const namespaces = key.namespaces()
namespaces[namespaces.length - 1] = encodedBaseNamespace // Replace the baseNamespace with encoded one
return Key.withNamespaces(namespaces)
},

/**
* Decode baseNamespace of a Key from base32
*
* @param {Key} key
* @returns {Key}
*
* @example invert(new Key('/info/key_onswyzq.data'))
* // => Key('/info/self.data')
*/
invert (key) {
const baseNamespace = key.baseNamespace()
if (!baseNamespace.startsWith(KEY_PREFIX)) {
throw Error('Unknown format of key\'s name!')
}

const decoder = new base32.Decoder({ type: 'rfc4648' })
const decodedBaseNamespace = decoder.finalize(baseNamespace.replace(KEY_PREFIX, '').toUpperCase())
const namespaces = key.namespaces()
namespaces[namespaces.length - 1] = Buffer.from(decodedBaseNamespace).toString() // Replace the baseNamespace with encoded one

return Key.withNamespaces(namespaces)
}
}
29 changes: 29 additions & 0 deletions test/utils-test/keychain-encode.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* eslint-env mocha */
'use strict'

const encoder = require('../../src/utils/keychain-encoder')
const Key = require('interface-datastore').Key
const { expect } = require('interface-ipfs-core/src/utils/mocha')

function test (input, expected, fnc) {
input = new Key(input)
const output = fnc(input)

expect(output.toString()).to.equal(expected)
}

describe('keychain-encode', () => {
it('encode keys', () => {
test('/self', '/key_onswyzq', encoder.convert)
test('bbbba', '/key_mjrgeytb', encoder.convert)
test('/some/path/self', '/some/path/key_onswyzq', encoder.convert)
})
it('decode keys', () => {
test('/key_onswyzq', '/self', encoder.invert)
test('key_mjrgeytb', '/bbbba', encoder.invert)
test('/some/path/key_onswyzq', '/some/path/self', encoder.invert)
})
it('decode expects specific format', () => {
expect(() => { encoder.invert(new Key('/some/path/onswyzq')) }).to.throw('Unknown')
})
})