Fix key issues

Signed-off-by: denis0001-dev <denis0001.dev@ya.ru>
This commit is contained in:
2026-03-28 14:18:29 +03:00
Unverified
parent 85ff429ff4
commit c09d605458
4 changed files with 71 additions and 38 deletions
@@ -121,39 +121,46 @@ object ApiClient {
} }
suspend fun login(request: LoginRequest) = suspend fun loginRequest(request: LoginRequest): LoginResponse =
http http
.post("${Config.apiBaseUrl}/login") { .post("${Config.apiBaseUrl}/login") {
contentType(ContentType.Application.Json) contentType(ContentType.Application.Json)
setBody(request) setBody(request)
} }
.body<LoginResponse>() .body()
.also {
token = it.token
user = it.user
secureSettings.putString("auth_token", it.token)
settings.putString("user_info", json.encodeToString(it.user))
settings.putInt("current_user_id", it.user.id)
// Upload any pending FCM token after successful login
MainScope().launch {
runCatching {
uploadPendingFcmTokenIfAvailable()
}
}
}
suspend fun register(request: RegisterRequest) = suspend fun registerRequest(request: RegisterRequest): LoginResponse =
http.post("${Config.apiBaseUrl}/register") { http
contentType(ContentType.Application.Json) .post("${Config.apiBaseUrl}/register") {
setBody(request) contentType(ContentType.Application.Json)
}.also { setBody(request)
// Upload any pending FCM token after successful registration }
MainScope().launch { .body()
runCatching {
uploadPendingFcmTokenIfAvailable() /**
} * Sets in-memory auth only so follow-up calls (e.g. crypto upload) use Bearer token.
* Persist with [persistSessionToStorage] only after identity keys are fully synced.
*/
fun bindSession(loginResponse: LoginResponse) {
token = loginResponse.token
user = loginResponse.user
}
fun clearMemorySession() {
token = null
user = null
}
suspend fun persistSessionToStorage(loginResponse: LoginResponse) {
secureSettings.putString("auth_token", loginResponse.token)
settings.putString("user_info", json.encodeToString(loginResponse.user))
settings.putInt("current_user_id", loginResponse.user.id)
MainScope().launch {
runCatching {
uploadPendingFcmTokenIfAvailable()
} }
} }
}
suspend fun getMessages(limit: Int = 50, beforeId: Int? = null) = suspend fun getMessages(limit: Int = 50, beforeId: Int? = null) =
http http
@@ -157,7 +157,11 @@ fun App(scrollToMessageId: Int? = null, startAtPublicChat: Boolean = false) {
composable("register") { composable("register") {
RegisterScreen( RegisterScreen(
onRegistered = { navController.navigate("login") } onRegistered = {
navController.navigate("chat") {
popUpTo("login") { inclusive = true }
}
}
) )
} }
@@ -181,13 +181,19 @@ fun LoginScreen(
onLoginSuccess() onLoginSuccess()
} }
) { ) {
val response = ApiClient.login(LoginRequest(trimmedUsername, derived)) val response = ApiClient.loginRequest(LoginRequest(trimmedUsername, derived))
// Ensure identity keys and backup are initialized after successful login ApiClient.bindSession(response)
IdentityKeyManager.ensureKeysOnLogin( try {
username = trimmedUsername, IdentityKeyManager.ensureKeysOnLogin(
password = trimmedPassword, username = trimmedUsername,
token = response.token password = trimmedPassword,
) token = response.token
)
} catch (e: Exception) {
ApiClient.clearMemorySession()
throw e
}
ApiClient.persistSessionToStorage(response)
response response
} }
} }
@@ -36,6 +36,7 @@ import ru.fromchat.Res
import ru.fromchat.api.ApiClient import ru.fromchat.api.ApiClient
import ru.fromchat.api.RegisterRequest import ru.fromchat.api.RegisterRequest
import ru.fromchat.api.apiRequest import ru.fromchat.api.apiRequest
import ru.fromchat.crypto.IdentityKeyManager
import ru.fromchat.back import ru.fromchat.back
import ru.fromchat.confirm_password import ru.fromchat.confirm_password
import ru.fromchat.display_name import ru.fromchat.display_name
@@ -165,7 +166,9 @@ fun RegisterScreen(
// Derive auth secret before sending (matches frontend implementation) // Derive auth secret before sending (matches frontend implementation)
scope.launch { scope.launch {
val derived = deriveAuthSecret(username.trim(), password) val u = username.trim()
val display = displayName.trim()
val derived = deriveAuthSecret(u, password)
apiRequest( apiRequest(
unexpectedError = errorUnexpected, unexpectedError = errorUnexpected,
@@ -176,14 +179,27 @@ fun RegisterScreen(
onRegistered() onRegistered()
} }
) { ) {
ApiClient.register( val response = ApiClient.registerRequest(
RegisterRequest( RegisterRequest(
username.trim(), u,
displayName.trim(), display,
derived, derived,
derived derived
) )
) )
ApiClient.bindSession(response)
try {
IdentityKeyManager.ensureKeysOnLogin(
username = u,
password = password,
token = response.token
)
} catch (e: Exception) {
ApiClient.clearMemorySession()
throw e
}
ApiClient.persistSessionToStorage(response)
response
} }
} }
} }