From beb2331e417a3f5796b044b31513a4fd2a7fe446 Mon Sep 17 00:00:00 2001 From: Evan Hahn Date: Wed, 26 Jun 2024 10:49:30 -0500 Subject: [PATCH] feat: keyToInviteId (#26) Similar to `keyToPublicId`, this adds a `keyToInviteId` for deriving an invite ID. This was originally added in `@mapeo/core` but should live here instead. See . --- index.js | 2 ++ tests/utils.test.js | 20 +++++++++++++++++++- utils.js | 12 ++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 928825b..7a32c97 100644 --- a/index.js +++ b/index.js @@ -3,6 +3,7 @@ const { sign, verifySignature, keyToPublicId, + keyToInviteId, } = require('./utils.js') exports.KeyManager = require('./key-manager') @@ -10,3 +11,4 @@ exports.invites = require('./project-invites') exports.sign = sign exports.verifySignature = verifySignature exports.keyToPublicId = keyToPublicId +exports.keyToInviteId = keyToInviteId diff --git a/tests/utils.test.js b/tests/utils.test.js index 276f9a4..4e75615 100644 --- a/tests/utils.test.js +++ b/tests/utils.test.js @@ -5,7 +5,8 @@ const { KeyManager, sign, verifySignature, - keyToPublicId + keyToPublicId, + keyToInviteId, } = require('../') const z32 = require('z32') @@ -38,3 +39,20 @@ test('key to public ID', function (t) { ) t.end() }) + +test('key to invite ID', (t) => { + const key = createHash('sha256').update('test key').digest() + const inviteId = keyToInviteId(key) + t.same( + inviteId, + Buffer.from('eQro+t0dzx2AFf3h9Bh5A94i0YdR19xJkq+NGny+IS0=', 'base64'), + 'checks for consistency - a change is a breaking change' + ) + t.same(keyToInviteId(key), inviteId, 'deterministic') + t.notSame( + key, + inviteId, + "didn't do something dumb and encode without hashing" + ) + t.end() +}) diff --git a/utils.js b/utils.js index 98f0fcf..e19e028 100644 --- a/utils.js +++ b/utils.js @@ -3,6 +3,7 @@ const sodium = require('sodium-universal') const z32 = require('z32') const MAPEO = Buffer.from('mapeo') +const PROJECT_INVITE_ID_SALT = Buffer.from('mapeo project invite id', 'ascii') /** * Sign message using secretKey @@ -41,3 +42,14 @@ exports.keyToPublicId = function (key) { sodium.crypto_generichash(digest, MAPEO, key) return z32.encode(digest) } + +/** + * Generate an invite ID from a project key + * @param {Readonly} key + * @returns {Buffer} + */ +exports.keyToInviteId = function (key) { + const digest = Buffer.allocUnsafe(32) + sodium.crypto_generichash(digest, PROJECT_INVITE_ID_SALT, key) + return digest +}