aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/tests/test_spa_ordering.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-30 15:06:14 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-30 15:06:14 +0200
commit91297944791a36f30302ef8c86dd69ebeb177671 (patch)
tree568188114baf438059458f1bc87903f4894cec90 /packages/meshbay-hub/tests/test_spa_ordering.py
parenta55d40b74bda77dff6ec565abdd551607fc665d6 (diff)
downloadmeshbay-91297944791a36f30302ef8c86dd69ebeb177671.tar.gz
feat: bundles sealed per node under the passphrase and the hub's pepper
The session key is M = HKDF(Argon2(passphrase) || pepper, account id); each node's bundle key and the playlist key derive from it. Bundles are MBK3, bound to account and node; MBK1/MBK2 are refused by name, never replaced silently. Playlists move to key v2 and are re-sealed over unreadable node copies. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/tests/test_spa_ordering.py')
-rw-r--r--packages/meshbay-hub/tests/test_spa_ordering.py17
1 files changed, 17 insertions, 0 deletions
diff --git a/packages/meshbay-hub/tests/test_spa_ordering.py b/packages/meshbay-hub/tests/test_spa_ordering.py
index fdedaf8..6f28aaa 100644
--- a/packages/meshbay-hub/tests/test_spa_ordering.py
+++ b/packages/meshbay-hub/tests/test_spa_ordering.py
@@ -91,6 +91,23 @@ def test_keys_are_recovered_before_the_join_is_attempted():
"browser that did not register has no key to sign the join with")
+def test_a_bundle_is_opened_with_the_key_the_node_has_already_proved():
+ """
+ A bundle is sealed for one account on one node: its key derives from the
+ node's public key and its associated data names both. That key has to be
+ the one the challenge signature proved — recorded before the bundle is
+ fetched — or a bundle would be opened, or a new one sealed, for nothing.
+ """
+ proved, user, sealed_for, fetch = _positions(
+ "this.nodePk = reply.node_pk",
+ "this._userId = userId",
+ "const sealedFor = { userId: this._userId, nodePk: this.nodePk }",
+ "type: 'keypair_bundle_fetch'",
+ )
+ assert proved < sealed_for < fetch
+ assert user < sealed_for
+
+
def test_the_ack_still_verifies_the_announced_node_key():
"""
Taking node_pk from the challenge is only safe because the ack proves it and