Collect Android browser sign-ins after the app was stopped

The Android app kept a pending browser sign-in in a thread inside the
login screen. Android often kills the process while the browser is in
front, so the approval reached the server but nothing collected it, and
the app came back signed out with nothing saved.

The pending device code is now kept in Prefs and collected whenever the
login screen resumes. The app passes return_url=keeporg://device-approved
when it starts the sign-in, and the server's approval page, after a
password or single sign-on, links back to it. Only the keeporg: scheme is
accepted. Against a server older than 0.9, which rejects the field, the
app retries without it.

Verified on an Android 15 emulator: approval collected after the process
was killed, and the fallback against the 0.8 server.

Server 0.9.0, Android 0.3.0 (versionCode 3).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Reactorcoremeltdown
2026-11-02 13:16:23 +01:00
co-authored by Claude Opus 5.5
parent ef6598fa15
commit 318bd68908
16 changed files with 352 additions and 49 deletions
+10 -1
View File
@@ -23,11 +23,20 @@ https, and every form carries a per-session CSRF token.
| POST | `/api/v1/auth/password` | `{current_password, new_password, totp}` | changes the account password; the current one is required, and the second factor when enrolled. Every other session of that account is revoked |
| POST | `/api/v1/auth/totp/enroll` | – | `{secret, uri}`; not active until confirmed |
| POST | `/api/v1/auth/totp/confirm` | `{code}` | `{totp_enabled: true}` |
| POST | `/api/v1/auth/device/start` | `{label}` | `{device_code, user_code, verification_url, interval, expires_in}` |
| POST | `/api/v1/auth/device/start` | `{label, return_url}` | `{device_code, user_code, verification_url, interval, expires_in}`; `400` when `return_url` is not a `keeporg:` URL |
| POST | `/api/v1/auth/device/poll` | `{device_code}` | `202 {status: "pending"}`, then `200 {token, ...}` once; `410 expired` |
A device code is single use: the first successful poll consumes it.
`return_url` is optional (server 0.9 and later). When it is given, the page
that ends the approval, after a password or single sign-on, carries a
"Return to KeepOrg" link to it. Only the `keeporg:` scheme is accepted, so
the page cannot be made to send anybody elsewhere. It is for a client whose
browser is a separate application, which is to say a phone; the client still
learns of the approval by polling, and the link only brings the person back.
Servers before 0.9 reject the unknown field with `400`, so a client should
retry without it.
## Synchronization
| Method | Path | Notes |