summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests/test_device_linking.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-10 17:30:22 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-10 17:30:22 +0200
commit803e654086ac63e2d01fa4eb9cca50a4ebebcb73 (patch)
tree8b79995745bdb19da7fb3ec33b55a68f8cc73676 /packages/meshbay-node/tests/test_device_linking.py
parent6cf21a019963468cb853e5c763ef0097115efa46 (diff)
downloadmeshbay-803e654086ac63e2d01fa4eb9cca50a4ebebcb73.tar.gz
fix(node): device messages are authenticated-only, and the code now says so
`device_add_request` and `device_hello` were dispatched behind `and self._nonce_node`, which reads as "pre-proof, once the challenge has gone out" — and is not what happens: both branches sit after the `self._user_id is None` guard, so the nonce is always set by the time either is reached, and a peer that has not finished its handshake gets "Handshake required" instead. The guard is removed rather than the branches moved. Filing a device is not something a peer needs *in order to* prove possession of the group key, which is the only reason anything is served pre-proof: the request is countersigned later by a device already pinned, so requiring the caller to finish its own handshake first costs nothing and keeps the pre-proof surface at three messages. A test drives all six device messages through the real dispatcher on an unauthenticated session, because this is a property of the order of its branches and of nothing else. Node suite 1216 passed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AsoWC3GmhNdwVFomW3QjH3
Diffstat (limited to 'packages/meshbay-node/tests/test_device_linking.py')
-rw-r--r--packages/meshbay-node/tests/test_device_linking.py26
1 files changed, 26 insertions, 0 deletions
diff --git a/packages/meshbay-node/tests/test_device_linking.py b/packages/meshbay-node/tests/test_device_linking.py
index 3580ff8..6d50580 100644
--- a/packages/meshbay-node/tests/test_device_linking.py
+++ b/packages/meshbay-node/tests/test_device_linking.py
@@ -82,6 +82,32 @@ async def _session(tmp_path: Path, roster, user_id: str = "alice"):
return session
+async def test_device_messages_need_an_authenticated_session(tmp_path, roster):
+ """
+ Filing a device is not a pre-proof message, and must not become one.
+
+ The pre-proof window exists for what a peer needs *in order to* prove
+ possession of the group key, and adding a device is not that: the request is
+ countersigned later by a device already pinned, so nothing is lost by
+ requiring the caller to finish its own handshake first. Left in the window it
+ would be a second thing a hub that forges a JWT could reach.
+
+ Driven through the real dispatcher, because this is a property of the order
+ of its branches and of nothing else.
+ """
+ session = await _session(tmp_path, roster)
+ session._user_id = None # challenged, has not proved anything yet
+ _sk, pk_ed, pk_x = _keys()
+
+ for mtype in ("device_add_request", "device_hello", "device_lookup",
+ "device_add", "device_list", "device_revoke"):
+ session.sent.clear()
+ session._dispatch_message({"type": mtype, "pk_ed25519": pk_ed,
+ "pk_x25519": pk_x})
+ assert _last(session) == {"type": "error",
+ "detail": "Handshake required"}, mtype
+
+
def _last(session):
return session.sent[-1] if session.sent else {}