diff options
Diffstat (limited to 'packages')
5 files changed, 86 insertions, 70 deletions
diff --git a/packages/meshbay-common/src/meshbay_common/__init__.py b/packages/meshbay-common/src/meshbay_common/__init__.py index 216a18f..842c52d 100644 --- a/packages/meshbay-common/src/meshbay_common/__init__.py +++ b/packages/meshbay-common/src/meshbay_common/__init__.py @@ -241,5 +241,13 @@ __version__ = "0.16.0" # `invite_link_result` and `invite_cancel`, a code bound to no account until it # is redeemed. Additive in the same way — a 3.3 node answers `unknown message # type`, and no client can hold a link code for a node that could not issue one. -MNP_VERSION = "3.4" +# +# 4.0 (2026-09-25) is a MAJOR — a change to what a peer must *present*, not an +# additive message (§5.6). A member now authenticates to a node with a +# short-lived MNP-audience token (aud=MNP_AUD), never its hub session token: the +# node operator holds whatever is presented, and the session token opens the hub +# API. A pre-4.0 client presents the session token and is refused at the +# handshake — there is no compatibility branch, because leaving one would keep +# the disclosure reachable on every node. So the floor moves with it. +MNP_VERSION = "4.0" MHP_VERSION = "0.1" diff --git a/packages/meshbay-common/src/meshbay_common/handshake.py b/packages/meshbay-common/src/meshbay_common/handshake.py index 2393df1..dedfeb1 100644 --- a/packages/meshbay-common/src/meshbay_common/handshake.py +++ b/packages/meshbay-common/src/meshbay_common/handshake.py @@ -85,7 +85,11 @@ CHALLENGE_PREFIX = b"meshbay:mnp:challenge:v1" # has no vocabulary to understand — or serving it outside every cap the operator # set, which makes the caps decoration. Neither is honest, so it is refused # here, with a code and a sentence. -MNP_MIN_SUPPORTED = "3.0" +# 4.0 (2026-09-25): a member authenticates with an MNP-audience token, not the +# hub session token (MNP_VERSION note). A pre-4.0 peer presents the session +# token, which this node now refuses — so the floor moves to 4.0 rather than +# leaving a branch that would keep a hub credential reachable by every node. +MNP_MIN_SUPPORTED = "4.0" ROLE_CLIENT = "client" ROLE_NODE = "node" diff --git a/packages/meshbay-hub/src/meshbay_hub/api/hub.py b/packages/meshbay-hub/src/meshbay_hub/api/hub.py index cab60c8..efebc4d 100644 --- a/packages/meshbay-hub/src/meshbay_hub/api/hub.py +++ b/packages/meshbay-hub/src/meshbay_hub/api/hub.py @@ -78,8 +78,13 @@ async def hub_pubkey(): # handshake refusal anyway. The operator is updating every client, node and hub # by hand for this flag day, which is what makes that acceptable exactly once. # The gate is in place for the next one, where it will work as intended. -MIN_CLIENT_VERSION = "0.13.0" -RECOMMENDED_CLIENT_VERSION = "0.13.0" +# +# 0.16.0 is the MNP 4.0 flag day: a client older than this presents its hub +# session token to a node, which a 4.0 node refuses. A desktop client below +# 0.16.0 is told to update *before* it connects rather than meeting a handshake +# refusal it cannot read; the browser reloads this build from the hub. +MIN_CLIENT_VERSION = "0.16.0" +RECOMMENDED_CLIENT_VERSION = "0.16.0" @router.get("/version") diff --git a/packages/meshbay-hub/src/meshbay_hub/static/transport.js b/packages/meshbay-hub/src/meshbay_hub/static/transport.js index 27edc4e..f3683eb 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/transport.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/transport.js @@ -305,16 +305,15 @@ window.addEventListener('hashchange', () => { // The `v: '0.1'` on every other message in this file is the historical value // and is read by nothing; it is left alone deliberately. The range is // negotiated once, at the start, not restated per message. -const MNP_V = '3.1'; -// **Not** raised with it, and that is the whole difference between 3.0 and 3.1. -// 3.0 was a flag day because a node older than it cannot grant the lease this -// client opens for every download and upload, so talking to one would mean -// every transfer failing for a reason the person cannot act on. 3.1 only adds -// `user_blob_*`: a 3.0 node answers "unknown message type" and the client -// stores its playlists on the next node it reaches, keeping its own copy -// meanwhile (docs/playlists.md §6.4). Refusing every 3.0 node over a feature -// that degrades this quietly would be the flag day nobody needed. -const MNP_V_MIN = '3.0'; +const MNP_V = '4.0'; +// Raised with it: 4.0 is a flag day. A member now presents a short-lived +// MNP-audience token in the handshake, not its hub session token — a node +// older than 4.0 expected the session token, and one newer refuses it, so the +// two cannot authenticate across the break. This is the C6 rule: no +// compatibility branch, or the old path (a hub credential handed to a node) +// stays reachable. The desktop client is gated by client.minimum before it +// even connects; the browser picks up this build on reload. +const MNP_V_MIN = '4.0'; // Codes a NODE sends us, in its own vocabulary (meshbay_common/handshake.py's // check_version): `version_too_old` means *we* are too old for it, diff --git a/packages/meshbay-node/tests/golden/dispatch.json b/packages/meshbay-node/tests/golden/dispatch.json index 98911f5..5d15057 100644 --- a/packages/meshbay-node/tests/golden/dispatch.json +++ b/packages/meshbay-node/tests/golden/dispatch.json @@ -2228,7 +2228,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -2551,7 +2551,7 @@ "subject": "gggggggggggggggggggggggggggggggg", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -2570,7 +2570,7 @@ "subject": "['x']", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -2589,7 +2589,7 @@ "subject": "7", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -2608,7 +2608,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -2878,7 +2878,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -2892,7 +2892,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -2906,7 +2906,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -2920,7 +2920,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -2934,7 +2934,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -2948,7 +2948,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -2962,7 +2962,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -2976,7 +2976,7 @@ "messages": [], "req_id": 4242, "type": "chat_hist_resp", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -8855,7 +8855,7 @@ "subject": "gggggggggggggggggggggggggggggggg", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -8874,7 +8874,7 @@ "subject": "['x']", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -8893,7 +8893,7 @@ "subject": "7", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -8912,7 +8912,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -9247,7 +9247,7 @@ "subject": "['x']", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -9266,7 +9266,7 @@ "subject": "7", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -9285,7 +9285,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -9620,7 +9620,7 @@ "subject": "['x']", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -9639,7 +9639,7 @@ "subject": "7", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -9658,7 +9658,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -11961,7 +11961,7 @@ "subject": "link:gggggggggggggggggggggggggggggggg", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -14060,7 +14060,7 @@ "subject": "['x']", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -14079,7 +14079,7 @@ "subject": "7", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -14098,7 +14098,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -14433,7 +14433,7 @@ "subject": "['x']", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -14452,7 +14452,7 @@ "subject": "7", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -14471,7 +14471,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -16532,7 +16532,7 @@ "req_id": 4242, "token": null, "type": "pong", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -16547,7 +16547,7 @@ "x" ], "type": "pong", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -16560,7 +16560,7 @@ "req_id": 4242, "token": 7, "type": "pong", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -16573,7 +16573,7 @@ "req_id": 4242, "token": "x", "type": "pong", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -16586,7 +16586,7 @@ "req_id": 4242, "token": null, "type": "pong", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -16601,7 +16601,7 @@ "x" ], "type": "pong", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -16614,7 +16614,7 @@ "req_id": 4242, "token": 7, "type": "pong", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -16627,7 +16627,7 @@ "req_id": 4242, "token": "x", "type": "pong", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -16962,7 +16962,7 @@ "subject": "['x']", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -16981,7 +16981,7 @@ "subject": "7", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -17000,7 +17000,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -17335,7 +17335,7 @@ "subject": "['x']", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -17354,7 +17354,7 @@ "subject": "7", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -17373,7 +17373,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -17708,7 +17708,7 @@ "subject": "['x']", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -17727,7 +17727,7 @@ "subject": "7", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -17746,7 +17746,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -18081,7 +18081,7 @@ "subject": "['x']", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -18100,7 +18100,7 @@ "subject": "7", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -18119,7 +18119,7 @@ "subject": "x", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -18454,7 +18454,7 @@ "subject": "['x']:rw=on,rem=on", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -18473,7 +18473,7 @@ "subject": "7:rw=on,rem=on", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -18492,7 +18492,7 @@ "subject": "x:rw=on,rem=on", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -21439,7 +21439,7 @@ "subject": "custom_token=no,language=default", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -21482,7 +21482,7 @@ "subject": "custom_token=yes,language=x", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] @@ -23369,7 +23369,7 @@ "subject": "d=7,u=7", "ts": "<volatile>", "type": "admin_challenge", - "v": "3.4" + "v": "4.0" } ], "spawned": [] |