feat: rework first run as a setup checklist and split settings into tabs
This commit is contained in:
parent
6f82a84b69
commit
1710d7b144
5 changed files with 604 additions and 232 deletions
|
|
@ -18,7 +18,7 @@ browser (all crypto, all keys) ⇄ bridge.py (dumb byte pipe) ⇄ smolmaild
|
|||
devbox run serve
|
||||
```
|
||||
|
||||
Then open http://127.0.0.1:8096. First use: create an identity, back up the master, pin your server's public key (from the operator, through a trusted channel), register an address, and fetch.
|
||||
Then open http://127.0.0.1:8096 and create an identity. A checklist over the mailbox carries the rest, each step opening the settings tab that completes it: back up the master, pin your server's public key (from the operator, through a trusted channel), and claim an address. Then fetch.
|
||||
|
||||
For a server on a non-default port, start the bridge with `uv run bridge.py --allow-port <port>`.
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ For a NixOS host, `nixosModules.default` provides `services.gsmol-bridge`:
|
|||
|
||||
The service runs under `DynamicUser`, restarts on failure, and — like the standalone script — listens on `127.0.0.1` by default. `nginx.enable` (or `caddy.enable`, wiring into `services.caddy.virtualHosts` — automatic HTTPS, no `enableACME`/`forceSSL` equivalent to set) puts a TLS-terminating reverse proxy in front rather than exposing the bridge directly: it has no TLS of its own, and a browser refuses a `ws://` connection from an `https://` page, so a real deployment needs one of the two regardless of `--allow-origin`. Enable only one; a deployment that replaces `services.caddy.configFile` with a hand-written Caddyfile instead of using `virtualHosts` needs the domain added there directly, proxying to `host`:`port`. `openFirewall = true` is for exposing the bridge's port directly instead of either, which is not the recommended path (see "Notes and limits").
|
||||
|
||||
`services.gsmol-bridge.presetServer = { host, publicKey }` bakes a server's key into the pages this deployment serves, so a first-time visitor is pre-pinned instead of asked to copy a base32 key into settings by hand (§4). The value reaches the browser over this deployment's own TLS, so it only stands in for "from the operator, through a trusted channel" when the deployment operator and the smolmaild operator are the same trusted party — set it only for a server you operate or otherwise vouch for. It seeds the first run only: the browser stores it as an ordinary pin from then on, replaceable or removable in settings like any other.
|
||||
`services.gsmol-bridge.presetServer = { host, publicKey }` bakes a server's key into the pages this deployment serves, so a first-time visitor is pre-pinned instead of asked to copy a base32 key into settings by hand (§4). The value reaches the browser over this deployment's own TLS, so it only stands in for "from the operator, through a trusted channel" when the deployment operator and the smolmaild operator are the same trusted party — set it only for a server you operate or otherwise vouch for. It seeds the first run only: the browser stores it as an ordinary pin from then on, replaceable or removable under settings → server like any other, and the checklist's pinning step is already ticked off on first run.
|
||||
|
||||
## What it implements
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ The service runs under `DynamicUser`, restarts on failure, and — like the stan
|
|||
- **Trust** (§4, §8): server keys pinned on first trust, mismatch aborts the handshake; `RESOLVE` over an unpinned session is marked unverified; registration and fetching require a pinned server; `REGISTER` carries a proof-of-possession signature bound to the server's own key, so a binding cannot be replayed elsewhere.
|
||||
- **Mail** (§5): sealed and signed envelopes, 1 KiB padding, frontmatter bodies, sent copies sealed to self, fetch pages forward by cursor and verifies id and signature before acknowledging — anything unreadable stays on the server. Outgoing mail carries a signed `Reply-To` frontmatter field with the sender's full `smol://` address (an "anonymous" checkbox omits it), so a first-time recipient can name the sender and answer; on receipt such a claim binds only when its key matches the message's signer, and never over an address already pinned to a different key.
|
||||
- **Accept tokens** (§5.8): mail from an accepted correspondent lands in the inbox's main tier; everything else lands in a separate "requests" tier. Accepting or blocking a contact pushes the changed token set to the server immediately; a learned token is attached automatically to outgoing mail once a correspondent's own token has been received.
|
||||
- **Leave mail on server**: a settings toggle that has fetch page forward by cursor without acknowledging, so mail stays server-side until deleted from the reader — off by default, which acknowledges (and so deletes) fetched mail immediately, as before.
|
||||
- **Leave mail on server**: a toggle under settings → mail that has fetch page forward by cursor without acknowledging, so mail stays server-side until deleted from the reader — off by default, which acknowledges (and so deletes) fetched mail immediately, as before.
|
||||
- **Rotation** (§7): rotate to the next index's derived key with a certificate both the old and new keys sign, binding the change to this username; contacts accept it from the chain; every superseded key stays derivable from the master, since mail sealed to it is readable with nothing else; key changes without a chain are surfaced, never applied silently.
|
||||
|
||||
## Layout
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue