mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 00:11:37 -06:00
fbaf0b63df
The iOS app lets an account reach one server through several addresses, such as a home network IP and a public name. Before it sends credentials to an alternative address it needs to know the address leads to the same installation, so expose a public, credential-free GET /server-identity returning a persisted UUID, and add the same optional instanceId to app-info with the server-connection-identity feature flag. The UUID lives in a singleton server_identity row shared by every replica, created on first use and cached per process. An unreadable identity omits instanceId instead of failing app-info, which clients rely on for feature detection. Existing routes and bodies are unchanged and the web client does not call the new route; the iOS app does. The migration uses IF NOT EXISTS because an unreleased build created the same table as 0109.
37 lines
2.3 KiB
Markdown
37 lines
2.3 KiB
Markdown
# Server connection identity
|
|
|
|
The iOS client supports several user-entered connection addresses for one
|
|
BookOrbit installation. `GET /api/v1/server-identity` is public and returns only
|
|
`product: "bookorbit"`, `protocolVersion: 1`, and a persisted UUID `instanceId`.
|
|
It sends `Cache-Control: no-store`. The authenticated `/api/v1/app-info` response
|
|
adds the same optional `instanceId` and advertises `server-connection-identity`.
|
|
Existing routes and request bodies are unchanged. Released clients ignore the
|
|
additional fields. New clients keep single-address behavior on older servers.
|
|
The iOS client consumes this route even though the web client does not call it.
|
|
|
|
The singleton `server_identity` row is generated on first use and shared by all
|
|
replicas through PostgreSQL. Keep it in database backups. Application restart,
|
|
container replacement, DNS changes, and reverse-proxy aliases preserve it.
|
|
Multiple addresses must reach the same database and installation.
|
|
|
|
The UUID detects accidental connection to another installation through an
|
|
alternative address. It is public and is not a replacement for TLS certificate
|
|
validation. Clients never send account credentials when probing an alternative
|
|
and never bypass TLS trust. The address a user signed in with keeps the trust
|
|
released clients gave it, including following its redirects. An alternative is
|
|
used only after it answers with the enrolled UUID, and its redirects must stay on
|
|
its host. Users who explicitly choose HTTP retain that transport's existing trust
|
|
limits. If the identity row cannot be read, `/app-info` still answers and omits
|
|
`instanceId`.
|
|
|
|
A restored database belonging to the same installation keeps its UUID. When the
|
|
UUID changes (an independent clone, a fresh database, or a backup taken before
|
|
this table existed), clients keep using the address they signed in with, adopt
|
|
the new UUID from the authenticated `/app-info` response, and ask the user to
|
|
verify each alternative again. For an independent clone, stop every application
|
|
replica, remove only the singleton `server_identity` row through an
|
|
administrative database session, and restart. The next request creates a fresh
|
|
UUID. Never regenerate the row while live replicas hold a cached identity.
|
|
|
|
Regression coverage is available through `pnpm e2e:run -- server-connection-identity`.
|