Replace the manual session-cookie interceptor in ApiClient and the manual cookie branch in TokenRefreshAuthenticator with a shared PersistentCookieJar backed by an encrypted, per-server EncryptedCookieStore. - Add CookieStore iface + EncryptedCookieStore (EncryptedSharedPreferences, per-server scope, legacy single-cookie migration) - Add CookieSerialization (OkHttp Cookie <-> holder) + PersistentCookieJar (in-mem cache, async persist, atomic useStore scope switching, prune, session-cookie accessor) - Add CookieManager coordinator (init/useStore/prune/clear) and wire its cookieJar into OkHttpProvider base/websocket/probe (lazy) - AuthManager.get/setSessionCookie now delegate to CookieManager; add pruneServerCache(); clear path drops the scope's session cookie - AuthLoginViewModel + HermesWsClient rely on the jar for Set-Cookie capture and session-cookie re-attachment (no manual header injection) - Add fakes (FakeEncryptedCookieStore/buildFakePersistentCookieJar) + unit tests (PersistentCookieJarTest, CookieManagerTest); inject fake jar into ApiClientTest/HermesWsClientTest setup WS token-out-of-URL (step 5) deferred: backend hermes-agent authenticates WS only via ws.query_params, so moving it requires a coordinated backend change (noted for follow-up). Verified: testDebugUnitTest (334 passing) + assembleDebug green via local SDK.
This commit is contained in:
15 files changed
+953
-88
No files matched your search
@@ -176,6 +176,9 @@ object HermesWsClient {
|
||||
* If a session cookie is present (gated mode), mint a fresh WS ticket
|
||||
* from the dashboard. The ticket is single-use and has a 30-second TTL,
|
||||
* so we must mint a new one on every connect (first launch and reconnect).
|
||||
*
|
||||
* The session cookie is attached automatically by the shared CookieJar on
|
||||
* OkHttpProvider.probe (issue #470), so we no longer inject it manually.
|
||||
*/
|
||||
private fun refreshWsTicketIfNeeded() {
|
||||
val sessionCookie = AuthManager.getSessionCookie()
|
||||
@@ -188,13 +191,12 @@ object HermesWsClient {
|
||||
Request
|
||||
.Builder()
|
||||
.url("http://${AuthManager.getHost()}:${AuthManager.getPort()}/api/auth/ws-ticket")
|
||||
.header("Cookie", "hermes_session_at=$sessionCookie")
|
||||
.post("{}".toRequestBody())
|
||||
.build()
|
||||
val response = client.newCall(request).execute()
|
||||
if (response.isSuccessful) {
|
||||
val body = response.body?.string() ?: ""
|
||||
val ticketMatch = Regex(""""ticket":"([^"]+)"""").find(body)
|
||||
val ticketMatch = Regex("""\"ticket\":\"([^\"]+)\""").find(body)
|
||||
val ticket = ticketMatch?.groupValues?.getOrNull(1)
|
||||
if (!ticket.isNullOrBlank()) {
|
||||
AuthManager.setToken(ticket)
|
||||
|
||||
Reference in new issue
Block a user