aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-cli
Commit message (Collapse)AuthorAgeFilesLines
* feat(auth): the recovery key never reaches the hubChristophe Besson23 hours2-16/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Ticking "also e-mail it to me" at registration sent the recovery key R in the register body, and the hub appended it to the verification e-mail: the hub saw R in clear on its way out, and the resend door — no captcha — let anyone who knew a pending username and address have the hub mail a "recovery key" of their choosing. The box is gone. The recovery screen offers "E-mail it to myself", a mailto: link that opens the person's own mail application with the key filled in; the desktop shell hands mailto: to the system (http, https and mailto only) and the Android shell to a mail application (ACTION_SENDTO). The CLI drops --email-recovery-key and prints the key, as before. The hub mails the code alone, and refuses a register that still carries a recovery_key rather than dropping it, so an older client offering the option cannot tell someone their key was sent when it was not. A mailbox holding R remains, with the reset code that reaches the same mailbox, enough to recover the account's identities; the link says so, and it is the person's choice. Checked in Chrome and Firefox (headless, the real page against a stubbed hub) and by the CLI's end-to-end registration against a local hub. The Android change was not built here, and the desktop link was not clicked in the application. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(chat): no thread_id — chat has no threadsChristophe Besson25 hours2-3/+3
| | | | | | | | | | | | | | Nothing ever set it (the page and the CLI sent null) and nothing read it (the node's get_thread had no caller). It is no longer sent by the page or the CLI, in clear or in the sealed payload, nor relayed or served by the node; get_thread and its index are gone, and the protocol and design docs no longer name it. The node still accepts a chat_msg carrying one, from the desktop apps and CLIs already installed, and drops it. The column stays, empty, in chat.db: a node downgraded to an older version names it in every query. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(cli): account, rm -r and mkdir, Tab completionChristophe Besson25 hours20-70/+2474
| | | | | | | | | | | | | | | | | | | | | | | | | account shows the account and does what the sign-up form and the Profile page do: register (the passphrase floor and the hub's proof of work checked here, the recovery key printed once), verify, change the passphrase, reset a forgotten one, change the e-mail address, sign out everywhere, delete. A new passphrase carries the copy of the account's keys each node keeps for browsers first — opened under the old M, the same keys sealed under the new one — and only then tells the hub; a refusal sets the copies back. A reset restores them from the recovery copy. The connections that do it never make keys nor ask for a device approval. This machine keeps the M it changed away from, so a node out of reach is carried at its next connection; a copy under an M it does not know is no longer rewritten, which locked the browsers out after a passphrase changed elsewhere. rm -r removes a folder and all it holds, from the node's operator key: the files, then the folders deepest first, one confirmation that counts them. mkdir makes folders, --parents the missing ones (not -p, the passphrase). completion bash|powershell prints the script that makes Tab complete actions, verbs, options and the paths of the groups this machine is signed in to, cached two minutes; the deb and rpm packages install the bash one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(cli): stream — a film or a song played in a media playerChristophe Besson27 hours9-9/+952
| | | | | | | | | | | | | | | `meshbay-cli stream PATH` serves one video or sound file over HTTP on 127.0.0.1 for VLC, mpv or any player that reads HTTP; `--player PROGRAM` starts the player, and closing it stops the stream, as Ctrl+C does. The file goes as the node stores it: no remux, no transcode, no stream slot on the node. Byte ranges are answered from leaseless file_req chunks decrypted in memory, eight ahead and the last 24 kept. Loopback only, a random token in the address, a foreign Host refused (DNS rebinding), an audio or video type with nosniff. The connection is pinged and reopened when it dies; a refusal by the node stops the stream (exit 5). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(cli): /put and /get in the interactive chatChristophe Besson28 hours7-9/+444
| | | | | | | | | | | | | | | | /put FILE sends one local file, relative to the current directory or absolute, into the chat's folder, then posts the application's attachment message naming it ({"text": "", "attachment": {filename, size, type}}), so the page shows it as its paperclip's. /get NAME saves a file of that folder, named from it, into the current directory, never over a file already there. The chat's folder is the page's rule: the operator's choice while its root is writable and present, else the first such root; a chat_directory_ack moves it. A line above the one written in shows the transfer's progress. Attachment messages, from the page or from /put, read as [file: name, size] in the room and in `chat`, and as an `attachment` field with --json. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(cli): help, and right-click copy and paste in the interactive chatChristophe Besson28 hours9-11/+378
| | | | | | | | | | | | | | | help prints what --help prints; help ACTION, what ACTION --help prints. In the interactive chat a right-click on the conversation copies the text selected with the mouse, else the line under the pointer: to the terminal (OSC 52) and to the platform's clipboard tool. A right-click on the line written in pastes the system clipboard's text at the cursor, its lines side by side, read with wl-paste, xclip or xsel, pbpaste or PowerShell, else what was copied here last. The conversation is selectable with the mouse, which RichLog alone is not. The deb and rpm packages recommend wl-clipboard or xclip for the paste. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(cli): chat --followChristophe Besson35 hours6-20/+313
| | | | | | | | | | | | chat GROUP --follow prints the last messages, then each one the node pushes, until Ctrl+C (exit 130). The connection is pinged every half minute; one that closes, fails or stops answering is opened again, and what was said meanwhile is read from the history. Each message is printed once, by its (device, nonce) pair, which the node stores once. With --json, one object per line. The man page lists it, with an example, and its FILES now names the device keys kept for the Tier 2 check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(cli): chat — Tier 2 check on the signing device, interactive roomChristophe Besson36 hours11-20/+750
| | | | | | | | | | | | | | | | Each message's signing device is checked against the group's roster as the page checks it (a port of transport-roster.js, held to it by the parity test): chains of countersignatures walked from each account's roots, the keys accepted per account and node kept in the store, the roster read again once before a key is called changed. Only "changed" is said, under the message; --json carries every verdict. chat with no group opens the interactive chat: the groups, then one group's conversation IRC-style with pushed messages arriving live and a line to write in; Esc or /part goes back to the groups, /quit or Ctrl+Q quits. Like the bare command, it opens on the sign-in screen when nothing is stored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(cli): chat — read a group's last messages, post oneChristophe Besson36 hours7-15/+473
| | | | | | | | | | | | | | chat GROUP prints the last ten messages, oldest first (-N, as head -N, or -n N for another count, paging back past the node's 200), and -m posts one (- reads it from stdin). The application's construction: every epoch key from chat_keys_req, a post sealed under the current epoch through the device subkey and signed with this machine's key on the node, the sender's name inside the envelope; nothing sent past the node's ciphertext bound. A stored message is read signature first, then key, then content, and one that fails is shown as unreadable, never dropped. Not done here: the Tier 2 roster check on the signing device. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(cli): search across groupsChristophe Besson36 hours6-4/+234
| | | | | | | | | | | | | search dials every group through the pool and matches each index here, on the Search page's fields (name, folder, title, artist, album), every word required. A group left out of Search by its operator (search_listed in the sealed ack) is skipped before its index is asked for. A file several groups hold is one result, keyed by its content hash, printed from the reader's own node first, as a path get takes. A group that cannot be searched is named and the others go on; one waiting for this machine's approval names its code instead of holding everything up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(cli): rm, and Delete in the interactive modeChristophe Besson37 hours10-12/+403
| | | | | | | | | | | | | rm deletes files, resolved as get resolves paths and patterns, with the node's rule (design §5.4): the uploading account's devices, or the node's operator account. The whole run is checked against the index first (the entry's uploader_id, the role the join result gives this key): a file outside the rule, or a folder, refuses it before anything is asked or sent. Then one confirmation, or --yes. The node's challenge is checked against what was asked before it is signed. In the interactive mode, Delete on the right pane does the same, asked once per batch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(cli): invitations, join, decline, leave, devices, browser accessChristophe Besson37 hours27-60/+1523
| | | | | | | | | | | | | | 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>
* docs: a browser is not linked as a deviceChristophe Besson38 hours1-1/+2
| | | | | | | | | | A browser keeps no identity between connections, so a key approved for it is gone by the next one: the guide, the design and the interface no longer offer it. With browser access off, the application and the command-line client open the account's groups; the linking form, shown in the application only, now says "this computer". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(client): link a device from the application; approve one match onlyChristophe Besson39 hours1-2/+176
| | | | | | | | | | | | | | | "Get a linking code" called the connection the page had just closed on the node's unknown_device refusal, so it never filed anything. It now retries with the request filed on that connection, before the proof (MNP 6.3), and the page tries the group again after each refusal until a linked device approves the code. Offered only in the desktop application: a browser's minted identity is gone by its next connection. Approving refuses a code that matches more than one pending request: filing needs only the account's token, so somebody holding the passphrase who saw a code could file their own keys under it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(cli): meshbay-cli, a command-line client for membersChristophe Besson39 hours46-0/+7484
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>