identity.add() can implicitly also create the consent

This commit is contained in:
Andre Staltz 2023-07-11 10:49:33 +03:00
parent 2347592aac
commit 07c2168f97
No known key found for this signature in database
GPG Key ID: 9EDE23EA7E8A4890
2 changed files with 30 additions and 15 deletions

View File

@ -10,12 +10,17 @@ const base58 = require('bs58')
const Obz = require('obz') const Obz = require('obz')
const Keypair = require('ppppp-keypair') const Keypair = require('ppppp-keypair')
const MsgV3 = require('./msg-v3') const MsgV3 = require('./msg-v3')
const { SIGNATURE_TAG_IDENTITY_ADD, IDENTITY_SELF } = require('./msg-v3/constants') const {
SIGNATURE_TAG_IDENTITY_ADD,
IDENTITY_SELF,
} = require('./msg-v3/constants')
const { ReadyGate } = require('./utils') const { ReadyGate } = require('./utils')
const { decrypt } = require('./encryption') const { decrypt } = require('./encryption')
/** /**
* @typedef {import('ppppp-keypair').Keypair} Keypair * @typedef {import('ppppp-keypair').Keypair} Keypair
* @typedef {import('ppppp-keypair').KeypairPublicSlice} KeypairPublicSlice
* @typedef {import('ppppp-keypair').KeypairPrivateSlice} KeypairPrivateSlice
* @typedef {import('./msg-v3').Msg} Msg * @typedef {import('./msg-v3').Msg} Msg
* @typedef {import('./encryption').EncryptionFormat} EncryptionFormat * @typedef {import('./encryption').EncryptionFormat} EncryptionFormat
* *
@ -300,7 +305,7 @@ function initDB(peer, config) {
} }
/** /**
* @param {{ keypair?: any; identity: string; domain: string; }} opts * @param {{ keypair?: Keypair; identity: string; domain: string; }} opts
* @param {CB<string>} cb * @param {CB<string>} cb
*/ */
function initializeFeed(opts, cb) { function initializeFeed(opts, cb) {
@ -339,7 +344,7 @@ function initDB(peer, config) {
/** /**
* @param {{ * @param {{
* keypair?: Keypair; * keypair?: KeypairPublicSlice;
* domain: string; * domain: string;
* }} opts * }} opts
* @param {CB<string>} cb * @param {CB<string>} cb
@ -428,7 +433,7 @@ function initDB(peer, config) {
/** /**
* @param {{ * @param {{
* keypair?: Keypair; * keypair?: KeypairPrivateSlice;
* identity: string; * identity: string;
* }} opts * }} opts
* @returns {string} * @returns {string}
@ -447,27 +452,39 @@ function initDB(peer, config) {
/** /**
* @param {{ * @param {{
* keypair: Keypair;
* identity: string; * identity: string;
* consent: string * } & ({
* }} opts * keypair: KeypairPublicSlice & {private?: never};
* consent: string;
* } | {
* keypair: Keypair;
* consent?: never;
* })} opts
* @param {CB<Rec>} cb * @param {CB<Rec>} cb
*/ */
function addToIdentity(opts, cb) { function addToIdentity(opts, cb) {
// prettier-ignore
if (!opts?.keypair) return cb(new Error('identity.add() requires a `keypair`'))
// prettier-ignore // prettier-ignore
if (!opts?.identity) return cb(new Error('identity.add() requires a `identity`')) if (!opts?.identity) return cb(new Error('identity.add() requires a `identity`'))
// prettier-ignore // prettier-ignore
if (!opts?.consent) return cb(new Error('identity.add() requires a `consent`')) if (!opts?.keypair) return cb(new Error('identity.add() requires a `keypair`'))
// prettier-ignore
if (!opts?.keypair.public) return cb(new Error('identity.add() requires a `keypair` with `public`'))
let consent = /** @type {string} */ (opts.consent)
if (typeof opts.consent === 'undefined') {
if (opts.keypair.private) {
consent = consentToIdentity(opts)
} else {
return cb(new Error('identity.add() requires a `consent`'))
}
}
const addedKeypair = opts.keypair const addedKeypair = opts.keypair
const signingKeypair = config.keypair const signingKeypair = config.keypair
// Verify consent: // Verify consent:
const signableBuf = b4a.from( const signableBuf = b4a.from(
SIGNATURE_TAG_IDENTITY_ADD + base58.decode(opts.identity), SIGNATURE_TAG_IDENTITY_ADD + base58.decode(opts.identity)
) )
if (!Keypair.verify(addedKeypair, signableBuf, opts.consent)) { if (!Keypair.verify(addedKeypair, signableBuf, consent)) {
// prettier-ignore // prettier-ignore
return cb(new Error('identity.add() failed because the consent is invalid')) return cb(new Error('identity.add() failed because the consent is invalid'))
} }
@ -558,7 +575,6 @@ function initDB(peer, config) {
ciphertextBuf = encryptionFormat.encrypt(plaintext, encryptOpts) ciphertextBuf = encryptionFormat.encrypt(plaintext, encryptOpts)
} catch (err) { } catch (err) {
// prettier-ignore // prettier-ignore
console.log(err);
return cb( return cb(
new Error('feed.publish() failed to encrypt data', { cause: err }) new Error('feed.publish() failed to encrypt data', { cause: err })
) )

View File

@ -68,11 +68,10 @@ test('publish with a key in the identity', async (t) => {
}) })
const identityMsg0 = peer.db.get(identity) const identityMsg0 = peer.db.get(identity)
const consent = peer.db.identity.consent({ identity, keypair: keypair2 }) // Consent is implicitly created because keypair2 has .private
const identityRec1 = await p(peer.db.identity.add)({ const identityRec1 = await p(peer.db.identity.add)({
identity, identity,
keypair: keypair2, keypair: keypair2,
consent,
}) })
const postRec = await p(peer.db.feed.publish)({ const postRec = await p(peer.db.feed.publish)({