feat(android): access-token support — same frozen contract as iOS
Android could not connect at all once the server set WEBTERM_TOKEN. Hand-written Cookie header on every request and on the WS upgrade (no CookieJar, matching the frozen decision), POST /auth pairing probe, Keystore-backed storage, and a 401 upgrade as a terminal state with no reconnect loop.
This commit is contained in:
@@ -59,6 +59,30 @@ Kover ≥80% on the pure modules); this checklist is what a human runs on real h
|
||||
no relaunch** (re-reading `X509KeyManager` + `connectionPool.evictAll()`); remove.
|
||||
- [ ] DataStore host list / `LastSessionStore` set-on-adopted / clear-on-exited.
|
||||
|
||||
## Access token — `WEBTERM_TOKEN` (B5 / ios-completion §1.1) — needs a token-enabled host
|
||||
Run the host as `WEBTERM_TOKEN=<16–512 chars> npm start`. The pure logic is JVM-tested (`AuthProbeTest`,
|
||||
`AccessTokenCookieTest`, `PairingProbeTokenTest`, `OkHttpAccessTokenTest`, `SessionEngineUnauthorizedTest`,
|
||||
`InMemoryAccessTokenStoreTest`); everything below needs real hardware + a real server.
|
||||
- [ ] `TinkAccessTokenStore` instrumented suite on a device:
|
||||
`./gradlew :host-registry:connectedDebugAndroidTest` (real AndroidKeyStore + Tink).
|
||||
- [ ] Pair a token-enabled host with the token typed → paired; the terminal attaches (the **WS upgrade**
|
||||
carries `Cookie: webterm_auth=…`), the session list, projects, diff and thumbnails all load.
|
||||
- [ ] Pair the same host with **no** token typed → the probe 401s → the confirm step comes back asking for
|
||||
the token ("该主机启用了访问令牌"); typing it and retrying pairs.
|
||||
- [ ] Wrong token → "访问令牌不正确" **under the field** (still on the confirm step, nothing stored).
|
||||
- [ ] 11 wrong tries within a minute → "尝试过多" (the server's 10/min/IP `/auth` limiter).
|
||||
- [ ] Pair a host with `WEBTERM_TOKEN` **unset** while typing a token → pairs, and NOTHING is stored
|
||||
(204-without-`Set-Cookie`); the app must not claim to be "authenticated".
|
||||
- [ ] Restart the app → the terminal re-attaches with no re-prompt (the token decrypts from the
|
||||
Keystore-backed store on a cold start).
|
||||
- [ ] Rotate `WEBTERM_TOKEN` on the host and restart it → the WS upgrade 401s → the terminal banner shows
|
||||
the 401 copy, offers **no** "新会话", and there is **no reconnect back-off storm** (verify with
|
||||
`adb logcat` / the server log: exactly one upgrade attempt).
|
||||
- [ ] `adb logcat` during all of the above: the token string appears **nowhere**; no request URL contains
|
||||
it (check the server's access log too).
|
||||
- [ ] `adb backup` / device-to-device transfer excludes the token blob (`allowBackup=false` +
|
||||
`data_extraction_rules.xml`).
|
||||
|
||||
## Nav / deep links / adaptive (A32/A26/A29)
|
||||
- [ ] cold-start AND warm deep link `webterminal://open?host=&join=` + the verified App Link route to the
|
||||
right destination; invalid UUID ignored.
|
||||
|
||||
Reference in New Issue
Block a user