diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-10-15 00:56:04 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-10-15 00:56:04 +0200 |
| commit | 6f68bb6c1970e26de1f66c073ea5d7fecd21840d (patch) | |
| tree | 859c74db5819f1d49046e71a53e12afe5eb4193a /packages/meshbay-cli/src/meshbay_cli/commands/browser_access.py | |
| parent | 16d92c96bde3a65fc54a93b4662df30cafc831e4 (diff) | |
| download | meshbay-6f68bb6c1970e26de1f66c073ea5d7fecd21840d.tar.gz | |
feat(cli): invitations, join, decline, leave, devices, browser access
join accepts an invitation or redeems a link pasted as sent, then has the
node admit a key pair made here, with the invitation's code (a link's code
goes only to the node it names; one for a node that is away is kept for the
next connection). decline, leave and devices revoke ask first, and refuse
without --yes where there is no terminal. devices approve countersigns the
one waiting request a code matches, none when several do. browser-access is
the application's setting, kept per machine and never enabled from the hub's
mirror: on leaves a copy sealed under M on each node, off withdraws it,
unset touches nothing. A key pair made for a first contact is now kept.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-cli/src/meshbay_cli/commands/browser_access.py')
| -rw-r--r-- | packages/meshbay-cli/src/meshbay_cli/commands/browser_access.py | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/packages/meshbay-cli/src/meshbay_cli/commands/browser_access.py b/packages/meshbay-cli/src/meshbay_cli/commands/browser_access.py new file mode 100644 index 0000000..e2b0b8e --- /dev/null +++ b/packages/meshbay-cli/src/meshbay_cli/commands/browser_access.py @@ -0,0 +1,72 @@ +""" +`browser-access`: whether this machine leaves, on each node, a copy of its keys +a browser can open with the passphrase — the application's Profile → Browser +access, kept by this machine (docs/MESHBAY_DESIGN.md §3.7). + +`on`: each group opened here leaves a copy sealed under the passphrase-derived +key, when its node holds none or an outdated one. `off`: the copy a node holds +is withdrawn. Never set: nothing is written or withdrawn, so a CLI nobody +configured never undoes what the application of another computer does. + +Set here and nowhere else. The hub keeps a mirror of it, written here as the +application writes it, but a mirror anyone with a hub session can write must +never make this machine upload keys: read, it only produces a message. +""" + +import json + +from ..client.hub import HubError +from ..errors import AUTH, CliError +from ..output import err, sentence +from .context import Context + +HELP = "whether a browser may open your groups: leave a copy of your keys on nodes, or not" + +EFFECT = { + "on": "Each group opened here from now on leaves a copy of your keys on its node, " + "sealed under your passphrase, so that a browser can open it.", + "off": "Each group opened here from now on withdraws the copy of your keys its node " + "holds; a browser will no longer open it with your passphrase.", +} + + +def add_parser(sub, parent) -> None: + p = sub.add_parser("browser-access", parents=[parent], help=HELP, + description=sentence(HELP) + ". As the application's Browser " + "access, for this machine. With no argument, shows the setting.") + p.add_argument("state", nargs="?", choices=("on", "off")) + + +async def run(ctx: Context) -> int: + a = ctx.args + account = ctx.account() + if not account.remembered: + raise CliError(AUTH, "This setting is kept with the saved session; run " + "`meshbay-cli login` first.") + if a.state is None: + try: + mirror = (await account.call(account.hub.preferences)).get("browser_access") + except (HubError, CliError): + mirror = None + mine = account.browser_access + if a.json: + print(json.dumps({"this_machine": mine, "hub": mirror})) + else: + print(f"This machine: {mine or 'not set (leaves the nodes as they are)'}") + print(f"The hub's copy: {mirror or 'none'} (informative: it sets nothing here)") + return 0 + + def put(state: dict, secrets: dict) -> None: + state["browser_access"] = a.state + await account.update(put) + try: + await account.call(account.hub.set_preference, "browser_access", a.state) + except (HubError, CliError) as e: + err(f"meshbay-cli: warning: the hub's copy of the setting was not updated " + f"({getattr(e, 'detail', None) or getattr(e, 'message', e)}); a browser may " + "explain a closed group less well.") + if a.json: + print(json.dumps({"this_machine": a.state})) + else: + print(f"Browser access: {a.state}. {EFFECT[a.state]}") + return 0 |