From a06eef221ffec84cfef919a2ce469dca18905851 Mon Sep 17 00:00:00 2001 From: Christophe Diederichs Date: Thu, 2 Apr 2026 14:02:38 +0100 Subject: [PATCH 1/5] add failing tests --- test/manifest.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/manifest.js b/test/manifest.js index 675dcec6..87f092c2 100644 --- a/test/manifest.js +++ b/test/manifest.js @@ -1553,6 +1553,44 @@ test('manifest - persist if manifest is updated', async function (t) { } }) +test('manifest - writable', async function (t) { + const keyPair = crypto.keyPair() + + const manifest = Verifier.createManifest({ + quorum: 1, + signers: [ + { + signature: 'ed25519', + publicKey: keyPair.publicKey + } + ] + }) + + const key = Verifier.manifestHash(manifest) + const core = await create(t, { compat: false, manifest }) + + t.alike(core.key, key) + + t.absent(core.keyPair) + t.absent(core.writable) + + const signature = b4a.alloc(32) + await t.exception(core.append('hello')) + + t.is(core.length, 0) +}) + +test('manifest - invalid signature fails', async function (t) { + const core = await create(t, { compat: false }) + + t.ok(core.writable) + + const signature = b4a.alloc(32) + await t.exception(core.append('hello', { signature })) + + t.is(core.length, 0) +}) + function createMultiManifest(signers, prologue = null) { return { hash: 'blake2b', From 29d3d4e0b8dd828bcd260a4bfbee5b2df1e81d3c Mon Sep 17 00:00:00 2001 From: Christophe Diederichs Date: Thu, 2 Apr 2026 14:07:10 +0100 Subject: [PATCH 2/5] add test for writable property with manfiest --- test/manifest.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/test/manifest.js b/test/manifest.js index 87f092c2..c96fe6af 100644 --- a/test/manifest.js +++ b/test/manifest.js @@ -1580,17 +1580,6 @@ test('manifest - writable', async function (t) { t.is(core.length, 0) }) -test('manifest - invalid signature fails', async function (t) { - const core = await create(t, { compat: false }) - - t.ok(core.writable) - - const signature = b4a.alloc(32) - await t.exception(core.append('hello', { signature })) - - t.is(core.length, 0) -}) - function createMultiManifest(signers, prologue = null) { return { hash: 'blake2b', From e1085c722edd416344cbf4cfc132fb86487f3f37 Mon Sep 17 00:00:00 2001 From: Christophe Diederichs Date: Thu, 2 Apr 2026 14:02:50 +0100 Subject: [PATCH 3/5] handle writable when manifest is passed --- lib/core.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core.js b/lib/core.js index 606b069e..a463ab3c 100644 --- a/lib/core.js +++ b/lib/core.js @@ -194,7 +194,7 @@ module.exports = class Core { } } - const keyPair = opts.keyPair || (opts.key ? null : crypto.keyPair()) + const keyPair = opts.keyPair || ((opts.key || opts.manifest) ? null : crypto.keyPair()) const defaultManifest = !opts.manifest && From e6500008e0675b3130490a2c2638015ec81a20bd Mon Sep 17 00:00:00 2001 From: Christophe Diederichs Date: Thu, 2 Apr 2026 14:12:16 +0100 Subject: [PATCH 4/5] lint --- lib/core.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core.js b/lib/core.js index a463ab3c..c06343bc 100644 --- a/lib/core.js +++ b/lib/core.js @@ -194,7 +194,7 @@ module.exports = class Core { } } - const keyPair = opts.keyPair || ((opts.key || opts.manifest) ? null : crypto.keyPair()) + const keyPair = opts.keyPair || (opts.key || opts.manifest ? null : crypto.keyPair()) const defaultManifest = !opts.manifest && From 8b69dd94da39341ed038cb980d32bf7c471e11ae Mon Sep 17 00:00:00 2001 From: Christophe Diederichs Date: Thu, 2 Apr 2026 18:27:04 +0100 Subject: [PATCH 5/5] add more tests to illustrate behaviour --- test/manifest.js | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/test/manifest.js b/test/manifest.js index c96fe6af..387ca8b8 100644 --- a/test/manifest.js +++ b/test/manifest.js @@ -1567,17 +1567,43 @@ test('manifest - writable', async function (t) { }) const key = Verifier.manifestHash(manifest) - const core = await create(t, { compat: false, manifest }) - t.alike(core.key, key) + // correct keyPair + const writer = await create(t, { compat: false, manifest, keyPair }) + t.alike(writer.key, key) - t.absent(core.keyPair) - t.absent(core.writable) + t.ok(writer.keyPair) + t.ok(writer.writable) const signature = b4a.alloc(32) - await t.exception(core.append('hello')) + await t.execution(writer.append('hello')) + + t.is(writer.length, 1) + + // no keyPair + const reader = await create(t, { compat: false, manifest }) + + t.alike(reader.key, key) + + t.absent(reader.keyPair) + t.absent(reader.writable) + + await t.exception(reader.append('hello')) + + t.is(reader.length, 0) + + // bad keyPair + const imposter = await create(t, { compat: false, manifest, keyPair: crypto.keyPair() }) + t.alike(imposter.key, key) + + t.ok(imposter.keyPair) + t.ok(imposter.writable) + + await t.exception(imposter.append('hello')) + + t.is(imposter.length, 0) + - t.is(core.length, 0) }) function createMultiManifest(signers, prologue = null) {