Mirrors the same fix in fumi-core. sendMail attached the token to every message addressed to an accepted contact, so a secret rode in the body of ordinary mail indefinitely. §5.8 has the owner deliver each token to its correspondent; it doesn't say every message carries one. Harmless between people, and fatal for any recipient that republishes what it receives: a published record is checked by rebuilding the exact bytes the author signed, and those can't include a token without disclosing it. Someone who accepted such a service could never post to it again, and accepting a correspondent is what the rest of the system teaches. Contacts stored before this field existed count as still owing, so the next message to each carries the token once more. That is what every message did before, so nothing that works today can break. Marked only once the recipient's server has taken the message, so a send that threw leaves the token still owing. Not cleared by block: the token is derived from the master and the identity frozen at acceptance, so they keep the value either way. |
||
|---|---|---|
| locales/en-US | ||
| nix | ||
| scripts | ||
| test | ||
| web | ||
| .gitignore | ||
| AI-DECLARATION.md | ||
| bridge.py | ||
| devbox.json | ||
| devbox.lock | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE | ||
| README.md | ||
gsmol
Smol Mail in a browser tab. All the crypto, keys and mail handling run client-side in JavaScript; a small local bridge just relays bytes to a smolmaild server over WebSocket.
browser (all crypto, all keys) ⇄ bridge.py (dumb byte pipe) ⇄ smolmaild (TCP :1961)
The bridge holds no keys and never parses a byte of traffic. The trust boundary is the machine running the browser.
Run
devbox run serve
Open http://127.0.0.1:8096. Onboarding walks you through creating or restoring an identity (the seed is shown once — write it down), pinning your server's public key, and claiming an address. Then fetch.
Non-default server port: uv run bridge.py --allow-port <port>.
Test
devbox run test
Byte-for-byte checks against the reference vectors, protocol cases, and a live end-to-end exchange with the reference client through the bridge — the exact byte path the browser takes. Only clicking through the UI is left to a manual pass.
Deploy
nix build .#default # -> ./result/bin/gsmol-bridge
The bridge binds to 127.0.0.1 and has no TLS of its own — for anything beyond localhost, put nginx or caddy in front. A NixOS module is included (nixosModules.default → services.gsmol-bridge) with the same options.