diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/MESHBAY_DESIGN.md | 15 | ||||
| -rw-r--r-- | docs/QUICKSTART.md | 380 | ||||
| -rw-r--r-- | docs/USERGUIDE.md | 861 |
3 files changed, 1252 insertions, 4 deletions
diff --git a/docs/MESHBAY_DESIGN.md b/docs/MESHBAY_DESIGN.md index dcfc77b..551c0ed 100644 --- a/docs/MESHBAY_DESIGN.md +++ b/docs/MESHBAY_DESIGN.md @@ -30,6 +30,8 @@ | Read | For | |---|---| | **this document** | the architecture, the trust model, and the reason each decision is what it is | +| `QUICKSTART.md` | one machine to a working group, for somebody who has installed nothing | +| `USERGUIDE.md` | using a group and running a node, for the person who does either | | `MESHBAY_NODE_PROTOCOL.md` | the MNP wire format, message by message | | `transfers-v1.md` | the transfer system's failure-mode analysis, kept because a synthesis cannot carry "every way a slot can be lost" | | `playlists.md` | the playlist design and its interface in full, with what building it corrected (§9.10) | @@ -38,10 +40,15 @@ | `PACKAGING-GUIDE.md`, `HTTPS.md`, `MAIL-SERVER.md`, `windows-build.md` | installation and server operations | | `CLAUDE.md` | project conventions and the engineering lessons that govern how changes are made | -**There is no user guide.** The one that existed described the system before -per-node identity, named roots and the sealed wire, and was retired rather than -repaired — a document a reader cannot tell the sound parts of is worse than none. -Writing a new one starts here. +**The user documentation is `QUICKSTART.md` and `USERGUIDE.md`** (written +2026-09-18). The guide that preceded them described the system before per-node +identity, named roots and the sealed wire, and was retired rather than repaired +— a document a reader cannot tell the sound parts of is worse than none. The +replacements are written from this document and from the code, address a reader +who is not a developer, and cover Linux and the browser; Windows stays in +`PACKAGING-GUIDE.md`. **They state what is not built as readily as what is** +(§15.2, §15.3), which is what keeps them from drifting into the same condition +as the one they replace. ### 0.2 Reference labels diff --git a/docs/QUICKSTART.md b/docs/QUICKSTART.md new file mode 100644 index 0000000..9a418f2 --- /dev/null +++ b/docs/QUICKSTART.md @@ -0,0 +1,380 @@ +# MeshBay — Quickstart + +This guide takes one Linux machine, turns it into a MeshBay node, creates a +group over a directory on it, and invites a second person. It assumes you can +use a terminal. It assumes nothing else. + +For what each step *means* — and for everything this guide leaves out — read +[`USERGUIDE.md`](USERGUIDE.md). + +> **Scope.** Linux only: Ubuntu/Debian and Fedora. Windows is covered by +> [`PACKAGING-GUIDE.md`](PACKAGING-GUIDE.md) and is not repeated here. This +> guide uses **meshbay.org** as the hub; running your own is +> [`PACKAGING-GUIDE.md`](PACKAGING-GUIDE.md) plus [`HTTPS.md`](HTTPS.md) and +> [`MAIL-SERVER.md`](MAIL-SERVER.md). + +--- + +## What you are building + +``` + your machine meshbay.org your friend + ──────────── ─────────── ─────────── + meshbay-node ◄─── signalling ────► hub ◄─── sign-in ───► browser + holds the files accounts, or desktop + holds the group key group list, client + decides who is served introductions + │ │ + └──────────── encrypted, peer to peer, direct ──────────────────┘ + (your files never touch the hub) +``` + +Three things, and it is worth knowing which is which before you start: + +| | What it is | +|---|---| +| **The hub** | An address book and a switchboard. It holds your account and your group's name, and introduces two machines to each other. It never sees a file, a message or a key. | +| **The node** | A daemon on *your* machine. It holds the directories you share and the key that encrypts them. It decides who gets served. This is the part you install. | +| **The client** | The web app the hub serves, or the desktop application. This is what you and your members look at. | + +--- + +## Before you start + +- [ ] **A Linux machine that stays on.** Your files are served from it, so a + laptop that sleeps is a group that is offline half the time. A spare + mini-PC, a home server or an always-on desktop is the right shape. +- [ ] **A directory to share**, with something in it. +- [ ] **An email address** you can read — account sign-up sends a code to it. +- [ ] **About half an hour**, plus however long a first index takes — which + depends on how much you are sharing, and does not need watching. +- [ ] **Terminal access** to that machine. Everything below works over SSH; no + graphical session is needed on the node. + +You do **not** need a static IP, a domain name, port forwarding, or a router +you control. Two residential ISPs have been measured working without any of it. + +--- + +## Step 1 — Download the packages + +From **https://meshbay.org/downloads**, take the ones for your +distribution: + +| | Ubuntu / Debian | Fedora | +|---|---|---| +| **`meshbay-common`** — required, install it first | `.deb` | `.rpm` | +| **`meshbay-node`** — the daemon that hosts your files | `.deb` | `.rpm` | +| `meshbay-client` — the desktop application, optional | `.deb` | `.rpm` | + +You need the first two. The desktop application is worth having if this machine +has a screen, but nothing in this guide requires it: a terminal and a browser +are enough. + +Put them in one directory — the next step installs them together. + +--- + +## Step 2 — Install + +Install **with your package manager, not with `dpkg -i` / `rpm -ivh`**. Both of +those ignore weak dependencies, and the video drivers that let this machine +re-encode a film without melting are weak dependencies. + +```bash +cd ~/Downloads # wherever you put them + +# Ubuntu / Debian +sudo apt install ./meshbay-common_*.deb ./meshbay-node_*.deb + +# Fedora +sudo dnf install ./meshbay-common-*.rpm ./meshbay-node-*.rpm +``` + +Add `./meshbay-client_*` to that line to install the desktop application too. + +`meshbay-common` carries everything the others need, so there is nothing else +to install and no Python environment to set up. **ffmpeg**, required for video +streaming, comes in as a recommended dependency of the command above; without +it the node refuses to start and says so. + +Check it landed: + +```bash +meshbay-node status +``` + +It will report that there is no keystore. That is the next step. + +--- + +## Step 3 — Create your account + +Open **https://meshbay.org** in a browser and register. + +Three things on that page are worth slowing down for: + +1. **Your passphrase is not a password.** It never reaches the hub. It + encrypts the copy of your identity keys that lives on every node you join, + and nobody — not the hub, not an operator, not us — can reset it. The floor + is 12 characters; **four unrelated words** is the shape that actually works. +2. **Your recovery key is shown exactly once.** It is a 32-byte secret that can + restore your access to your groups if you forget the passphrase. Put it in a + password manager before clicking past it. Lose both it and the passphrase and + your files are still there — but every group has to be rejoined by hand, with + a new identity. +3. **Verify your email.** A code arrives; the account is inactive until you + enter it. + +--- + +## Step 4 — Set up the node + +Back on the node machine: + +```bash +meshbay-node init +``` + +It asks for the hub URL (press Enter for `https://meshbay.org`) and your hub +username. Then it writes `~/.config/meshbay/node.toml`, creates the keystore, +and prints something like: + +``` +Node key: 7mK2p...base64...= +``` + +**Copy that key.** In your browser, on meshbay.org: **Settings → Link Node**, +paste it, submit. + +This is what lets the hub introduce your members to this machine. It is a +public key; it identifies the node and unlocks nothing. + +--- + +## Step 5 — Start the node + +```bash +systemctl --user enable --now meshbay-node +loginctl enable-linger $USER # keep serving when you are not logged in +``` + +`enable-linger` is not optional on a machine you reach over SSH. Without it, +systemd stops your user services when your session ends — the group goes dark +the moment you disconnect. + +Check: + +```bash +meshbay-node status +``` + +You want to see `daemon running`. If not: + +```bash +journalctl --user -u meshbay-node -f +``` + +### If your files live outside your home directory + +The node unit is hardened: it can only write inside `~/.config/meshbay` and +`~/.local/share/meshbay`. An external drive or a second partition needs a +drop-in, and it needs **both** lines: + +```bash +mkdir -p ~/.config/systemd/user/meshbay-node.service.d +cat > ~/.config/systemd/user/meshbay-node.service.d/paths.conf <<'EOF' +[Service] +ReadWritePaths=/mnt/library +RequiresMountsFor=/mnt/library +EOF +systemctl --user daemon-reload +systemctl --user restart meshbay-node +``` + +`RequiresMountsFor` matters as much as `ReadWritePaths`. The service runs in its +own mount namespace, so a volume mounted *after* it started is invisible to it — +and the symptom is a directory that reads as empty while everything else looks +correct. + +--- + +## Step 6 — Create the group + +In the browser, on meshbay.org: **Create group** in the sidebar. + +- **Name** — anything. It is shown to members as `name@yourusername`. +- **Join policy** — leave it on **Invite only**. The alternative, *Open*, lists + the group publicly and lets anyone in, including the hub. There are groups + that want that; a first one is not it. +- **Description** — optional, shown to members on their home page. + +The group now exists on the hub and has no files, no key and no host. The next +step is all three. + +--- + +## Step 7 — Hand the group to your node + +Back on the node machine. Use the same name you just typed: + +```bash +meshbay-node group add "Family Photos" --dir ~/Pictures/shared +meshbay-node reload +meshbay-node gek init --group "Family Photos" +``` + +What those three did: + +| | | +|---|---| +| `group add` | told the node to host that group, and made the directory its first shared folder. It is **read-write** by default, so members can upload into it. Add `--no-writable` if you want a published, read-only library. | +| `reload` | made the running daemon re-read its config without dropping anyone. | +| `gek init` | generated the group's encryption key. **Nothing works before this** — the key never leaves your node, and every member receives it wrapped for their own key, on every connection. | + +The node starts indexing immediately. A large library takes a while; you can +watch it with `meshbay-node status` or in the group page, which shows the +progress. + +Want more than one directory in the group? + +```bash +meshbay-node root add /mnt/library/films --name Films +meshbay-node root add /mnt/usb/archive --removable # external drive +meshbay-node root list +``` + +Roots added later are **read-only by default** — the opposite of the first one, +deliberately. Pass `--writable` if members should be able to upload there. + +--- + +## Step 8 — Pair your browser + +Your node does not take orders from the hub. Before your browser can invite +anyone or delete a file, the node has to recognise it: + +```bash +meshbay-node operator pair +``` + +It prints a code like `R3H8-TB6V`, valid 24 hours. In the browser, open your +group → **Members** tab → enter the code. + +The code never passes through the hub. That is the whole point of it: a hub +that could name your operator key could make itself your node's administrator. + +--- + +## Step 9 — Let people reach you + +WebRTC picks a fresh UDP port per connection, so there is no single port to +forward. What the node needs is to **accept unsolicited inbound UDP on your +LAN** — browsers announce themselves with an address the node cannot resolve, +so the browser must be able to call the node, not the reverse. + +```bash +# Ubuntu — your LAN, never "anywhere" +sudo ufw allow from 192.168.0.0/16 app "MeshBay Node" + +# Fedora — apply to the zone holding your LAN interface +sudo firewall-cmd --permanent --zone=FedoraWorkstation --add-service=meshbay-node +sudo firewall-cmd --reload +``` + +**Scope it to the LAN.** This profile opens UDP 1024-65535; it does not belong +in an internet-facing zone. Members outside your network are reached by hole +punching, which needs no open port at all. + +The node's own admin surface is not affected: it listens on loopback only, +behind a token, and is never network-exposed. + +--- + +## Step 10 — Invite someone + +Your friend needs a meshbay.org account first — send them to Step 3. Then, with +their username: + +```bash +meshbay-node member invite alice_dupont +``` + +You get: + +``` +INVITATION CODE K7P2-9WQX +valid until 2026-09-25T17:40:00Z +``` + +Send that code however you normally talk to them — message, mail, out loud. It +works once, for that account only, for that group only, and the hub never sees +it. You do not need to be online when they use it. + +You can do the same thing from the **Members** tab of the group, from the +browser you paired in Step 8. + +--- + +## Step 11 — What your friend does + +1. Signs in at **https://meshbay.org**. +2. The group is already in their sidebar — creating the invitation registered + their membership. +3. They open it and are asked: *"This node needs to recognise you."* They paste + the code. +4. That is it. Your node pins their key, wraps the group key for it, and their + files appear. + +They will not be asked again on that browser. A *different* browser on the same +node recovers the same identity with their passphrase alone. A different +*node* — someone else's group — asks for a code again, as first contact always +does. + +--- + +## Did it work? + +```bash +meshbay-node status +``` + +A healthy node reads roughly like this: + +``` +hub https://meshbay.org (user yourname) +node key 7mK2p...= +daemon running — ok +node_id 82.65.x.x:0 +groups 1 files 4213 peers 1 +config /home/you/.config/meshbay/node.toml + group Family Photos [private] 8f3c... + shared → /home/you/Pictures/shared (rw) +operator yourname key AAAC3NzaC1lZDI1… paired 2026-09-18T14:02:11Z +``` + +If a line is missing, `status` names the command that fixes it. The four that +catch most people: + +| Symptom | Cause | +|---|---| +| `daemon not running` | Step 5, or a startup error in `journalctl --user -u meshbay-node` | +| `operator NONE PAIRED` | Step 8 — invites and file deletion are refused until this is done | +| an `action needed:` block naming a group key | Step 7's `gek init` was skipped — `meshbay-node group list` shows it as `NO KEY` | +| Group shows files to you, nothing to a member | The member never redeemed a code, or the firewall in Step 9 | + +--- + +## Where to go next + +- **Point Videos, Music and Photos at their folders.** Group → Settings — as + many folders as each library needs. Until you do, those tabs stay empty and + say so. +- **Turn off the applications you do not want.** Group → Members → Applications. + Files and Settings always stay. +- **Add your other devices.** Your phone's browser, the desktop application: + each one asks to be recognised, and you approve it from a device already + linked. Nobody else is involved. +- **Read [`USERGUIDE.md`](USERGUIDE.md)** — what each application does, how + members are managed, what happens when someone leaves, what is private and + what is not, and what to do when something breaks. diff --git a/docs/USERGUIDE.md b/docs/USERGUIDE.md new file mode 100644 index 0000000..9f7cea7 --- /dev/null +++ b/docs/USERGUIDE.md @@ -0,0 +1,861 @@ +# MeshBay — User Guide + +This guide is for people who **use** MeshBay and for people who **run** a node. + +If you have not installed anything yet, start with +[`QUICKSTART.md`](QUICKSTART.md) and come back here. + +**Contents** + +1. [What MeshBay is](#1-what-meshbay-is) +2. [Your account](#2-your-account) +3. [Your devices](#3-your-devices) +4. [Joining a group](#4-joining-a-group) +5. [Using a group](#5-using-a-group) +6. [Running a node](#6-running-a-node) +7. [Managing people](#7-managing-people) +8. [What is private, and what is not](#8-what-is-private-and-what-is-not) +9. [When something breaks](#9-when-something-breaks) +10. [Reference](#10-reference) +11. [Running your own hub](#11-running-your-own-hub) +12. [What this software does not do yet](#12-what-this-software-does-not-do-yet) + +--- + +## 1. What MeshBay is + +MeshBay gives a small group of people — a family, a household, a few friends — +private access to files that live on **somebody's own machine**, with +applications over them: a chat, a file explorer, a video library, a music +player, a photo album. + +It is not a public file-sharing network and it is not a cloud. Nothing is +uploaded to a company. The files stay where they already are. + +### The three parts + +**The hub** (meshbay.org, or one you run) holds accounts and the list of +groups, and introduces two machines to each other. Under a kilobyte of +connection setup passes through it. For a private group — the default, and what +this guide assumes — it never sees a file, a message, a file name or a key. §8 +says exactly where that stops. + +**The node** is a daemon on the machine that holds the files. It holds the +group's encryption key, and it is the only thing that decides who gets served. +Not the hub — the node. If the hub invented an account and put it in your +group, the node would still refuse it. + +**The client** is either the web application the hub serves, or the desktop +application you install. Both are the same interface. + +### The one idea that explains the rest + +> **Everything about a group lives on the machine that hosts it.** + +The files, the list of them, who has been let in, invitations, chat history, +which folders allow uploads, how each application is set up — all of it on that +machine. The hub keeps accounts, group names and who belongs to what, and +nothing more. + +That is why the person running the group sends you the invitation code rather +than the website. It is why a hub having a bad day loses nothing. And it is why +there is no "I forgot my group" button to press. + +### What a group is + +A group is **people + directories + applications**. + +``` + A group's contents, as members see it + ───────────────────────────────────── + / + ├── Films/ → /mnt/library/films on the operator's machine + ├── Music/ → /mnt/audio an external drive + └── Documents/ → /home/them/share read-write: members may upload +``` + +Each of those is a **root** — a named directory. Members see the names; they +never see, and never name, a path on the operator's disk. + +--- + +## 2. Your account + +Your account lives on a hub. It is a username, an email address, and a +passphrase — and the passphrase is the part worth understanding. + +### Your passphrase is not a password + +It never reaches the hub. Your browser turns it into two separate values: one +that proves who you are to the hub, and one that encrypts **your identity keys** +where they are stored — on each node you have joined. + +Two consequences: + +- **The hub can reset your sign-in. Nobody can reset your keys.** A hub + operator, a node operator and the authors of this software are all equally + unable to open your keys. There is no back door, no support ticket, no + recovery from a database. +- **A good passphrase is worth more here than anywhere else.** Twelve + characters is the minimum the sign-up page accepts; four unrelated words is + the shape that really protects you. The locked copy of your keys on each + machine you join is only as strong as what locks it. + +### Your recovery key + +Shown **once**, at sign-up. It is a long random secret rendered as words. Put it +in a password manager. + +What it is for: a second, recovery-encrypted copy of your identity is stored on +each node beside the passphrase-encrypted one. With the recovery key, a +passphrase reset also restores your access to your groups. Without it, a reset +restores your sign-in only, and every group has to be rejoined by hand with a +fresh code from its operator. + +If you missed it at sign-up, or you signed in from a new browser: **Settings → +Recovery key → Enter recovery key** adds the backup copies to every group whose +node is reachable. + +### Forgetting your passphrase + +**Sign-in → "Forgot your passphrase?"** You need your username **and** the +email address on the account — the page says the same thing either way, so if +no code arrives, one of the two did not match. + +A code arrives by email. Enter it with a new passphrase, and your recovery key +if you have one. + +A reset also signs out every device that had been signing in by itself, so each +one asks for your passphrase once more. That is on purpose: if you are +resetting because something may have gone astray, a laptop that still lets +itself in is the thing you want stopped. + +### Changing a passphrase you still know + +**Settings → Passphrase → Change passphrase.** + +Your keys are re-encrypted on every group whose node is online **before** +anything changes on the hub — so if it fails half way, nothing has changed. +Groups whose nodes were offline are listed by name afterwards; for each one, +ask its operator to unpin you and send a fresh code. + +### Deleting your account + +**Settings → Delete account.** It removes your account, memberships and +notifications from the hub, and frees your username. + +What it cannot reach is anything sitting on other people's machines: files you +uploaded stay where their operator keeps them, and each node remembers you +until its operator says otherwise. Connection logs are kept for a year, as the +law requires. + +--- + +## 3. Your devices + +You can use one account from several devices — a laptop browser, a phone, the +desktop application. Each one gets **its own key on each machine you join** — +they are not copies of one key, and the key you hold on one person's machine +means nothing on another's. + +### Adding a device + +The first time a new browser opens a group, it says *"This browser is not +linked to this node yet"* and offers a code. You then approve it **from a +device that is already linked** — Members tab → *"Linking a new device? Enter +the code it is showing."* + +No operator is involved and the code never passes through the hub — one of +your own devices vouches for the new one, which is what stops anybody else +adding a device to your account. + +A few limits: **five devices per account on each machine**, a code lasts an +hour, and five wrong codes in a row stop the attempt. + +### Removing a device + +**Settings** on the node's group, or the Members tab: *Remove*. It loses access +to that node until it is linked again. Removing a device also moves the chat +key on, so it cannot read anything written from then on. + +### One passphrase, several browsers + +A second browser on a machine you have already joined picks up the *same* +identity: it asks for your passphrase, unlocks the copy of your keys kept +there, and you are in. No second code, nobody to ask — which is another reason +the passphrase is worth choosing well. + +### The desktop application + +Worth installing if you use MeshBay more than occasionally: + +| | Browser | Desktop application | +|---|---|---| +| Install | none | a package | +| Interface comes from | the hub, on every visit | inside the package, from disk | +| Keys | in the browser, plus a copy on each node | in the OS keyring, never bundled anywhere | +| Downloads | to disk where the browser allows it | native, streamed, no size limit | +| Casting to a TV | — | yes | + +The difference that matters: a browser fetches its code from the hub every time +you open it, while the application carries its own and never asks the hub for +any. So the application is the one to prefer for anything you care about. The +browser stays, and is a perfectly reasonable way to use MeshBay — being able to +open a group on someone else's laptop with nothing installed is worth having. + +--- + +## 4. Joining a group + +Someone who runs a node invites you. You need an account on the same hub first. + +1. **They send you a code** — eight characters like `K7P2-9WQX`, by message, + mail, or read out loud. It is good for 7 days by default, works once, and + only for your account in that one group. +2. **You sign in**, and the group is already in your sidebar. +3. **You open it.** It says *"This node needs to recognise you"*. Paste the + code. +4. Done — the machine hosting the group recognises you from now on, and the + files appear. + +You will not be asked again on that browser, or on that machine. + +**The code never passes through the hub**, and that is the whole reason it +exists: it proves the invitation came from the person running the group, and +not from the service in the middle. + +### Leaving + +Group menu → **Leave group**. You lose access to its files and chat. Anything +you uploaded stays on the machine hosting the group, which also remembers you +until its operator says otherwise. + +--- + +## 5. Using a group + +A group is a set of tabs. Which ones you see is the operator's choice; **Files** +and **Settings** are always there. + +### Files + +The explorer. Roots are the top-level folders; below that it behaves like any +file browser — sort, select, download, preview. + +- **Upload** appears only where the current folder is in a **read-write** root. + You can also drag files and whole folders onto the file list. +- **A drop is decided before anything is sent.** A name already in the folder, + or a name the node cannot store, cancels the whole drop and tells you which + name caused it — so you never end up with half a copy. +- **Download a folder as a zip**, built in your browser from the same encrypted + chunks as any other download. The node never compresses anything. +- **Delete** — you can remove a file you uploaded yourself; anything else is + the operator's to remove. A folder has to be empty first, so nothing here can + sweep away files you cannot see. + +### Chat + +Per-group messages, always encrypted, with threads, attachments and link +previews. + +- **Attachments** need a read-write folder in the group. Where there is none, + the paperclip is off and says so. +- **Link previews** are fetched **by the node** — the machine hosting the group + makes a request to whatever site somebody linked. The operator can turn it + off. +- **History is kept on the node**, and stays readable to members. A member + removed from the group cannot read anything written after their removal. +- Sometimes a message reads *"Written before this device could read this + conversation"* — that is a device added later, not an error. A message marked + *"the signature does not match the sender"* is different and worth asking + about. + +### Videos + +A poster browser over the folders the operator chose for it. Two modes: a +poster grid with artwork and summaries, and a plain folder-driven list that +needs no third-party service at all. + +- **Nothing appears until the operator chooses at least one folder** — the tab + tells you so, rather than just looking empty. +- Films and shows are **one card each**, not one per file; a show expands into + seasons and episodes. +- The operator can **correct a wrong match**, and the correction applies to the + whole show rather than one episode. +- Streaming has **seeking, audio-track selection and subtitles**. Picture-based + subtitle tracks (the ones stored as images rather than text) are not offered: + they would need text recognition to display, so they are left out rather than + listed and blank. +- A library is read **a page at a time**; the page size is your own preference + in Settings, not the group's. + +### Music + +An album browser and a player, over the folders the operator chose for it. + +- Tags in your files come first, then folder and filename, then a lookup for + cover art or canonical spelling. +- **The player survives leaving the tab** — go to Files, go to another group, + the music keeps playing. +- **Playlists are yours, not the group's**, and follow you across groups and + devices. Favourites, queues saved as playlists, drag to reorder. + +### Photos + +An album browser over the folders the operator chose for it, where **an album +is a folder**. Thumbnails come from the node, already rotated correctly. + +**Location data is never shown.** Photos shows when a picture was taken and +what took it, and no coordinates anywhere. Worth knowing, though: the +coordinates are still inside the photo itself, as your phone wrote them, so +anyone who downloads the original file has them. Strip them before sharing if +that matters to you. + +### Search + +The magnifying glass in the sidebar searches **across every group you are in** +at once, with a Files / Videos / Music / Photos view each. + +A file that two groups both have is **one result**, not two — identity is the +content, not the path. Each result says which group it came from, or how many. + +An operator can keep a group out of Search. It is a tidiness setting and +protects nothing: members still see everything by opening the group. + +### Transfers + +The transfers panel shows what is moving. Downloads queue, run, pause and +resume. + +- The node runs a limited number at once, and each member has their own share + so nobody can take the machine. Queued transfers say what they are waiting + for. +- **Pausing needs a download folder** chosen in Settings → Downloads. Without + one, your browser decides where files go and a transfer cannot be resumed. +- **Browsing is never queued.** Posters, thumbnails, opening a photo or a + document to look at it — none of it takes a transfer slot. A busy group + browses exactly like an idle one. + +### Casting to a TV + +**Desktop application only.** A film playing in the application can be sent to a +cast-capable TV or dongle on the same network: *Cast to device* in the player, +pick one from the list. + +The application decrypts the film and relays it to the TV itself, over your LAN. +The TV is not a group member and holds no key — which is also why the relay's +ports have to be reachable on the local network (§10). + +Subtitles travel with it. Other TV protocols — the UPnP/DLNA family — are +designed and not built. + +### Notifications and settings worth knowing + +**Settings → Downloads** — save automatically to a folder, or ask every time. +**Settings → Defaults** — which tab a group opens on, how many items per page. +**Settings → Appearance** — theme and language (ten languages ship). +**Group menu → Mute** — stop notifications for one group. + +--- + +## 6. Running a node + +This section is for the person whose machine holds the files. + +### What you decide + +Your node, not the hub, decides who gets served and what gets served — from a +list you build yourself with invitation codes. Two things follow from that: + +- The hub can tell somebody your group exists and point them at your machine, + but it cannot get them let in. Only your invitation does that. +- **Your own browser counts as a stranger until you pair it** + (`meshbay-node operator pair`). Until then it cannot invite anyone or delete + anything — which is a little surprising the first time, and is what keeps the + decision yours. + +### Two ways in + +| | | +|---|---| +| **The CLI**, over SSH | no browser needed, and it works while the daemon is stopped | +| **A paired browser** | the group's Settings and Members tabs, and the Node page in the desktop application | + +On a headless server the CLI is the only path, and it covers everything you +need to run a group. One gap is known: removing **one** device of one member is +only doable from the interface (§7). Start with: + +```bash +meshbay-node status +``` + +It reports what is configured, what is running, and — when something is +missing — the command that fixes it. + +### Directories (roots) + +A group's content is a set of **named directories**. The name members see is +the directory's own basename, fixed when you add it. + +```bash +meshbay-node root list +meshbay-node root add /mnt/library/films --name Films +meshbay-node root add /mnt/usb/archive --removable +meshbay-node root set Films --writable +meshbay-node root remove Films +``` + +Rules that will bite you if you do not know them: + +- **Two roots cannot share a basename**, even on different drives. `/mnt/a/Films` + and `/mnt/b/Films` is refused; name one of them explicitly. +- **No root inside another.** The same bytes would be indexed twice under two + identities. +- **Renaming a root rewrites every path under it**, so it is an explicit act, + not a cosmetic one. +- The first directory of a new group is **read-write**; every root added later + is **read-only** unless you say otherwise. + +### Read-only and read-write + +A read-only directory is read-only **for everybody, including you**. That is +intentional: a library you have published as read-only should stay as you +arranged it, and an accidental drag-and-drop from your own browser is as +unwelcome as anyone else's. + +Whether uploads are allowed is decided per directory and nowhere else. A group +can have several directories open for uploads, or none at all — a group nobody +can add to is a perfectly normal thing to want. + +### External drives + +Mark a root `--removable` and you get **Eject** and **Plug in** beside it. + +Eject before you unplug. It stops watching that directory and freezes its files +in the index — they stay listed and are reported as unavailable, rather than +looking to every member as though you deleted your library. Plug in checks the +path is really back, then rescans. + +If a removable root's path disappears without an eject, the node ejects it for +you. Nothing is deleted: index entries, thumbnails, metadata and chat history +referring to those files all survive. + +Remember the systemd drop-in for anything outside your home directory — both +`ReadWritePaths` and `RequiresMountsFor`. It is in +[`QUICKSTART.md` Step 5](QUICKSTART.md#step-5--start-the-node). + +### Indexing + +The node watches its directories and re-checks them periodically — the periodic +pass is not a backstop, it is required, because filesystem events are dropped +under load and are unreliable on network and FUSE mounts. + +Files over 40 MB are identified by reading their beginning, end and middle +rather than the whole file. A 4 TB library does not need 4 TB of reading to be +catalogued. + +Group → Settings has the re-check interval and how long the node waits after a +file changes before indexing it. Members see indexing progress while it runs. + +One thing that surprises people: **two identical files in one group are one +entry**, because a file is identified by its content. A scan that reports ten +files and indexes nine has not lost anything. + +### Applications and their folders + +Group → **Members → Applications** turns applications on and off for everyone. +Files and Settings always stay. + +Group → **Settings** points each application at folders: + +- **Videos**, **Music** and **Photos** — as many folders as you like for each. + A library is rarely in one place, so pick every folder that belongs to it and + leave out the rest. Each tab stays empty until at least one is chosen. +- **Chat** — one folder, for attachments. It has to be one members can write + to. + +This is not a personal view: it decides what **everyone** in the group sees in +that tab. The change is signed by your paired browser and reaches connected +members straight away. + +### Metadata from third parties + +**Videos** uses a film and TV database for posters, summaries and cast. It ships +with a default credential and you can set your own; the language is a +group-wide setting, because there is one shared cache rather than a request per +viewer. Turn it off and Videos falls back to thumbnails and cleaned filenames, +with no outside request at all. + +**Music** uses a music database for cover art and canonical spelling when a +track carries none. It needs no credential. + +Both lookups are made **by the node**, once per title, for everybody. Your +members' devices never talk to a third party. + +### Node settings + +Group Settings covers a group; **Node settings** covers the machine. From the +desktop application's Node page, or by editing `~/.config/meshbay/node.toml` +and running `meshbay-node reload`: + +| Setting | Default | What it decides | +|---|---|---| +| `invite_ttl_hours` | 168 (7 days) | how long an invitation stays usable | +| `pair_ttl_hours` | 24 | how long an operator pairing code lasts | +| `device_request_ttl_minutes` | 60 | how long a device request waits for approval | +| `max_concurrent_streams` | 8 | how many people can watch video at once | +| `max_concurrent_downloads` | 8 | node-wide download slots | +| `max_concurrent_uploads` | 8 | node-wide upload slots | +| `max_upload_gb` | 8 | the largest single file a member may send you | +| `transcode_incompatible_video` | true | re-encode video no browser can play | +| `hardware_video_encode` | true | use the GPU for that, if one actually works | + +`max_concurrent_streams` is the one to think about: a stream costs a video +process for as long as the film lasts, so this counts **viewers**, not +requests. + +`max_upload_gb` is the only one of these about your disk rather than this +machine's work. Fractions are allowed — `0.5` is 512 MB — and the new ceiling +applies to an upload already in progress, so raising it unblocks a file that +was about to be refused. There is no total quota behind it: a member who can +write to a folder can still fill the disk one capped file at a time. + +Turning transcoding off does two different things depending on the video: one +your viewers' browsers can decode by themselves plays as it is, and one they +cannot is refused with a message pointing at this setting. + +Changes are saved to the database for immediate effect **and** written back +into `node.toml` so they survive a reinstall. Your hand-written comments in +that file are left alone. + +--- + +## 7. Managing people + +### Inviting + +```bash +meshbay-node member invite alice_dupont +``` + +Or the group's **Members** tab, from a paired browser. + +They need an account on the same hub first. The invitation registers their +membership on the hub and produces a code that never goes near it. Send the +code out of band; they enter it the first time they open the group. You do not +need to be online then. + +### Seeing who is in + +```bash +meshbay-node member list +``` + +Names, roles, when each identity was pinned and how, plus any pending +invitations. + +### Removing someone + +```bash +meshbay-node member revoke alice_dupont +meshbay-node gek rotate --group "Family Photos" +``` + +**Both lines, and the second one matters.** Revoking means the node stops +handing them the group key on their next connection. It does not take back the +key they already have — no protocol can. Rotating replaces it: every member +still in the group gets the new one automatically, and the person you removed +keeps the old one, which opens nothing written from now on. + +Anything they already downloaded stays theirs. Once a file has been copied, no +software can reach back and take it away. + +If you mistype the username, `member revoke` says so rather than quietly doing +nothing. + +### Unpinning, and when to use it + +```bash +meshbay-node member unpin alice_dupont +``` + +This forgets **every device** of theirs on this node, so they can pair again +with a new key. It is the fix for two specific situations: + +- Someone lost their passphrase and had no recovery key. Unpin, then send a new + invitation code. +- Someone changed their passphrase while your node was offline, and their group + is now unreadable to them. + +### Devices + +A member's devices are managed **from the interface, not from the CLI** — their +own *Your devices on this node* list, or your group's Members tab from a paired +browser. A removed device is remembered as removed, so the same key cannot +quietly reappear later. + +`meshbay-node member unpin <user>` is the CLI's blunt version: it removes +**every** device that person has on this node, and they pair again from scratch. +There is no per-device CLI verb today — noted in +[`MESHBAY_DESIGN.md` §15.3](MESHBAY_DESIGN.md#153-open-and-why-each-is-where-it-is). + +### Rotating the group key + +```bash +meshbay-node gek rotate --group "Family Photos" +``` + +Connected members get the new key with no action on their part. Anyone revoked +keeps the old one and loses everything from that point on. Nothing already +downloaded is affected. + +### The audit log + +Every admission, refusal, invitation and deletion is recorded on the node. The +desktop application's Node page shows it and exports it as CSV. + +--- + +## 8. What is private, and what is not + +**The short version: your files stay on the machine that hosts them.** They +travel encrypted and directly to the people that machine has been told to +serve. The hub that introduced everybody never holds them, and cannot read +them. + +For most people that is the whole answer. The rest of this section is for +deciding what belongs in a group and what is better kept elsewhere. + +### What you can rely on + +- **Nothing goes through the hub** — not your files, not their names, not even + the list of them. Your devices talk to the node directly. +- **The hub cannot open your group.** It holds none of the keys, and for a + private group it does not know what is in it. +- **The hub cannot let anybody in.** Only the node decides who it serves, from + the list its operator built with invitation codes. An account the hub added by + itself gets nowhere. +- **Only your own devices can add another of your devices.** The hub cannot, + and neither can an operator. +- **You get separate keys in each group you join**, so two people hosting you + cannot work out that you are the same person. +- **Chat history is encrypted where it is stored.** +- **Your client remembers each node** and refuses one whose identity has + changed — which is what stops a machine being quietly swapped for another. +- **People you have already seen in a group stay checked** every time they post + after that. + +### Worth knowing before you share something + +- **Whoever hosts a group can read what is in it.** The files sit on their + machine in the ordinary way, because that is what hosting is. It is the same + trust you extend to a friend keeping a spare key to your flat — reasonable, + and worth being conscious of. +- **Everyone in a group sees everything in it.** There is nothing below group + level: no per-person permissions, no private corner inside a shared library. + If two sets of people should not see the same things, make two groups. +- **The desktop application protects you a little better than a browser.** A + browser downloads its code from the hub every time you open it; the + application carries its own and never asks the hub for any. For anything you + would rather not stake on the hub behaving, prefer the application. +- **Your passphrase is what guards your keys.** A copy of them, locked with it, + sits on each machine you have joined. A long one puts that out of reach; a + guessable one does not. This is the single thing most worth getting right. +- **An open group is open.** Anybody can walk into one, which is what open + means. Invite-only is the default, and is what you want for anything personal. +- **The hub sees who is in which group, and when.** Never what was said or + shared — but the pattern of it is visible to whoever runs the hub. +- **Deleting your account does not delete what you shared.** Files you uploaded + stay on the machines hosting them, and each node remembers you until its + operator says otherwise. Ask them if it matters. + +## 9. When something breaks + +### Start here + +```bash +meshbay-node status +journalctl --user -u meshbay-node -f +``` + +`status` works whether or not the daemon is running, and names the command for +anything missing. + +### The common ones + +**"No nodes are currently online for this group."** +The node is not running, is not reachable, or has not linked its key to the +hub. On the node: `meshbay-node status`, then Step 4 and 5 of the quickstart. + +**A member sees the group but no files.** +They never redeemed an invitation code, or the group has no key +(`meshbay-node gek init`), or nothing has been indexed yet. + +**Members on other networks connect, members on your own LAN do not.** +The firewall. A browser on your LAN has to be able to call the node, and a node +refusing unsolicited inbound UDP cannot be called. See +[`QUICKSTART.md` Step 9](QUICKSTART.md#step-9--let-people-reach-you). + +**A shared directory reads as empty and everything else looks right.** +A mount the service cannot see. The systemd drop-in needs +`RequiresMountsFor` as well as `ReadWritePaths` — the service has its own mount +namespace, so a volume mounted after it started is invisible to it. + +**"Invitations are signed with the key this node pinned for your browser."** +The browser is not paired. `meshbay-node operator pair`, then enter the code in +the Members tab. + +**A member changed their passphrase while the node was down.** +`meshbay-node member unpin <user>`, then a fresh invitation code. + +**Video says the codec is not supported.** +The source codec has no decoder in that browser and transcoding is off, or +ffmpeg is missing. Check `transcode_incompatible_video` and that ffmpeg is +installed. + +**"Server busy" when starting a film.** +Every streaming slot is taken. `max_concurrent_streams` counts viewers, and +each one holds a slot for the whole film. + +**A download stops near the end in the browser.** +Choose a download folder in Settings → Downloads, which switches the browser to +writing straight to disk, and retry. The desktop application does not have this +class of problem. + +**Nothing appears in Videos, Music or Photos.** +No folders have been chosen for that application yet. Group → Settings. The tab +says so rather than just looking empty, but it is easy to miss. + +### After changing config by hand + +```bash +meshbay-node reload # re-read node.toml without dropping anyone +meshbay-node restart-daemon # full restart — drops live streams +``` + +Prefer `reload`. A restart kills every connection, which for someone watching a +film looks like a failure they caused. + +--- + +## 10. Reference + +### Node commands + +``` +meshbay-node status what is configured and running +meshbay-node init first-time setup +meshbay-node reset erase all node state (destructive) + +meshbay-node group list|add|remove groups this node hosts +meshbay-node root list|add|remove|set directories in a group +meshbay-node root eject|plug removable drives +meshbay-node gek init|rotate the group's encryption key + +meshbay-node operator pair authorise a browser +meshbay-node member list|invite|revoke|unpin people + +meshbay-node file list|rm files, from the machine itself +meshbay-node chat status|rotate|encrypt-history|prune +meshbay-node transfers show|set|max-size|per-member + transfer limits, and the + largest single upload +meshbay-node denylist show|clear +meshbay-node stun list|add|remove|reset NAT traversal servers +meshbay-node video rematch re-resolve video metadata + +meshbay-node reload re-read node.toml, hot +meshbay-node restart-daemon full restart +``` + +`--group <name>` selects a group where you host more than one. `--yes` skips +the confirmation on destructive commands. `man meshbay-node` has the full page. + +### Where things live + +| | | +|---|---| +| `~/.config/meshbay/node.toml` | configuration — hand-edited, commented, preserved | +| `~/.config/meshbay/node.env` | environment: keystore unlock, third-party tokens | +| `~/.config/meshbay/keystore.enc` | the node's own keys. **Back this up.** | +| `~/.config/meshbay/unlock.key` | what opens the keystore. Mode 0600. | +| `~/.local/share/meshbay/` | roster, indexes, chat, caches, thumbnails | +| `/opt/meshbay-common/venv/` | the shared Python environment | + +Losing the keystore means a new node identity: every group has to be re-linked +and every member re-admitted. It is small — back it up somewhere safe. + +### Ports + +| | | +|---|---| +| **inbound UDP, ephemeral** | peer connections. Scope the rule to your LAN. | +| **127.0.0.1:18000** | the node's own control API. Loopback only, behind a per-run token, never exposed. | +| **TCP 19550-19553, UDP 5353** | casting to a TV, desktop application only, LAN only | + +### Defaults worth remembering + +| | | +|---|---| +| Invitation code | 7 days, single use, one account, one group | +| Operator pairing code | 24 hours | +| Device linking code | 1 hour | +| Devices per account per node | 5 | +| Upload size limit | 8 GB per file, settable on the node | +| Transfers at once | 8 node-wide, 2 per member per group | +| Video streams at once | 8 | + +--- + +## 11. Running your own hub + +You do not need to. meshbay.org exists, is free, and sees nothing of your +content. Run your own if you want nobody else holding your account list, or you +want a hub that is not reachable from the internet at all. + +A hub is a Linux server with PostgreSQL, a reverse proxy for HTTPS, and +somewhere to send mail from. The steps are in: + +- [`PACKAGING-GUIDE.md`](PACKAGING-GUIDE.md) — install, database, configuration, first start +- [`HTTPS.md`](HTTPS.md) — the reverse proxy and certificates +- [`MAIL-SERVER.md`](MAIL-SERVER.md) — outgoing mail, which sign-up and recovery need + +Two things to know before you start. **Your hub serves the web application**, +so anyone using a browser against it is trusting you with their keys — the +same relationship you have with meshbay.org, pointed at you. And **a hub cannot +be moved**: accounts, group registrations and node links are all on it. + +--- + +## 12. What this software does not do yet + +Better to know now than to go looking for it: + +- **Packages are not signed**, and there is no signed repository yet, so there + is nothing to check a download against and no updates through your + distribution. Until that ships, take them from the download page and from + nowhere else. +- **There is no Android client.** A phone browser works. +- **A node cannot be hosted on Android**, and is not planned to be. +- **Hubs do not talk to each other yet.** Everyone in a group needs an account + on the same hub. +- **Casting reaches Chromecast devices** from the desktop application. Support + for other TV protocols is designed but not built. +- **Some subtitle tracks cannot be shown** — the ones stored as images rather + than text, roughly one embedded track in five. Displaying them would need + text recognition. +- **There is no overall storage quota.** Files are capped at 8 GB each — lower + or raise it on the node, above — but somebody can still fill a disk one file + at a time. Worth a glance now and then if you have opened a folder to people + you do not know well. +- **Searching the film database by hand has no per-member limit**, and it draws + on the node's own quota. Only likely to matter on a large group. +- **The record of who uploaded what belongs to the node.** It is kept and it is + accurate, but other members have no way to check it for themselves. +- **Chat history stays readable to everyone in the group**, including people + who join later. That is what makes it a shared history rather than + disappearing messages — but if a conversation should leave no trace, it does + not belong here. +- **Your client remembers each node's identity, but not the hub's.** It matters + less than it sounds: a stand-in hub still cannot read anything, and cannot + touch the desktop application at all. |