aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/tests/test_playlist_store.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_playlist_store.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_playlist_store.py')
-rw-r--r--packages/meshbay-hub/tests/test_playlist_store.py21
1 files changed, 15 insertions, 6 deletions
diff --git a/packages/meshbay-hub/tests/test_playlist_store.py b/packages/meshbay-hub/tests/test_playlist_store.py
index 701de41..3c1d109 100644
--- a/packages/meshbay-hub/tests/test_playlist_store.py
+++ b/packages/meshbay-hub/tests/test_playlist_store.py
@@ -272,16 +272,25 @@ def test_a_node_holding_something_unreadable_does_not_wedge_the_sync(steps):
assert "Depuis le menu" in s["names"]
-def test_a_session_from_before_the_hkdf_handle_degrades_rather_than_failing(steps):
- """A bundle key loaded out of IndexedDB from before `deriveBundleKeys`
- existed has no HKDF handle, and the passphrase is not in memory to
- re-derive from. Playlists stay local until the next sign-in — reported,
- rather than silently doing nothing."""
- r = steps["a session from before the HKDF handle"]["result"]
+def test_a_session_from_before_the_pepper_degrades_rather_than_failing(steps):
+ """A bundle key from before the pepper opens nothing, and the passphrase
+ is not in memory to re-derive from. Playlists stay local until it is
+ entered again — reported, rather than silently doing nothing."""
+ r = steps["a session from before the pepper"]["result"]
assert r["ok"] is False and r["reason"] == "no_key"
assert r["pushed"] == 0
+def test_a_node_sealed_under_the_previous_key_is_sealed_again(steps):
+ """After the playlist key changed, every row on a node has the revision the
+ local copy has. All of it is sealed again under the current key, no
+ revision goes down, and a body nothing here can name is dropped."""
+ s = steps["a node sealed under the previous key"]
+ assert s["readable"] == s["kinds"], "a row is still sealed under the old key"
+ assert s["remaining"] == s["kinds"], "the unknown body was not dropped"
+ assert s["revsNotLowered"] is True
+
+
def test_what_a_playlist_costs_sealed_is_measured_not_quoted(steps):
"""The ceiling the UI promises comes from here, not from the design doc.