docs: enrollment link encoding rules in the spec, session log in build-status
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
5291bdd045
commit
199807a8c9
@@ -660,3 +660,37 @@ One user-visible bug caught in the process: Go's JSON encoder HTML-escapes `<`,
|
||||
default, so the refusal reached the client as `needs \u003e= 0.2.0`. Disabled at the encoder (this
|
||||
is an API, not a page), and the client now *parses* the error field instead of pattern-matching it,
|
||||
so it survives whatever a future encoder decides to escape.
|
||||
|
||||
### Enrollment: the server mints the bootstrap link (server-v0.5.3 … v0.5.4, 2026-08-01)
|
||||
Until now a device was configured by hand-typing a control URL, a base64 SPKI pin and a
|
||||
credential. That is the step that goes wrong, and it goes wrong quietly: a pin off by one
|
||||
character does not fail loudly, it just never matches, and surfaces days later as an inscrutable
|
||||
TLS error.
|
||||
|
||||
`POST /admin/enroll-tokens` now returns the whole §2.1 bootstrap link alongside the token, because
|
||||
the server is the only party holding all three parts at once. The app takes it from a paste or an
|
||||
`echolot://enroll` deep link (so a QR scan configures a server in one action) and writes URL, pin
|
||||
and credential **together or not at all** — a half-applied server fails later, somewhere else,
|
||||
with an error pointing at the wrong thing.
|
||||
|
||||
The control URL comes from `ECHOLOT_PUBLIC_URL` (set on fmr to `https://fmr-1.echo-lot.app:8443`),
|
||||
falling back to the first control listen address; a wildcard bind warns rather than emitting a
|
||||
link to `0.0.0.0`.
|
||||
|
||||
**The encoding trap, which is the whole reason this is tested across both languages.** The pin is
|
||||
base64, so it contains `+`, `/` and `=` — each of which means something else in a query string. An
|
||||
unencoded `+` decodes to a space, leaving the pin wrong by exactly one character. Base64 has no
|
||||
spaces, so the parser restores them; that cannot damage a correctly-encoded pin and it rescues
|
||||
every hand-assembled link. `LiveEnrollmentTest` redeems a link the *server* produced, which is the
|
||||
only way to catch a disagreement between the Go assembler and the Kotlin parser — a unit test on
|
||||
either side alone cannot see it. It also asserts the token is refused the second time.
|
||||
|
||||
Also fixed a spec divergence found while reading §2.1: the spec names the field
|
||||
`device_credential`, the first implementation shipped `credential`. The server now sends both and
|
||||
the client prefers the spec's; the alias goes once nothing reads it.
|
||||
|
||||
Two process notes from this round:
|
||||
- An edit to the admin handler silently failed to apply and the endpoint kept returning just the
|
||||
token. Caught by deploying and *looking at the response*, not by trusting a green build.
|
||||
- The live suite is now six tests (`LiveServerTest`, `LiveMeasurement`, `LiveGranted`,
|
||||
`LiveUpload`, `LiveCompat`, `LiveEnrollment`), all green against fmr from the PC with no device.
|
||||
|
||||
Reference in New Issue
Block a user