From b1ebcdeb9082457972c41a47e77494902335d262 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Wed, 30 Sep 2026 17:13:40 +0200 Subject: feat: browser access, decided in the desktop application Off for an account made there: its identities stay on the device and nothing is left on nodes. Turned on from the Profile page behind a native confirmation; each node is settled when its group next opens. The hub keeps a mirror a browser reads to say why a group will not open; it grants nothing. Co-Authored-By: Claude Opus 5.5 --- packages/meshbay-hub/tests/test_bundle_pepper.py | 16 ++++++++++++++++ packages/meshbay-hub/tests/test_desktop_shell.py | 21 +++++++++++++++++++++ 2 files changed, 37 insertions(+) (limited to 'packages/meshbay-hub/tests') diff --git a/packages/meshbay-hub/tests/test_bundle_pepper.py b/packages/meshbay-hub/tests/test_bundle_pepper.py index e99799f..be9da19 100644 --- a/packages/meshbay-hub/tests/test_bundle_pepper.py +++ b/packages/meshbay-hub/tests/test_bundle_pepper.py @@ -167,3 +167,19 @@ async def test_it_is_never_logged(client): lg.disabled = disabled assert seen, "the handler saw nothing, so it proves nothing" assert not any(login["bundle_pepper"] in m for m in seen) + + +@pytest.mark.asyncio +async def test_the_browser_access_mirror_is_a_preference_like_any_other(client): + """The desktop application writes what it holds, and a browser reads it to + say why it cannot open a group. Nothing on the hub or a node acts on it.""" + await _register(client, "pepper_mirror") + login = await _login(client, "pepper_mirror") + headers = _bearer(login["access_token"]) + r = await client.put("/v1/users/me/preferences/browser_access", headers=headers, + json={"value": "off"}) + assert r.status_code == 200, r.text + prefs = (await client.get("/v1/users/me/preferences", headers=headers)).json() + assert prefs["browser_access"] == "off" + # Still handed the pepper: the mirror decides nothing. + assert "bundle_pepper" in await _login(client, "pepper_mirror") diff --git a/packages/meshbay-hub/tests/test_desktop_shell.py b/packages/meshbay-hub/tests/test_desktop_shell.py index 6e1c634..4426dd7 100644 --- a/packages/meshbay-hub/tests/test_desktop_shell.py +++ b/packages/meshbay-hub/tests/test_desktop_shell.py @@ -446,6 +446,17 @@ def test_the_native_dialogs_are_worded_in_every_language(): assert not missing, f"{catalogue.name} lacks {missing}" +def test_browser_access_is_widened_only_by_the_person_natively(): + """Turning it on puts every identity of the account on every node, for a + browser to open: the application asks, in a dialog the page cannot + answer. What the page may say unasked only narrows it.""" + source = _main() + widen = source.split("handle('keys:set-browser-access'", 1)[1].split("\n handle(", 1)[0] + assert "confirmOrRefuse('native.browser_access_confirm')" in widen + here = source.split("handle('keys:created-here'", 1)[1].split("\n", 1)[0] + assert "setBrowserAccess(uid(u), false)" in here + + def test_the_node_is_never_pointed_at_a_hub_the_page_names(): """`node:start` writes the hub this application is signed in to, and a username that cannot break out of a TOML string.""" @@ -680,3 +691,13 @@ def test_hardware_decoding_can_be_turned_off_without_a_rebuild(): catch needs an answer that is not "reinstall": config.json, the same file every other client setting lives in.""" assert "config.videoAcceleration" in _main() + + +def test_an_account_made_in_the_application_starts_without_browser_access(): + """Registration tells the application, which then leaves nothing of the + account's identities on any node until the person turns it on.""" + auth = (STATIC / "auth-page.js").read_text(encoding="utf-8") + register = auth.split("const reg = await window.MeshBayKeys.registerUser(", 1)[1][:900] + assert "platform.keys.createdHere(reg.userId)" in register + assert "userId" in (STATIC / "keyderive.js").read_text(encoding="utf-8").split( + "async function registerUser", 1)[1].split("\n}\n", 1)[0] -- cgit v1.2.3