Accounts, credentials and the platform keychain, and real implementations of all four protocols (mail, webdav, calendar, contacts) against the ordner suite.
Not yet run against a live server. Every plugin is tested against an in-process fake built from the suite's own source (ordner.fyi). The first real run with app passwords is what this PR is for.
Accounts and credentials #
- Passwords live in the platform keychain: libsecret (
secret-tool) or KWallet on Linux, the macOS keychain, the Windows Credential Manager. A secret only ever reaches those tools on stdin, never in argv. The config file holds no secrets. - Each protocol has named accounts, one of them the default. Every protocol command takes
--account/-a. ordner <protocol> account list | add | edit | rm | default | passwordordner credential list | add | edit | rm | password: a user plus one app password, stored once and shared by any number of accounts. Oneall-scoped app password then sets up all four protocols with a single prompt:ordner credential add lab --user <you> ordner mail account add lab --url https://lab.ordner.fyi --credential lab # likewise webdav, calendar, contacts- A password is asked for once, then tried against the server: the protocol's
checkruns with it. A refused password stores nothing.--no-verifyskips the trial. - Account management stays in the app. Plugins are handed one resolved
Account {protocol, name, url, user, password}and never see the config or the keychain.
Protocols #
| commands | app password scope | |
|---|---|---|
| mail (JMAP) | search, get, send, move, mailboxes, check | imap (sending included) |
| webdav | ls, get, put, mkdir, rm, check | webdav |
| calendar (JMAP) | list, create, update, rm, calendars, check | calendar |
| contacts (JMAP) | search, get, create, update, rm, books, check | contacts |
- For every protocol, an account url can be just the origin (
https://lab.ordner.fyi). JMAP goes through/.well-known/jmap; webdav finds your files folder viacurrent-user-principal. - The suite's
jmap-client,icalandxmlare vendored underpackages/cli/src/vendor/.vendor/README.mdrecords the upstream commits and every local change (Basic auth for app passwords injmap-client).
Fixes along the way #
--json: every failure, usage errors included, now prints the{ok:false, error:{code, message}}envelope with the plugin's own code.- Tab completion never worked below the top level from a real shell: the program name and the
--separator reached the parser. - The skill generator went only one level deep, so SKILL.md documented no leaf commands.
--helplisted options that have a short alias twice.
Tests #
- 88 tests. They use a fake
secret-tool(which also logs its argv, so a test can prove no password reached a command line) and fake suite servers. npm testand smoke run underpackages/cli/test/loopback-only.ts, which refuses any non-loopback connection. During development one smoke run sent a single session GET to lab.ordner.fyi, with a dummy password, before the fixture URLs were fixed. The guard makes that impossible now.- typecheck, test, pack and smoke all pass.
Known gaps, not checked against a real server #
- That
Authorizationsurvives the same-origin 301 from/.well-known/jmap. - The exact 401 and wrong-scope responses.
- WebDAV discovery behind the proxy.
- Chunked uploads from stdin.
- Shared or delegated mailboxes, calendars, address books and folders are not reached; only the primary account is used.
- No creating recurring events, no WebDAV COPY/MOVE.
- The KWallet, macOS and Windows keychain backends are untested (libsecret was tested against a real gnome-keyring).