First Commit
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
plugins {
|
||||
id("io.element.android-compose-library")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "io.element.android.libraries.sessionstorage.api"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.coroutines.core)
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.sessionstorage.api
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
sealed interface LoggedInState {
|
||||
data object NotLoggedIn : LoggedInState
|
||||
data class LoggedIn(
|
||||
val sessionId: String,
|
||||
val isTokenValid: Boolean,
|
||||
) : LoggedInState
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.sessionstorage.api
|
||||
|
||||
// Imported from Element Android, to be able to migrate from EA to EXA.
|
||||
enum class LoginType {
|
||||
PASSWORD,
|
||||
OIDC,
|
||||
SSO,
|
||||
UNSUPPORTED,
|
||||
CUSTOM,
|
||||
DIRECT,
|
||||
UNKNOWN,
|
||||
QR;
|
||||
|
||||
companion object {
|
||||
fun fromName(name: String) = when (name) {
|
||||
PASSWORD.name -> PASSWORD
|
||||
OIDC.name -> OIDC
|
||||
SSO.name -> SSO
|
||||
UNSUPPORTED.name -> UNSUPPORTED
|
||||
CUSTOM.name -> CUSTOM
|
||||
DIRECT.name -> DIRECT
|
||||
QR.name -> QR
|
||||
else -> UNKNOWN
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.sessionstorage.api
|
||||
|
||||
import java.util.Date
|
||||
|
||||
/**
|
||||
* Data class representing the session data to store locally.
|
||||
*/
|
||||
data class SessionData(
|
||||
/** The user ID of the logged in user. */
|
||||
val userId: String,
|
||||
/** The device ID of the session. */
|
||||
val deviceId: String,
|
||||
/** The current access token of the session. */
|
||||
val accessToken: String,
|
||||
/** The optional current refresh token of the session. */
|
||||
val refreshToken: String?,
|
||||
/** The homeserver URL of the session. */
|
||||
val homeserverUrl: String,
|
||||
/** The Open ID Connect info for this session, if any. */
|
||||
val oidcData: String?,
|
||||
/** The timestamp of the last login. May be `null` in very old sessions. */
|
||||
val loginTimestamp: Date?,
|
||||
/** Whether the [accessToken] is valid or not. */
|
||||
val isTokenValid: Boolean,
|
||||
/** The login type used to authenticate the session. */
|
||||
val loginType: LoginType,
|
||||
/** The optional passphrase used to encrypt data in the SDK local store. */
|
||||
val passphrase: String?,
|
||||
/** The paths to the session data stored in the filesystem. */
|
||||
val sessionPath: String,
|
||||
/** The path to the cache data stored for the session in the filesystem. */
|
||||
val cachePath: String,
|
||||
/** The position, to be able to order account. */
|
||||
val position: Long,
|
||||
/** The index of the last date of session usage. */
|
||||
val lastUsageIndex: Long,
|
||||
/** The optional display name of the user. */
|
||||
val userDisplayName: String?,
|
||||
/** The optional avatar URL of the user. */
|
||||
val userAvatarUrl: String?,
|
||||
)
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.sessionstorage.api
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
interface SessionStore {
|
||||
/**
|
||||
* A flow emitting the current logged in state.
|
||||
* If there is at least one session, the state is [LoggedInState.LoggedIn] with the latest used session.
|
||||
* If there is no session, the state is [LoggedInState.NotLoggedIn].
|
||||
*/
|
||||
fun loggedInStateFlow(): Flow<LoggedInState>
|
||||
|
||||
/**
|
||||
* Return a flow of all sessions ordered by last usage descending.
|
||||
*/
|
||||
fun sessionsFlow(): Flow<List<SessionData>>
|
||||
|
||||
/**
|
||||
* Add a new session. If other sessions exist, the new one will be set as the latest used one, and
|
||||
* the added session position will be set to a value higher than the other session positions.
|
||||
*/
|
||||
suspend fun addSession(sessionData: SessionData)
|
||||
|
||||
/**
|
||||
* Will update the session data matching the userId, except the value of loginTimestamp.
|
||||
* No op if userId is not found in DB.
|
||||
*/
|
||||
suspend fun updateData(sessionData: SessionData)
|
||||
|
||||
/**
|
||||
* Update the user profile info of the session matching the userId.
|
||||
*/
|
||||
suspend fun updateUserProfile(sessionId: String, displayName: String?, avatarUrl: String?)
|
||||
|
||||
/**
|
||||
* Get the session data matching the userId, or null if not found.
|
||||
*/
|
||||
suspend fun getSession(sessionId: String): SessionData?
|
||||
|
||||
/**
|
||||
* Get all sessions ordered by last usage descending.
|
||||
*/
|
||||
suspend fun getAllSessions(): List<SessionData>
|
||||
|
||||
/**
|
||||
* Get the number of sessions.
|
||||
*/
|
||||
suspend fun numberOfSessions(): Int
|
||||
|
||||
/**
|
||||
* Get the latest session, or null if no session exists.
|
||||
*/
|
||||
suspend fun getLatestSession(): SessionData?
|
||||
|
||||
/**
|
||||
* Set the session with [sessionId] as the latest used one.
|
||||
*/
|
||||
suspend fun setLatestSession(sessionId: String)
|
||||
|
||||
/**
|
||||
* Remove the session matching the sessionId.
|
||||
*/
|
||||
suspend fun removeSession(sessionId: String)
|
||||
}
|
||||
|
||||
fun List<SessionData>.toUserList(): List<String> {
|
||||
return map { it.userId }
|
||||
}
|
||||
|
||||
fun Flow<List<SessionData>>.toUserListFlow(): Flow<List<String>> {
|
||||
return map { it.toUserList() }
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a flow emitting the sessionId of the latest session if logged in, null otherwise.
|
||||
*/
|
||||
fun SessionStore.sessionIdFlow(): Flow<String?> {
|
||||
return loggedInStateFlow().map {
|
||||
when (it) {
|
||||
is LoggedInState.LoggedIn -> it.sessionId
|
||||
is LoggedInState.NotLoggedIn -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.sessionstorage.api.observer
|
||||
|
||||
interface SessionListener {
|
||||
suspend fun onSessionCreated(userId: String) {}
|
||||
suspend fun onSessionDeleted(userId: String, wasLastSession: Boolean) {}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.sessionstorage.api.observer
|
||||
|
||||
interface SessionObserver {
|
||||
fun addListener(listener: SessionListener)
|
||||
fun removeListener(listener: SessionListener)
|
||||
}
|
||||
Reference in New Issue
Block a user