Account management with OIDC: split account and session management. #1303

This commit is contained in:
Benoit Marty
2023-09-14 16:34:58 +02:00
committed by Benoit Marty
parent aa22e731f9
commit 51e663ffdc
11 changed files with 108 additions and 18 deletions

View File

@@ -29,6 +29,7 @@ import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.libraries.androidutils.browser.openUrlInChromeCustomTab
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.theme.ElementTheme
import timber.log.Timber
@ContributesNode(SessionScope::class)
@@ -67,9 +68,17 @@ class PreferencesRootNode @AssistedInject constructor(
plugins<Callback>().forEach { it.onOpenAbout() }
}
private fun onManageAccountClicked(activity: Activity, accountManagementUrl: String?) {
accountManagementUrl?.let {
activity.openUrlInChromeCustomTab(null, false, it)
private fun onManageAccountClicked(
activity: Activity,
url: String?,
isDark: Boolean,
) {
url?.let {
activity.openUrlInChromeCustomTab(
null,
darkTheme = isDark,
url = it
)
}
}
@@ -81,6 +90,7 @@ class PreferencesRootNode @AssistedInject constructor(
override fun View(modifier: Modifier) {
val state = presenter.present()
val activity = LocalContext.current as Activity
val isDark = ElementTheme.isLightTheme.not()
PreferencesRootView(
state = state,
modifier = modifier,
@@ -91,7 +101,7 @@ class PreferencesRootNode @AssistedInject constructor(
onVerifyClicked = this::onVerifyClicked,
onOpenDeveloperSettings = this::onOpenDeveloperSettings,
onSuccessLogout = { onSuccessLogout(activity, it) },
onManageAccountClicked = { onManageAccountClicked(activity, state.accountManagementUrl) },
onManageAccountClicked = { onManageAccountClicked(activity, it, isDark) },
onOpenNotificationSettings = this::onOpenNotificationSettings
)
}

View File

@@ -32,6 +32,7 @@ import io.element.android.libraries.designsystem.utils.collectSnackbarMessageAsS
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.oidc.AccountManagementAction
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.api.user.getCurrentUser
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
@@ -74,9 +75,12 @@ class PreferencesRootPresenter @Inject constructor(
val accountManagementUrl: MutableState<String?> = remember {
mutableStateOf(null)
}
val devicesManagementUrl: MutableState<String?> = remember {
mutableStateOf(null)
}
LaunchedEffect(Unit) {
initAccountManagementUrl(accountManagementUrl)
initAccountManagementUrl(accountManagementUrl, devicesManagementUrl)
}
val logoutState = logoutPresenter.present()
@@ -87,6 +91,7 @@ class PreferencesRootPresenter @Inject constructor(
version = versionFormatter.get(),
showCompleteVerification = showCompleteVerification,
accountManagementUrl = accountManagementUrl.value,
devicesManagementUrl = devicesManagementUrl.value,
showAnalyticsSettings = hasAnalyticsProviders,
showDeveloperSettings = showDeveloperSettings,
showNotificationSettings = showNotificationSettings.value,
@@ -98,7 +103,11 @@ class PreferencesRootPresenter @Inject constructor(
matrixUser.value = matrixClient.getCurrentUser()
}
private fun CoroutineScope.initAccountManagementUrl(accountManagementUrl: MutableState<String?>) = launch {
accountManagementUrl.value = matrixClient.getAccountManagementUrl().getOrNull()
private fun CoroutineScope.initAccountManagementUrl(
accountManagementUrl: MutableState<String?>,
devicesManagementUrl: MutableState<String?>,
) = launch {
accountManagementUrl.value = matrixClient.getAccountManagementUrl(AccountManagementAction.Profile).getOrNull()
devicesManagementUrl.value = matrixClient.getAccountManagementUrl(AccountManagementAction.SessionsList).getOrNull()
}
}

View File

@@ -26,6 +26,7 @@ data class PreferencesRootState(
val version: String,
val showCompleteVerification: Boolean,
val accountManagementUrl: String?,
val devicesManagementUrl: String?,
val showAnalyticsSettings: Boolean,
val showDeveloperSettings: Boolean,
val showNotificationSettings: Boolean,

View File

@@ -26,6 +26,7 @@ fun aPreferencesRootState() = PreferencesRootState(
version = "Version 1.1 (1)",
showCompleteVerification = true,
accountManagementUrl = "aUrl",
devicesManagementUrl = "anOtherUrl",
showAnalyticsSettings = true,
showDeveloperSettings = true,
showNotificationSettings = true,

View File

@@ -23,8 +23,8 @@ import androidx.compose.material.icons.outlined.BugReport
import androidx.compose.material.icons.outlined.DeveloperMode
import androidx.compose.material.icons.outlined.Help
import androidx.compose.material.icons.outlined.InsertChart
import androidx.compose.material.icons.outlined.ManageAccounts
import androidx.compose.material.icons.outlined.Notifications
import androidx.compose.material.icons.outlined.OpenInNew
import androidx.compose.material.icons.outlined.VerifiedUser
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@@ -53,7 +53,7 @@ fun PreferencesRootView(
state: PreferencesRootState,
onBackPressed: () -> Unit,
onVerifyClicked: () -> Unit,
onManageAccountClicked: () -> Unit,
onManageAccountClicked: (url: String) -> Unit,
onOpenAnalytics: () -> Unit,
onOpenRageShake: () -> Unit,
onOpenAbout: () -> Unit,
@@ -82,10 +82,11 @@ fun PreferencesRootView(
}
if (state.accountManagementUrl != null) {
PreferenceText(
title = stringResource(id = CommonStrings.screen_settings_oidc_account),
icon = Icons.Outlined.ManageAccounts,
onClick = onManageAccountClicked,
title = stringResource(id = CommonStrings.action_manage_account),
icon = Icons.Outlined.OpenInNew,
onClick = { onManageAccountClicked(state.accountManagementUrl) },
)
HorizontalDivider()
}
if (state.showAnalyticsSettings) {
PreferenceText(
@@ -94,7 +95,7 @@ fun PreferencesRootView(
onClick = onOpenAnalytics,
)
}
if(state.showNotificationSettings) {
if (state.showNotificationSettings) {
PreferenceText(
title = stringResource(id = CommonStrings.screen_notification_settings_title),
icon = Icons.Outlined.Notifications,
@@ -111,10 +112,19 @@ fun PreferencesRootView(
icon = Icons.Outlined.Help,
onClick = onOpenAbout,
)
HorizontalDivider()
if (state.devicesManagementUrl != null) {
PreferenceText(
title = stringResource(id = CommonStrings.action_manage_devices),
icon = Icons.Outlined.OpenInNew,
onClick = { onManageAccountClicked(state.devicesManagementUrl) },
)
HorizontalDivider()
}
if (state.showDeveloperSettings) {
DeveloperPreferencesView(onOpenDeveloperSettings)
HorizontalDivider()
}
HorizontalDivider()
LogoutPreferenceView(
state = state.logoutState,
onSuccessLogout = onSuccessLogout,

View File

@@ -73,6 +73,7 @@ class PreferencesRootPresenterTest {
assertThat(loadedState.showDeveloperSettings).isEqualTo(true)
assertThat(loadedState.showAnalyticsSettings).isEqualTo(false)
assertThat(loadedState.accountManagementUrl).isNull()
assertThat(loadedState.devicesManagementUrl).isNull()
}
}
}