aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-common/tests/test_webcrypto.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-08-11 14:55:52 +0200
committerChristophe Besson <cbesson@gmail.com>2026-08-11 14:55:52 +0200
commitcc90dc943fcd0e7bbf52674fb3f95ff097026f4a (patch)
tree6315a5e966c027c50b92d59e60c4b506a418143e /packages/meshbay-common/tests/test_webcrypto.py
parentedde9e441fb6b84e9d56215d6e2a8d9338b8f962 (diff)
downloadmeshbay-cc90dc943fcd0e7bbf52674fb3f95ff097026f4a.tar.gz
feat: Phase 10b — Self-service UI (group create/join, upload, IndexedDB, search)
Six self-service features for the web SPA: - Group creation UI with GEK auto-generation (AES-256-GCM ECIES) - Member management + invite by username (GEK wrapping for invitee) - Open group self-join flow (POST /v1/groups/{id}/join) - File upload client→node (FILE_UPLOAD MNP type, .uploads/ staging) - IndexedDB caching of group file indexes (instant display on revisit) - Cross-group file search (SearchPage, pure client-side on cached indexes) 11 new tests (166 total): 8 group self-service + 3 AES GEK wrap/unwrap. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-common/tests/test_webcrypto.py')
-rw-r--r--packages/meshbay-common/tests/test_webcrypto.py42
1 files changed, 42 insertions, 0 deletions
diff --git a/packages/meshbay-common/tests/test_webcrypto.py b/packages/meshbay-common/tests/test_webcrypto.py
index 25bcd5c..2ed6405 100644
--- a/packages/meshbay-common/tests/test_webcrypto.py
+++ b/packages/meshbay-common/tests/test_webcrypto.py
@@ -44,3 +44,45 @@ def test_aes_chunk_keys_unique_per_chunk():
fh = blake3.blake3(data).digest()
keys = {chunk_key_aes(gek, fh, i) for i in range(5)}
assert len(keys) == 5 # all distinct
+
+
+def test_aes_gek_wrap_unwrap_roundtrip():
+ from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
+ from meshbay_common.crypto import (
+ wrap_gek_aes, unwrap_gek_aes, sk_to_raw, pk_to_raw,
+ )
+ gek = generate_gek()
+ sk = X25519PrivateKey.generate()
+ pk_raw = pk_to_raw(sk.public_key())
+ sk_raw = sk_to_raw(sk)
+
+ bundle = wrap_gek_aes(gek, pk_raw)
+ recovered = unwrap_gek_aes(bundle, sk_raw, pk_raw)
+ assert recovered == gek
+
+
+def test_aes_gek_wrap_wrong_key_rejected():
+ from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
+ from meshbay_common.crypto import wrap_gek_aes, unwrap_gek_aes, sk_to_raw, pk_to_raw
+
+ gek = generate_gek()
+ sk_a = X25519PrivateKey.generate()
+ sk_b = X25519PrivateKey.generate()
+
+ bundle = wrap_gek_aes(gek, pk_to_raw(sk_a.public_key()))
+ with pytest.raises(Exception):
+ unwrap_gek_aes(bundle, sk_to_raw(sk_b), pk_to_raw(sk_b.public_key()))
+
+
+def test_aes_gek_wrap_differs_from_chacha_wrap():
+ from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
+ from meshbay_common.crypto import (
+ wrap_gek, wrap_gek_aes, pk_to_raw,
+ )
+ gek = generate_gek()
+ sk = X25519PrivateKey.generate()
+ pk_raw = pk_to_raw(sk.public_key())
+
+ bundle_aes = wrap_gek_aes(gek, pk_raw)
+ bundle_chacha = wrap_gek(gek, pk_raw)
+ assert bundle_aes["wrapped_b64"] != bundle_chacha["wrapped_b64"]