From 8fe85a756bf601d8a61f632e2564a2f3e7f83a76 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 8 Nov 2022 19:40:51 +0100 Subject: [PATCH] Update to latest matrix-rust-sdk and update store session so it compiles --- gradle/libs.versions.toml | 5 +- libraries/matrix/build.gradle.kts | 5 +- .../io/element/android/x/matrix/Matrix.kt | 10 ++-- .../android/x/matrix/session/SessionStore.kt | 50 +++++++++++++------ 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c9a90bfda3..3329cad5d3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -36,6 +36,7 @@ timber = "5.0.1" coil = "2.2.1" datetime = "0.4.0" wysiwyg = "0.4.0" +serialization-json = "1.4.1" [libraries] # Project @@ -45,7 +46,8 @@ kotlin_gradle_plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", v # AndroidX androidx_material = { module = "com.google.android.material:material", version.ref = "material" } androidx_corektx = { module = "androidx.core:core-ktx", version.ref = "corektx" } -androidx_datastore = { module = "androidx.datastore:datastore-preferences", version.ref = "datastore" } +androidx_datastore_preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastore" } +androidx_datastore_datastore = { module = "androidx.datastore:datastore", version.ref = "datastore" } androidx_constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayout" } androidx_compose_bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose_bom" } @@ -78,6 +80,7 @@ mavericks_compose = { module = "com.airbnb.android:mavericks-compose", version.r timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" } coil_compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" } datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "datetime" } +serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization-json" } # Composer wysiwyg = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" } diff --git a/libraries/matrix/build.gradle.kts b/libraries/matrix/build.gradle.kts index b5ed341d9d..e7563b3fd6 100644 --- a/libraries/matrix/build.gradle.kts +++ b/libraries/matrix/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("io.element.android-library") + kotlin("plugin.serialization") version "1.7.20" } android { @@ -11,6 +12,6 @@ dependencies { implementation(project(":libraries:core")) implementation(libs.timber) implementation("net.java.dev.jna:jna:5.10.0@aar") - implementation("androidx.datastore:datastore-core:1.0.0") - implementation("androidx.datastore:datastore-preferences:1.0.0") + implementation(libs.androidx.datastore.preferences) + implementation(libs.serialization.json) } \ No newline at end of file diff --git a/libraries/matrix/src/main/java/io/element/android/x/matrix/Matrix.kt b/libraries/matrix/src/main/java/io/element/android/x/matrix/Matrix.kt index 31e4591b70..45521fc372 100644 --- a/libraries/matrix/src/main/java/io/element/android/x/matrix/Matrix.kt +++ b/libraries/matrix/src/main/java/io/element/android/x/matrix/Matrix.kt @@ -53,14 +53,14 @@ class Matrix( } suspend fun restoreSession() = withContext(coroutineDispatchers.io) { - sessionStore.getStoredData() - ?.let { sessionData -> + sessionStore.getLatestSession() + ?.let { session -> try { ClientBuilder() .basePath(baseFolder.absolutePath) - .username(sessionData.userId) + .username(session.userId) .build().apply { - restoreLogin(sessionData.restoreToken) + restoreSession(session) } } catch (throwable: Throwable) { logError(throwable) @@ -76,7 +76,7 @@ class Matrix( val authService = AuthenticationService(baseFolder.absolutePath) authService.configureHomeserver(homeserver) val client = authService.login(username, password, "MatrixRustSDKSample", null) - sessionStore.storeData(SessionStore.SessionData(client.userId(), client.restoreToken())) + sessionStore.storeData(client.session()) createMatrixClient(client) } diff --git a/libraries/matrix/src/main/java/io/element/android/x/matrix/session/SessionStore.kt b/libraries/matrix/src/main/java/io/element/android/x/matrix/session/SessionStore.kt index 44815490bd..a30c5b4ebc 100644 --- a/libraries/matrix/src/main/java/io/element/android/x/matrix/session/SessionStore.kt +++ b/libraries/matrix/src/main/java/io/element/android/x/matrix/session/SessionStore.kt @@ -9,45 +9,63 @@ import androidx.datastore.preferences.preferencesDataStore import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.map +import kotlinx.serialization.Serializable +import kotlinx.serialization.* +import kotlinx.serialization.json.Json +import org.matrix.rustcomponents.sdk.Session private val Context.dataStore: DataStore by preferencesDataStore(name = "elementx_sessions") -private val userIdPreference = stringPreferencesKey("userId") // TODO It contains the access token, so it has to be stored in a more secured storage. -// I would expect the Rust SDK to provide a more obscure token. -private val restoreTokenPreference = stringPreferencesKey("restoreToken") - +private val sessionKey = stringPreferencesKey("session") internal class SessionStore( context: Context ) { + @Serializable data class SessionData( - val userId: String, - val restoreToken: String, + val accessToken: String, + val deviceId: String, + val homeserverUrl: String, + val isSoftLogout: Boolean, + val refreshToken: String?, + val userId: String ) private val store = context.dataStore fun isLoggedIn(): Flow { return store.data.map { prefs -> - prefs[userIdPreference] != null && prefs[restoreTokenPreference] != null + prefs[sessionKey] != null } } - suspend fun storeData(sessionData: SessionData) { + suspend fun storeData(session: Session) { store.edit { prefs -> - prefs[userIdPreference] = sessionData.userId - prefs[restoreTokenPreference] = sessionData.restoreToken + val sessionData = SessionData( + accessToken = session.accessToken, + deviceId = session.deviceId, + homeserverUrl = session.homeserverUrl, + isSoftLogout = session.isSoftLogout, + refreshToken = session.refreshToken, + userId = session.userId + ) + val encodedSession = Json.encodeToString(sessionData) + prefs[sessionKey] = encodedSession } } - suspend fun getStoredData(): SessionData? { + suspend fun getLatestSession(): Session? { return store.data.firstOrNull()?.let { prefs -> - val userId = prefs[userIdPreference] ?: return@let null - val restoreToken = prefs[restoreTokenPreference] ?: return@let null - SessionData( - userId = userId, - restoreToken = restoreToken, + val encodedSession = prefs[sessionKey] ?: return@let null + val sessionData = Json.decodeFromString(encodedSession) + Session( + accessToken = sessionData.accessToken, + deviceId = sessionData.deviceId, + homeserverUrl = sessionData.homeserverUrl, + isSoftLogout = sessionData.isSoftLogout, + refreshToken = sessionData.refreshToken, + userId = sessionData.userId ) } }