aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-cli/src/meshbay_cli/commands/logout.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-14 22:20:15 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-14 22:20:15 +0200
commit422647e7898b8df67cd11f8fb060aec23dec84aa (patch)
tree7ecca0e8df1bc8a7d26cf4b471bd44906dd9cfd1 /packages/meshbay-cli/src/meshbay_cli/commands/logout.py
parent28c88908b88c58cba4de08710f6bb268ede02d57 (diff)
downloadmeshbay-422647e7898b8df67cd11f8fb060aec23dec84aa.tar.gz
feat(cli): meshbay-cli, a command-line client for members
Signs in to the hub, lists the account's groups and their folders, and downloads and uploads files directly with each group's node, end-to-end encrypted. With no argument it opens a two-pane interactive mode (Textual). Session and device keys are kept encrypted under the system's key storage, or a 0600 key file where there is none; node keys are pinned at first contact; a new machine links as a device. Packaged on its own on Linux (deb and rpm, on meshbay-common's venv, with a man page generated from the parser) and frozen next to meshbay-node in the full Windows installer, not the light one, with a self-test the build runs. client/keys.py ports keyderive.js and is LGPL like it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-cli/src/meshbay_cli/commands/logout.py')
-rw-r--r--packages/meshbay-cli/src/meshbay_cli/commands/logout.py43
1 files changed, 43 insertions, 0 deletions
diff --git a/packages/meshbay-cli/src/meshbay_cli/commands/logout.py b/packages/meshbay-cli/src/meshbay_cli/commands/logout.py
new file mode 100644
index 0000000..7ee3aa2
--- /dev/null
+++ b/packages/meshbay-cli/src/meshbay_cli/commands/logout.py
@@ -0,0 +1,43 @@
+"""`logout`: end the session on the hub, retire this machine's key, erase the store."""
+
+import json
+
+from ..client.account import Account, no_passphrase
+from ..client.hub import Hub
+from ..errors import CliError
+from ..output import err, sentence
+from .context import Context
+
+HELP = "end the session, retire this machine's device key and erase what is stored"
+
+
+def add_parser(sub, parent) -> None:
+ sub.add_parser("logout", parents=[parent], help=HELP, description=sentence(HELP) + ".")
+
+
+async def sign_out_stored(ctx: Context) -> None:
+ """Whatever account the store holds, on whatever hub. Never asks anything."""
+ stored = ctx.store.peek()
+ hub = ctx.hub if stored.get("hub") == ctx.hub.url else Hub(stored.get("hub", ""))
+ try:
+ account = Account.open(hub, None, no_passphrase, ctx.store)
+ warnings = await account.sign_out()
+ except CliError as e:
+ warnings = [f"The saved session could not be opened ({e.message}); it is erased "
+ "here, and ends on the hub when it expires."]
+ with ctx.store.locked():
+ ctx.store.erase()
+ finally:
+ if hub is not ctx.hub:
+ await hub.aclose()
+ for w in warnings:
+ err(f"meshbay-cli: warning: {w}")
+
+
+async def run(ctx: Context) -> int:
+ if not ctx.store.peek():
+ print(json.dumps({"signed_out": False}) if ctx.args.json else "Not signed in.")
+ return 0
+ await sign_out_stored(ctx)
+ print(json.dumps({"signed_out": True}) if ctx.args.json else "Signed out.")
+ return 0