diff --git a/app/src/main/kotlin/com/infomaniak/auth/ui/components/dialog/PasswordChangedDialog.kt b/app/src/main/kotlin/com/infomaniak/auth/ui/dialog/PasswordChangedDialog.kt similarity index 98% rename from app/src/main/kotlin/com/infomaniak/auth/ui/components/dialog/PasswordChangedDialog.kt rename to app/src/main/kotlin/com/infomaniak/auth/ui/dialog/PasswordChangedDialog.kt index e317a6b8..c8a60059 100644 --- a/app/src/main/kotlin/com/infomaniak/auth/ui/components/dialog/PasswordChangedDialog.kt +++ b/app/src/main/kotlin/com/infomaniak/auth/ui/dialog/PasswordChangedDialog.kt @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.infomaniak.auth.ui.components.dialog +package com.infomaniak.auth.ui.dialog import android.annotation.SuppressLint import androidx.compose.material3.AlertDialog diff --git a/app/src/main/kotlin/com/infomaniak/auth/ui/components/dialog/VerifyAccountSecurityDialog.kt b/app/src/main/kotlin/com/infomaniak/auth/ui/dialog/VerifyAccountSecurityDialog.kt similarity index 98% rename from app/src/main/kotlin/com/infomaniak/auth/ui/components/dialog/VerifyAccountSecurityDialog.kt rename to app/src/main/kotlin/com/infomaniak/auth/ui/dialog/VerifyAccountSecurityDialog.kt index 93b82070..73201b10 100644 --- a/app/src/main/kotlin/com/infomaniak/auth/ui/components/dialog/VerifyAccountSecurityDialog.kt +++ b/app/src/main/kotlin/com/infomaniak/auth/ui/dialog/VerifyAccountSecurityDialog.kt @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.infomaniak.auth.ui.components.dialog +package com.infomaniak.auth.ui.dialog import android.annotation.SuppressLint import androidx.compose.material3.AlertDialog diff --git a/app/src/main/kotlin/com/infomaniak/auth/ui/dialog/disconnect/DisconnectConfirmDialog.kt b/app/src/main/kotlin/com/infomaniak/auth/ui/dialog/disconnect/DisconnectConfirmDialog.kt new file mode 100644 index 00000000..f7b53473 --- /dev/null +++ b/app/src/main/kotlin/com/infomaniak/auth/ui/dialog/disconnect/DisconnectConfirmDialog.kt @@ -0,0 +1,97 @@ +/* + * Infomaniak Authenticator - Android + * Copyright (C) 2026 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.infomaniak.auth.ui.dialog.disconnect + +import android.annotation.SuppressLint +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel +import com.infomaniak.auth.R +import com.infomaniak.auth.ui.screen.accountdetails.DisconnectConfiguration +import com.infomaniak.auth.ui.theme.AuthenticatorTheme +import com.infomaniak.core.ui.compose.preview.PreviewSmallWindow + +@Composable +fun DisconnectConfirmDialog( + accountId: Long, + configuration: DisconnectConfiguration, + onAccountDisconnected: () -> Unit, + onDismissRequest: () -> Unit, + viewModel: DisconnectDialogViewModel = hiltViewModel() +) { + LaunchedEffect(Unit) { + viewModel.fetchAccountDetails(accountId) + } + + AlertDialog( + icon = { + Icon( + painter = painterResource(R.drawable.triangle_alert), + contentDescription = null + ) + }, + onDismissRequest = onDismissRequest, + title = { + Text( + text = stringResource(configuration.confirmationTitleResId), + textAlign = TextAlign.Center + ) + }, + text = { + Text(text = stringResource(configuration.confirmationDescriptionResId)) + }, + confirmButton = { + TextButton( + onClick = { + viewModel.removeAccount(onAccountRemoved = onAccountDisconnected) + }, + colors = ButtonDefaults.textButtonColors( + contentColor = MaterialTheme.colorScheme.error, + ) + ) { + Text(stringResource(configuration.criticalButtonStringResId)) + } + } + ) +} + +@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") +@PreviewSmallWindow +@Composable +private fun DisconnectWarningDialogPreview() { + AuthenticatorTheme { + Scaffold { _ -> + DisconnectConfirmDialog( + accountId = 1L, + configuration = DisconnectConfiguration.DisconnectSecuredAccount, + onAccountDisconnected = {}, + onDismissRequest = {}, + ) + } + } +} diff --git a/app/src/main/kotlin/com/infomaniak/auth/ui/dialog/disconnect/DisconnectDialogViewModel.kt b/app/src/main/kotlin/com/infomaniak/auth/ui/dialog/disconnect/DisconnectDialogViewModel.kt new file mode 100644 index 00000000..84a55ddd --- /dev/null +++ b/app/src/main/kotlin/com/infomaniak/auth/ui/dialog/disconnect/DisconnectDialogViewModel.kt @@ -0,0 +1,76 @@ +/* + * Infomaniak Authenticator - Android + * Copyright (C) 2026 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.infomaniak.auth.ui.dialog.disconnect + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.infomaniak.auth.lib.AuthenticatorFacade +import com.infomaniak.auth.utils.AccountUtils +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.launch +import javax.inject.Inject + +@OptIn(ExperimentalCoroutinesApi::class) +@HiltViewModel +class DisconnectDialogViewModel @Inject constructor( + private val accountUtils: AccountUtils, + private val authenticatorFacade: AuthenticatorFacade, +) : ViewModel() { + private val accountIdFlow = MutableSharedFlow(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) + + val userAccessToken = accountIdFlow + .flatMapLatest { id -> + combine( + accountUtils.users, + authenticatorFacade.accounts + ) { users, accounts -> + val user = users.find { it.id.toLong() == id } + val account = accounts.find { it.id == id } + + if (account != null) user?.apiToken?.accessToken else null + } + } + .stateIn( + scope = viewModelScope, + started = SharingStarted.Eagerly, + initialValue = null + ) + + fun fetchAccountDetails(accountId: Long) { + accountIdFlow.tryEmit(accountId) + } + + fun removeAccount(onAccountRemoved: () -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + accountIdFlow.first().let { accountId -> + accountUtils.removeUser(accountId.toInt()) + authenticatorFacade.removeAccount(token = null, id = accountId) + onAccountRemoved() + } + } + } +} diff --git a/app/src/main/kotlin/com/infomaniak/auth/ui/dialog/disconnect/DisconnectWarningDialog.kt b/app/src/main/kotlin/com/infomaniak/auth/ui/dialog/disconnect/DisconnectWarningDialog.kt new file mode 100644 index 00000000..a0a17821 --- /dev/null +++ b/app/src/main/kotlin/com/infomaniak/auth/ui/dialog/disconnect/DisconnectWarningDialog.kt @@ -0,0 +1,125 @@ +/* + * Infomaniak Authenticator - Android + * Copyright (C) 2026 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.infomaniak.auth.ui.dialog.disconnect + +import android.annotation.SuppressLint +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.infomaniak.auth.R +import com.infomaniak.auth.lib.models.UrlConstants +import com.infomaniak.auth.ui.screen.accountdetails.DisconnectConfiguration +import com.infomaniak.auth.ui.theme.AuthenticatorTheme +import com.infomaniak.core.network.ApiEnvironment +import com.infomaniak.core.ui.compose.preview.PreviewSmallWindow +import com.infomaniak.core.webview.ui.WebViewActivity + +@Composable +fun DisconnectWarningDialog( + accountId: Long, + configuration: DisconnectConfiguration, + onDismissRequest: () -> Unit, + onConfirmButton: () -> Unit, + viewModel: DisconnectDialogViewModel = hiltViewModel() +) { + val context = LocalContext.current + val host = ApiEnvironment.current.host + + val userAccessToken by viewModel.userAccessToken.collectAsStateWithLifecycle() + + LaunchedEffect(Unit) { + viewModel.fetchAccountDetails(accountId) + } + + AlertDialog( + icon = { + Icon( + painter = painterResource(R.drawable.ic_circle_information_outlined), + contentDescription = null + ) + }, + onDismissRequest = onDismissRequest, + title = { + Text( + text = stringResource(configuration.warningTitleResId), + textAlign = TextAlign.Center + ) + }, + text = { + Text(text = stringResource(configuration.warningDescriptionResId)) + }, + confirmButton = { + TextButton( + onClick = onConfirmButton, + colors = ButtonDefaults.textButtonColors( + contentColor = MaterialTheme.colorScheme.error, + ) + ) { + Text(stringResource(configuration.criticalButtonStringResId)) + } + }, + dismissButton = { + if (userAccessToken != null) { + TextButton( + onClick = { + onDismissRequest() + WebViewActivity.startActivity( + context = context, + url = UrlConstants.autologUrl( + host = host, + UrlConstants.managerUrl(host, configuration.dismissHelpUrl) + ), + headers = mapOf("Authorization" to "Bearer $userAccessToken"), + ) + } + ) { + Text(stringResource(configuration.neutralButtonStringResId)) + } + } + } + ) +} + +@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") +@PreviewSmallWindow +@Composable +private fun DisconnectWarningDialogPreview() { + AuthenticatorTheme { + Scaffold { _ -> + DisconnectWarningDialog( + accountId = 1L, + configuration = DisconnectConfiguration.DisconnectSecuredAccount, + onDismissRequest = {}, + onConfirmButton = {} + ) + } + } +} diff --git a/app/src/main/kotlin/com/infomaniak/auth/ui/navigation/NavDestination.kt b/app/src/main/kotlin/com/infomaniak/auth/ui/navigation/NavDestination.kt index 2143a237..5d068113 100644 --- a/app/src/main/kotlin/com/infomaniak/auth/ui/navigation/NavDestination.kt +++ b/app/src/main/kotlin/com/infomaniak/auth/ui/navigation/NavDestination.kt @@ -19,6 +19,7 @@ package com.infomaniak.auth.ui.navigation import androidx.compose.runtime.Immutable import androidx.navigation3.runtime.NavKey +import com.infomaniak.auth.ui.screen.accountdetails.DisconnectConfiguration import kotlinx.serialization.Serializable @Immutable @@ -85,6 +86,20 @@ sealed interface NavDestination : NavKey { @Serializable data class AccountDetails(val accountId: Long) : NavDestination + + //region Dialog + + interface DialogDestination : NavDestination + + sealed interface DisconnectDialog : DialogDestination { + @Serializable + data class DisconnectWarning(val accountId: Long, val configuration: DisconnectConfiguration) : DisconnectDialog + + @Serializable + data class DisconnectConfirmation(val accountId: Long, val configuration: DisconnectConfiguration) : DisconnectDialog + } + + //endregion } @Immutable diff --git a/app/src/main/kotlin/com/infomaniak/auth/ui/navigation/NavigationEntryProvider.kt b/app/src/main/kotlin/com/infomaniak/auth/ui/navigation/NavigationEntryProvider.kt index 6bcb22d4..7cbfea69 100644 --- a/app/src/main/kotlin/com/infomaniak/auth/ui/navigation/NavigationEntryProvider.kt +++ b/app/src/main/kotlin/com/infomaniak/auth/ui/navigation/NavigationEntryProvider.kt @@ -17,10 +17,14 @@ */ package com.infomaniak.auth.ui.navigation +import androidx.navigation3.runtime.EntryProviderScope import androidx.navigation3.runtime.NavBackStack import androidx.navigation3.runtime.NavEntry import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.entryProvider +import androidx.navigation3.scene.DialogSceneStrategy +import com.infomaniak.auth.ui.dialog.disconnect.DisconnectConfirmDialog +import com.infomaniak.auth.ui.dialog.disconnect.DisconnectWarningDialog import com.infomaniak.auth.ui.screen.accountdetails.AccountDetailsScreen import com.infomaniak.auth.ui.screen.accountlist.AccountListScreen import com.infomaniak.auth.ui.screen.home.HomeScreen @@ -72,9 +76,19 @@ fun baseEntryProvider( AccountDetailsScreen( accountId = it.accountId, onLoginPressed = { legacyAccount -> - backStack.add(NavDestination.LoginInApp.Form(legacyAccount, isOnboarding = false)) + backStack.add( + NavDestination.LoginInApp.Form(legacyAccountId = legacyAccount, isOnboarding = false) + ) }, - onBackPressed = backStack::tryPopLast + onBackPressed = backStack::tryPopLast, + onRemoveAccountClicked = { accountId, configuration -> + backStack.add( + NavDestination.DisconnectDialog.DisconnectWarning( + accountId = accountId, + configuration = configuration + ) + ) + } ) } entry { @@ -122,6 +136,45 @@ fun baseEntryProvider( returnToLoginScreen = backStack::tryPopLast, ) } + addDisconnectEntries(backStack) +} + +private fun EntryProviderScope.addDisconnectEntries(backStack: NavBackStack) { + entry( + metadata = DialogSceneStrategy.dialog() + ) { params -> + DisconnectWarningDialog( + params.accountId, + params.configuration, + onDismissRequest = { + backStack.clearDialog() + }, + onConfirmButton = { + backStack.clearDialog() + backStack.add( + NavDestination.DisconnectDialog.DisconnectConfirmation( + accountId = params.accountId, + configuration = params.configuration + ) + ) + } + ) + } + + entry( + metadata = DialogSceneStrategy.dialog() + ) { params -> + DisconnectConfirmDialog( + params.accountId, + params.configuration, + onAccountDisconnected = { + backStack.popUntil(NavDestination.Home) + }, + onDismissRequest = { + backStack.clearDialog() + } + ) + } } fun homeEntryProvider(rootBackStack: NavBackStack): (NavKey) -> NavEntry = entryProvider { @@ -155,6 +208,11 @@ fun NavBackStack.tryPopLast() { removeAt(lastIndex) } +fun NavBackStack.clearDialog() { + if (lastIndex == 0) return + removeAll { it is NavDestination.DialogDestination } +} + fun NavBackStack.replaceAllWith(destination: NavKey) { add(destination) removeAll { it != destination } diff --git a/app/src/main/kotlin/com/infomaniak/auth/ui/screen/accountdetails/AccountDetailsScreen.kt b/app/src/main/kotlin/com/infomaniak/auth/ui/screen/accountdetails/AccountDetailsScreen.kt index e143162b..58a2ae0b 100644 --- a/app/src/main/kotlin/com/infomaniak/auth/ui/screen/accountdetails/AccountDetailsScreen.kt +++ b/app/src/main/kotlin/com/infomaniak/auth/ui/screen/accountdetails/AccountDetailsScreen.kt @@ -69,6 +69,7 @@ fun AccountDetailsScreen( accountId: Long, onBackPressed: () -> Unit, onLoginPressed: (Long) -> Unit, + onRemoveAccountClicked: (Long, DisconnectConfiguration) -> Unit, viewModel: AccountDetailsViewModel = hiltViewModel(), ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() @@ -77,11 +78,6 @@ fun AccountDetailsScreen( viewModel.fetchAccountDetails(accountId) } - LaunchedEffect(Unit) { - viewModel.accountRemovedChannel.receive() - onBackPressed() - } - AccountDetailsScreen( uiState = { uiState }, onLoginPressed = onLoginPressed, @@ -89,9 +85,7 @@ fun AccountDetailsScreen( onChallengesRefreshClicked = { viewModel.refreshChallenges(accountId) }, - onRemoveAccountClicked = { - viewModel.removeAccount() - } + onRemoveAccountClicked = onRemoveAccountClicked ) } @@ -101,7 +95,7 @@ fun AccountDetailsScreen( onLoginPressed: (Long) -> Unit, onBackPressed: () -> Unit, onChallengesRefreshClicked: () -> Unit, - onRemoveAccountClicked: () -> Unit, + onRemoveAccountClicked: (Long, DisconnectConfiguration) -> Unit, modifier: Modifier = Modifier ) { SinglePaneScaffold( @@ -122,7 +116,9 @@ fun AccountDetailsScreen( user = uiState.user, onLoginPressed = onLoginPressed, onChallengesRefreshClicked = onChallengesRefreshClicked, - onRemoveAccountClicked = onRemoveAccountClicked + onRemoveAccountClicked = { + onRemoveAccountClicked(uiState.account.id, uiState.disconnectConfiguration) + } ) } is AccountDetailsUiState.Loading -> Unit @@ -242,7 +238,7 @@ private fun SettingsSections( } add( OptionItemType.Default( - stringResId = R.string.disconnectButton, + stringResId = if (accountStatus is Account.Status.NotConnected) R.string.removeAccountButton else R.string.disconnectButton, textColor = AuthenticatorTheme.materialColors.error, onClick = { onRemoveAccountClicked() @@ -265,11 +261,15 @@ private fun AccountDetailsScreenPreview( ) { AuthenticatorTheme { AccountDetailsScreen( - uiState = { AccountDetailsUiState.Success(accountPairs.first, accountPairs.second) }, + uiState = { AccountDetailsUiState.Success( + account = accountPairs.first, + user = accountPairs.second, + disconnectConfiguration = DisconnectConfiguration.DisconnectSecuredAccount + ) }, onLoginPressed = {}, onBackPressed = {}, onChallengesRefreshClicked = {}, - onRemoveAccountClicked = {}, + onRemoveAccountClicked = { _, _ -> }, ) } } diff --git a/app/src/main/kotlin/com/infomaniak/auth/ui/screen/accountdetails/AccountDetailsViewModel.kt b/app/src/main/kotlin/com/infomaniak/auth/ui/screen/accountdetails/AccountDetailsViewModel.kt index 77e6e572..dd12d84a 100644 --- a/app/src/main/kotlin/com/infomaniak/auth/ui/screen/accountdetails/AccountDetailsViewModel.kt +++ b/app/src/main/kotlin/com/infomaniak/auth/ui/screen/accountdetails/AccountDetailsViewModel.kt @@ -20,24 +20,23 @@ package com.infomaniak.auth.ui.screen.accountdetails import androidx.compose.runtime.Immutable import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.infomaniak.auth.R import com.infomaniak.auth.lib.Account import com.infomaniak.auth.lib.AuthenticatorFacade +import com.infomaniak.auth.lib.models.UrlConstants import com.infomaniak.auth.utils.AccountUtils import com.infomaniak.core.auth.models.user.User import com.infomaniak.core.twofactorauth.back.TwoFactorAuthManager import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.launch +import kotlinx.serialization.Serializable import javax.inject.Inject @OptIn(ExperimentalCoroutinesApi::class) @@ -59,7 +58,11 @@ class AccountDetailsViewModel @Inject constructor( val account = accounts.find { it.id == id } if (account != null) { - AccountDetailsUiState.Success(account, user) + AccountDetailsUiState.Success( + account = account, + user = user, + disconnectConfiguration = genDisconnectConfiguration(status = account.status) + ) } else { AccountDetailsUiState.Error } @@ -70,22 +73,21 @@ class AccountDetailsViewModel @Inject constructor( started = SharingStarted.Eagerly, initialValue = AccountDetailsUiState.Loading ) - - val accountRemovedChannel = Channel(Channel.CONFLATED) - + fun fetchAccountDetails(accountId: Long) { accountIdFlow.tryEmit(accountId) } - fun removeAccount() { - viewModelScope.launch(Dispatchers.IO) { - accountIdFlow.first() - .let { accountId -> accountUtils.users.first().firstOrNull { it.id.toLong() == accountId } } - ?.let { user -> - authenticatorFacade.removeAccount(user.apiToken.accessToken, user.id.toLong()) - accountUtils.removeUser(user.id) - accountRemovedChannel.send(Unit) + private fun genDisconnectConfiguration(status: Account.Status): DisconnectConfiguration { + return when (status) { + is Account.Status.LoggedIn -> { + if (status.isSecured) { + DisconnectConfiguration.DisconnectSecuredAccount + } else { + DisconnectConfiguration.DisconnectPartiallySecuredAccount } + } + else -> DisconnectConfiguration.DisconnectNotConnectedAccount } } @@ -97,6 +99,51 @@ class AccountDetailsViewModel @Inject constructor( @Immutable sealed interface AccountDetailsUiState { data object Loading : AccountDetailsUiState - data class Success(val account: Account, val user: User?) : AccountDetailsUiState + data class Success( + val account: Account, + val user: User?, + val disconnectConfiguration: DisconnectConfiguration + ) : AccountDetailsUiState data object Error : AccountDetailsUiState } + +@Serializable +enum class DisconnectConfiguration( + val warningTitleResId: Int, + val warningDescriptionResId: Int, + val confirmationTitleResId: Int, + val confirmationDescriptionResId: Int, + val neutralButtonStringResId: Int, + val criticalButtonStringResId: Int, + val dismissHelpUrl: String +) { + DisconnectSecuredAccount( + warningTitleResId = R.string.disconnectAccountWarningTitle, + warningDescriptionResId = R.string.disconnectAccountWarningDescription, + confirmationTitleResId = R.string.disconnectAccountTitle, + confirmationDescriptionResId = R.string.disconnectAccountOnThisDeviceDescription, + neutralButtonStringResId = R.string.checkMyMethodsButton, + criticalButtonStringResId = R.string.disconnectCriticalButton, + dismissHelpUrl = UrlConstants.SETTINGS_ACCOUNT_SECURITY_URL, + ), + + DisconnectPartiallySecuredAccount( + warningTitleResId = R.string.disconnectAccountPartiallySecuredWarningTitle, + warningDescriptionResId = R.string.disconnectAccountPartiallySecuredWarningDescription, + confirmationTitleResId = R.string.disconnectAccountTitle, + confirmationDescriptionResId = R.string.disconnectPartiallySecuredDescription, + neutralButtonStringResId = R.string.disconnectAccountAdd2faButton, + criticalButtonStringResId = R.string.disconnectCriticalButton, + dismissHelpUrl = UrlConstants.SETTINGS_2FA_MANAGER_URL, + ), + + DisconnectNotConnectedAccount( + warningTitleResId = R.string.removeAccountWarningTitle, + warningDescriptionResId = R.string.removeAccountWarningDescription, + confirmationTitleResId = R.string.removeAccountTitle, + confirmationDescriptionResId = R.string.removeAccountDescription, + neutralButtonStringResId = R.string.checkMyMethodsButton, + criticalButtonStringResId = R.string.removeAccountTitle, + dismissHelpUrl = UrlConstants.SETTINGS_ACCOUNT_SECURITY_URL, + ) +} diff --git a/app/src/main/kotlin/com/infomaniak/auth/ui/screen/main/MainScreen.kt b/app/src/main/kotlin/com/infomaniak/auth/ui/screen/main/MainScreen.kt index 6bbf9a83..5d1e69d2 100644 --- a/app/src/main/kotlin/com/infomaniak/auth/ui/screen/main/MainScreen.kt +++ b/app/src/main/kotlin/com/infomaniak/auth/ui/screen/main/MainScreen.kt @@ -35,6 +35,7 @@ import androidx.navigation3.runtime.NavEntryDecorator import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.rememberNavBackStack import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator +import androidx.navigation3.scene.DialogSceneStrategy import androidx.navigation3.ui.NavDisplay import androidx.navigationevent.NavigationEventDispatcher import androidx.navigationevent.NavigationEventDispatcherOwner @@ -47,8 +48,8 @@ import com.infomaniak.auth.lib.Account import com.infomaniak.auth.lib.AppStatus import com.infomaniak.auth.lib.models.UrlConstants.HELP_SUPPORT_URL import com.infomaniak.auth.lib.models.UrlConstants.RECOVER_PASSWORD_URL -import com.infomaniak.auth.ui.components.dialog.PasswordChangedDialog -import com.infomaniak.auth.ui.components.dialog.VerifyAccountSecurityDialog +import com.infomaniak.auth.ui.dialog.PasswordChangedDialog +import com.infomaniak.auth.ui.dialog.VerifyAccountSecurityDialog import com.infomaniak.auth.ui.navigation.NavDestination import com.infomaniak.auth.ui.navigation.baseEntryProvider import com.infomaniak.auth.ui.navigation.replaceAllWith @@ -146,10 +147,13 @@ fun MainScreen( backStack: NavBackStack, entryDecorators: ImmutableList>, ) { + val dialogStrategy = remember { DialogSceneStrategy() } + NavDisplay( backStack = backStack, entryDecorators = entryDecorators, entryProvider = baseEntryProvider(backStack), + sceneStrategies = listOf(dialogStrategy), transitionSpec = { defaultEnterAnimation }, popTransitionSpec = { defaultExitAnimation }, predictivePopTransitionSpec = { defaultExitAnimation }, diff --git a/app/src/main/res/drawable/ic_circle_information_outlined.xml b/app/src/main/res/drawable/ic_circle_information_outlined.xml new file mode 100644 index 00000000..13a5afbe --- /dev/null +++ b/app/src/main/res/drawable/ic_circle_information_outlined.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index c216b356..11d2ad41 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -68,12 +68,17 @@ Afvis Beskrivelse Enhed + Tilføj endnu et trin Din konto vil ikke længere være beskyttet af totrinsbekræftelse og vil blive sårbar over for uautoriseret adgang. Du vil ikke længere kunne godkende login på denne enhed med Authenticator. + Denne enhed er den eneste, der er autoriseret til at logge ind.\n\nTilføj en anden enhed eller login-metode, før du fortsætter. + Hvis du afbryder forbindelsen til kontoen, fjernes dens beskyttelse Afbryd denne konto Sørg for, at dine bekræftelses- og gendannelsesmetoder stadig er opdaterede for ikke at miste adgangen til din konto. Afbrydelse af denne konto kan svække dens sikkerhed Log ud + Afbryd forbindelsen til kontoen + Din konto vil ikke længere være beskyttet af totrinsbekræftelse og vil være sårbar over for uautoriseret adgang. Konto afbrudt Færdig E-mail @@ -120,9 +125,12 @@ Glemt adgangskode? Adgangskode Opdater afventende login + Fjern konto Du vil ikke længere kunne bekræfte dit login til denne konto med Authenticator. Konto fjernet Fjern konto + Hvis Authenticator er din eneste totrinsbekræftelse, kan du blive låst ude, næste gang du prøver at logge ind. + Fjern konto Fjern Påkrævet Ikon for sikret konto diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 4ba4f7ac..ccd07132 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -69,12 +69,17 @@ Ablehnen Beschreibung Gerät + Einen weiteren Schritt hinzufügen Ihr Konto wird nicht mehr durch die Zwei-Faktor-Verifizierung geschützt und ist anfällig für unbefugten Zugriff. Sie können die Anmeldung auf diesem Gerät nicht mehr mit Authenticator bestätigen. + Dieses Gerät ist das einzige, das zur Anmeldung berechtigt ist.\n\nFügen Sie ein anderes Gerät oder eine andere Anmeldemethode hinzu, bevor Sie fortfahren. + Durch das Trennen der Verbindung wird der Schutz des Kontos aufgehoben Dieses Konto trennen Stellen Sie sicher, dass Ihre Verifizierungs- und Wiederherstellungsmethoden immer aktuell sind, um den Zugriff auf Ihr Konto nicht zu verlieren. Das Trennen dieses Kontos kann dessen Sicherheit beeinträchtigen Abmelden + Trennen Sie das Konto + Ihr Konto ist dann nicht mehr durch die zweistufige Verifizierung geschützt und anfällig für unbefugten Zugriff. Konto getrennt Fertig E-Mail @@ -121,9 +126,12 @@ Passwort vergessen? Passwort Ausstehende Anmeldungen aktualisieren + Konto entfernen Sie können sich nicht mehr mit Authenticator bei diesem Konto anmelden. Konto entfernt Konto entfernen + Wenn Authenticator Ihre einzige Methode der zweistufigen Verifizierung ist, werden Sie möglicherweise beim nächsten Anmeldeversuch gesperrt. + Konto entfernen Entfernen Erforderlich Symbol für ein gesichertes Konto diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index bbc921c3..9ecf7a3b 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -68,12 +68,17 @@ Άρνηση Περιγραφή Συσκευή + Προσθήκη ενός άλλου βήματος Ο λογαριασμός σας δεν θα προστατεύεται πλέον από επαλήθευση σε δύο βήματα και θα γίνει ευάλωτος σε μη εξουσιοδοτημένη πρόσβαση. Δεν θα μπορείτε πλέον να εγκρίνετε συνδέσεις σε αυτή τη συσκευή με το Authenticator. + Αυτή η συσκευή είναι η μόνη εξουσιοδοτημένη να συνδεθεί.\n\nΠροσθέστε άλλη συσκευή ή μέθοδο σύνδεσης πριν συνεχίσετε. + Η αποσύνδεση του λογαριασμού θα καταργήσει την προστασία του Αποσύνδεση αυτού του λογαριασμού Βεβαιωθείτε ότι οι μέθοδοι επαλήθευσης και ανάκτησής σας είναι ενημερωμένοι για να αποφύγετε την απώλεια πρόσβασης στον λογαριασμό σας. Η αποσύνδεση αυτού του λογαριασμού μπορεί να εξασθενήσει την ασφάλειά του Αποσύνδεση + Αποσυνδέστε το λογαριασμό + Ο λογαριασμός σας δεν θα προστατεύεται πλέον από επαλήθευση δύο βημάτων και θα είναι ευάλωτος σε μη εξουσιοδοτημένη πρόσβαση. Ο λογαριασμός αποσυνδέθηκε Τέλος Email @@ -120,9 +125,12 @@ Ξεχάσατε τον κωδικό πρόσβασης; Κωδικός πρόσβασης Ανανέωση εκκρεμών συνδέσεων + Κατάργηση λογαριασμού Δεν θα μπορείτε πλέον να επαληθεύετε τη σύνδεσή σας σε αυτόν τον λογαριασμό με το Authenticator. Ο λογαριασμός αφαιρέθηκε Αφαίρεση λογαριασμού + Εάν ο Αυθεντικός έλεγχος είναι η μόνη μέθοδος επαλήθευσης δύο βημάτων, ενδέχεται να κλειδωθείτε την επόμενη φορά που θα προσπαθήσετε να συνδεθείτε. + Κατάργηση λογαριασμού Αφαίρεση Απαιτούμενο Εικονίδιο ασφαλισμένου λογαριασμού diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 16e065b3..66f4387f 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -69,12 +69,17 @@ Denegar Descripción Dispositivo + Añadir otro paso Su cuenta ya no estará protegida por la verificación en dos pasos y se volverá vulnerable a accesos no autorizados. Ya no podrá validar el inicio de sesión en este dispositivo con Authenticator. + Este dispositivo es el único autorizado para iniciar sesión.\n\nAñade otro dispositivo o método de inicio de sesión antes de continuar. + La desconexión de la cuenta eliminará su protección Desconectar esta cuenta Verifique que sus métodos de verificación y recuperación estén siempre actualizados para no perder el acceso a su cuenta. Desconectar esta cuenta puede debilitar su seguridad Cerrar sesión + Desconectar la cuenta + Su cuenta dejará de estar protegida por la verificación en dos pasos y será vulnerable a accesos no autorizados. Cuenta desconectada Listo Correo electrónico @@ -121,9 +126,12 @@ ¿Olvidaste tu contraseña? Contraseña Actualizar inicios de sesión pendientes + Eliminar cuenta Ya no podrá verificar su inicio de sesión en esta cuenta con Authenticator. Cuenta eliminada Eliminar cuenta + Si Authenticator es su único método de verificación en dos pasos, es posible que se bloquee la próxima vez que intente iniciar sesión. + Eliminar cuenta Eliminar Requerido Icono de cuenta protegida diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index cc9b7af2..e6b3be8c 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -68,12 +68,17 @@ Hylkää Kuvaus Laite + Lisää toinen vaihe Tilisi ei ole enää suojattu kaksivaiheisella todennuksella ja se on altis luvattomalle käytölle. Et voi enää hyväksyä kirjautumisia tällä laitteella Authenticatorilla. + Tämä laite on ainoa, jolla on lupa kirjautua sisään.\n\nLisää toinen laite tai kirjautumismenetelmä ennen jatkamista. + Tilin yhteyden katkaiseminen poistaa sen suojauksen Katkaise tämän tilin yhteys Varmista että vahvistus- ja palautusmenetelmäsi ovat edelleen ajan tasalla, jotta et menetä pääsyä tiliisi. Tämän tilin yhteyden katkaiseminen voi heikentää sen turvallisuutta Kirjaudu ulos + Tilin katkaiseminen + Tiliäsi ei enää suojata kaksivaiheisella vahvistuksella, ja se on altis luvattomalle käytölle. Tilin yhteys katkaistu Valmis Sähköposti @@ -120,9 +125,12 @@ Unohditko salasanan? Salasana Päivitä odottavat kirjautumiset + Poista tili Et voi enää vahvistaa kirjautumistasi tälle tilille Authenticatorilla. Tili poistettu Poista tili + Jos Authenticator on ainoa kaksivaiheinen vahvistusmenetelmäsi, saatat jäädä ulos, kun yrität kirjautua sisään seuraavan kerran. + Poista tili Poista Vaadittu Tilin turvattu kuvake diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index e85c39f4..d2e83791 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -69,12 +69,17 @@ Refuser Description Appareil + Ajouter une autre étape Votre compte ne sera plus protégé par la validation en deux étapes et deviendra vulnérable aux accès non autorisés. Vous ne pourrez plus valider la connexion sur cet appareil avec Authenticator. + Cet appareil est le seul autorisé à se connecter.\n\nAjoutez un autre appareil ou une autre méthode de connexion avant de continuer. + La déconnexion du compte supprimera sa protection Déconnecter ce compte Vérifiez que vos méthodes de validation et de récupération soient toujours à jour pour ne pas perdre l’accès à votre compte. Déconnecter ce compte peut affaiblir sa sécurité Se déconnecter + Déconnecter le compte + Votre compte ne sera plus protégé par la vérification en deux étapes et sera vulnérable à un accès non autorisé. Compte déconnecté Terminer E-mail @@ -121,9 +126,12 @@ Mot de passe oublié ? Mot de passe Actualiser les connexions en attente + Retirer le compte Vous ne pourrez plus valider la connexion à ce compte avec Authenticator. Compte retiré Retirer le compte + Si Authenticator est votre seule méthode de vérification en deux étapes, vous risquez d’être bloqué lors de votre prochaine tentative de connexion. + Retirer le compte Retirer Requis Icône de compte sécurisé diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 978197be..a82032c1 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -69,12 +69,17 @@ Nega Descrizione Dispositivo + Aggiungi un altro passo Il tuo account non sarà più protetto dalla verifica a due passaggi e diventerà vulnerabile ad accessi non autorizzati. Non potrai più verificare l’accesso su questo dispositivo con Authenticator. + Questo dispositivo è l’unico autorizzato ad accedere.\n\nAggiungere un altro dispositivo o metodo di accesso prima di continuare. + La disconnessione dell’account ne rimuove la protezione Disconnetti questo account Verifica che i tuoi metodi di verifica e recupero siano sempre aggiornati per non perdere l’accesso al tuo account. Disconnettere questo account può indebolirne la sicurezza Disconnettiti + Disconnettere l’account + Il vostro account non sarà più protetto dalla verifica in due passaggi e sarà vulnerabile ad accessi non autorizzati. Account disconnesso Fine Email @@ -121,9 +126,12 @@ Hai dimenticato la password? Password Aggiorna accessi in sospeso + Rimuovere l’account Non potrai più verificare l’accesso a questo account con Authenticator. Account rimosso Rimuovi account + Se Authenticator è l’unico metodo di verifica in due passaggi, è possibile che si venga bloccati al successivo tentativo di accesso. + Rimuovere l’account Rimuovi Richiesto Icona del conto protetto diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index edd44f9e..a50ebae9 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -68,12 +68,17 @@ Avvis Beskrivelse Enhet + Legg til et nytt trinn Kontoen din vil ikke lenger være beskyttet av totrinnsverifisering og vil bli sårbar for uautorisert tilgang. Du vil ikke lenger kunne godkjenne pålogginger på denne enheten med Authenticator. + Denne enheten er den eneste som er autorisert til å logge på.\n\nLegg til en annen enhet eller påloggingsmetode før du fortsetter. + Hvis du kobler fra kontoen, oppheves beskyttelsen av den Koble fra denne kontoen Sørg for at verifiserings- og gjenopprettingsmetodene dine fortsatt er oppdaterte for å unngå å miste tilgangen til kontoen din. Å koble fra denne kontoen kan svekke sikkerheten Logg ut + Koble fra kontoen + Kontoen din vil ikke lenger være beskyttet av totrinnsbekreftelse og vil være sårbar for uautorisert tilgang. Konto frakoblet Ferdig E-post @@ -120,9 +125,12 @@ Glemt passord? Passord Oppdater ventende pålogginger + Fjern konto Du vil ikke lenger kunne verifisere påloggingen din til denne kontoen med Authenticator. Konto fjernet Fjern konto + Hvis Authenticator er din eneste totrinnsbekreftelsesmetode, kan du bli låst neste gang du prøver å logge på. + Fjern konto Fjern Nødvendig Ikon for sikret konto diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 595e4832..0d12abd6 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -68,12 +68,17 @@ Weigeren Beschrijving Apparaat + Nog een stap toevoegen Uw account zal niet langer worden beschermd door twee-stapsverificatie en zal kwetsbaar worden voor ongeautoriseerde toegang. U kunt geen inloggen meer goedkeuren op dit apparaat met Authenticator. + Dit apparaat is het enige dat gemachtigd is om aan te melden.\n\nVoeg een ander apparaat of een andere aanmeldingsmethode toe voordat u doorgaat. + Door de verbinding met de account te verbreken, wordt de beveiliging verwijderd Dit account loskoppelen Zorg ervoor dat uw verificatie- en herstelmethoden nog steeds up-to-date zijn om de toegang tot uw account niet te verliezen. Het loskoppelen van dit account kan de beveiliging ervan verzwakken Uitloggen + De account ontkoppelen + Je account wordt niet langer beschermd door verificatie in twee stappen en is kwetsbaar voor ongeautoriseerde toegang. Account losgekoppeld Gereed E-mail @@ -120,9 +125,12 @@ Wachtwoord vergeten? Wachtwoord In afwachting zijnde inloggen vernieuwen + Account verwijderen U kunt uw inloggen naar dit account niet langer verifiëren met Authenticator. Account verwijderd Account verwijderen + Als Authenticator uw enige tweestapsverificatiemethode is, wordt u mogelijk uitgesloten wanneer u de volgende keer probeert in te loggen. + Account verwijderen Verwijderen Vereist Pictogram voor beveiligde account diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 59c5d7f3..d33d80c6 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -68,12 +68,17 @@ Odmów Opis Urządzenie + Dodaj kolejny krok Twoje konto nie będzie już chronione przez weryfikację dwuetapową i stanie się podatne na nieautoryzowany dostęp. Nie będziesz już mógł zatwierdzać logowań na tym urządzeniu za pomocą Authenticatora. + To urządzenie jest jedynym uprawnionym do logowania.\n\nPrzed kontynuowaniem dodaj inne urządzenie lub metodę logowania. + Odłączenie konta spowoduje usunięcie jego ochrony Odłącz to konto Upewnij się, że Twoje metody weryfikacji i odzyskiwania są nadal aktualne, aby nie stracić dostępu do konta. Odłączenie tego konta może osłabić jego bezpieczeństwo Wyloguj się + Odłączenie konta + Twoje konto nie będzie już chronione weryfikacją dwuetapową i będzie podatne na nieautoryzowany dostęp. Konto odłączone Gotowe E-mail @@ -120,9 +125,12 @@ Nie pamiętasz hasła? Hasło Odśwież oczekujące logowania + Usuń konto Nie będziesz już mógł weryfikować logowania do tego konta za pomocą Authenticatora. Konto usunięte Usuń konto + Jeśli Authenticator jest jedyną metodą weryfikacji dwuetapowej, możesz zostać zablokowany przy następnej próbie logowania. + Usuń konto Usuń Wymagane Ikona zabezpieczonego konta diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 4fe6d3d4..14db56de 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -68,12 +68,17 @@ Negar Descrição Dispositivo + Adicionar outra etapa Sua conta não estará mais protegida pela verificação em duas etapas e ficará vulnerável a acessos não autorizados. Você não poderá mais aprovar logins neste dispositivo com o Authenticator. + Este dispositivo é o único autorizado a iniciar sessão.\n\nAdicione outro dispositivo ou método de início de sessão antes de continuar. + A desconexão da conta removerá a sua proteção Desconectar esta conta Certifique-se de que seus métodos de verificação e recuperação ainda estão atualizados para evitar perder o acesso à sua conta. Desconectar esta conta pode enfraquecer sua segurança Sair + Desligar a conta + A sua conta deixará de estar protegida pela verificação em dois passos e ficará vulnerável a acessos não autorizados. Conta desconectada Concluir E-mail @@ -120,9 +125,12 @@ Esqueceu-se da palavra-passe? Palavra-passe Atualizar logins pendentes + Remover conta Você não poderá mais verificar seu login nesta conta com o Authenticator. Conta removida Remover conta + Se o Authenticator for o seu único método de verificação em dois passos, poderá ficar bloqueado da próxima vez que tentar iniciar sessão. + Remover conta Remover Necessário Ícone de conta protegida diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 4b053653..507c65d2 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -68,12 +68,17 @@ Neka Beskrivning Enhet + Lägg till ytterligare ett steg Ditt konto kommer inte längre att skyddas av tvåstegsverifiering och blir sårbart för obehörig åtkomst. Du kommer inte längre att kunna godkänna inloggningar på denna enhet med Authenticator. + Den här enheten är den enda som är behörig att logga in.\n\nLägg till en annan enhet eller inloggningsmetod innan du fortsätter. + Om du kopplar bort kontot tas dess skydd bort Koppla från detta konto Se till att dina verifierings- och återställningsmetoder fortfarande är uppdaterade för att undvika att förlora åtkomst till ditt konto. Att koppla från detta konto kan försvaga dess säkerhet Logga ut + Koppla bort kontot + Ditt konto kommer inte längre att skyddas av tvåstegsverifiering och kommer att vara sårbart för obehörig åtkomst. Konto frånkopplat Klar E-post @@ -120,9 +125,12 @@ Glömt lösenordet? Lösenord Uppdatera väntande inloggningar + Ta bort konto Du kommer inte längre att kunna verifiera din inloggning till detta konto med Authenticator. Konto borttaget Ta bort konto + Om Authenticator är din enda metod för tvåstegsverifiering kan du bli utelåst nästa gång du försöker logga in. + Ta bort konto Ta bort Krävs Ikon för säkrat konto diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 74c3562e..3ef266ab 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -69,12 +69,17 @@ Deny Description Device + Add another step Your account will no longer be protected by two-step verification and will become vulnerable to unauthorized access. You will no longer be able to approve logins on this device with Authenticator. + This device is the only one authorized to sign in.\n\nAdd another device or sign-in method before continuing. + Disconnecting the account will remove its protection Disconnect this account Make sure your verification and recovery methods are still up to date to avoid losing access to your account. Disconnecting this account may weaken its security Log out + Disconnect the account + Your account will no longer be protected by two-step verification and will be vulnerable to unauthorized access. Account disconnected Done Email @@ -121,9 +126,12 @@ Forgot password? Password Refresh pending logins + Remove account You will no longer be able to verify your login to this account with Authenticator. Account removed Remove account + If Authenticator is your only two-step verification method, you may be locked out the next time you try to log in. + Remove account Remove Required Account secured icon diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4dfb281d..65cf8c5d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ kotlin = "2.3.0" osmerionkotlinBase32 = "1.0.0" ksp = "2.3.4" lifecycleViewmodelNav3 = "2.10.0" -nav3Core = "1.0.0" +nav3Core = "1.1.1" room = "2.8.4" skie = "0.10.9" sonarqube = "7.2.3.7755"