mirror of
https://github.com/bitwarden/android.git
synced 2026-06-01 02:06:52 -05:00
BIT-2231: Disable components of the AccountSecurityScreen for TDE (#1276)
This commit is contained in:
committed by
Álison Fernandes
parent
52561215fe
commit
dc2a0d10b9
@@ -28,6 +28,8 @@ import androidx.compose.ui.unit.dp
|
||||
* @param onClick The callback when the row is clicked.
|
||||
* @param modifier The modifier to be applied to the layout.
|
||||
* @param description An optional description label to be displayed below the [text].
|
||||
* @param isEnabled Indicates if the row is enabled or not, a disabled row will not be clickable
|
||||
* and it's contents will be dimmed.
|
||||
* @param withDivider Indicates if a divider should be drawn on the bottom of the row, defaults
|
||||
* to `false`.
|
||||
* @param content The content of the [BitwardenTextRow].
|
||||
@@ -38,6 +40,7 @@ fun BitwardenTextRow(
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
description: String? = null,
|
||||
isEnabled: Boolean = true,
|
||||
withDivider: Boolean = false,
|
||||
content: (@Composable () -> Unit)? = null,
|
||||
) {
|
||||
@@ -45,6 +48,7 @@ fun BitwardenTextRow(
|
||||
contentAlignment = Alignment.BottomCenter,
|
||||
modifier = modifier
|
||||
.clickable(
|
||||
enabled = isEnabled,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = rememberRipple(color = MaterialTheme.colorScheme.primary),
|
||||
onClick = onClick,
|
||||
@@ -67,13 +71,17 @@ fun BitwardenTextRow(
|
||||
Text(
|
||||
text = text,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(
|
||||
alpha = if (isEnabled) 1.0f else 0.38f,
|
||||
),
|
||||
)
|
||||
description?.let {
|
||||
Text(
|
||||
text = it,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(
|
||||
alpha = if (isEnabled) 1.0f else 0.38f,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,6 +255,7 @@ fun AccountSecurityScreen(
|
||||
)
|
||||
}
|
||||
SessionTimeoutActionRow(
|
||||
isEnabled = state.hasUnlockMechanism,
|
||||
vaultTimeoutPolicyAction = state.vaultTimeoutPolicyAction,
|
||||
selectedVaultTimeoutAction = state.vaultTimeoutAction,
|
||||
onVaultTimeoutActionSelect = remember(viewModel) {
|
||||
@@ -293,27 +294,31 @@ fun AccountSecurityScreen(
|
||||
.semantics { testTag = "TwoStepLoginLinkItemView" }
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
BitwardenExternalLinkRow(
|
||||
text = stringResource(id = R.string.change_master_password),
|
||||
onConfirmClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(AccountSecurityAction.ChangeMasterPasswordClick) }
|
||||
},
|
||||
withDivider = false,
|
||||
dialogTitle = stringResource(id = R.string.continue_to_web_app),
|
||||
dialogMessage = stringResource(
|
||||
id = R.string.change_master_password_description_long,
|
||||
),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
BitwardenTextRow(
|
||||
text = stringResource(id = R.string.lock_now),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(AccountSecurityAction.LockNowClick) }
|
||||
},
|
||||
modifier = Modifier
|
||||
.semantics { testTag = "LockNowLabel" }
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
if (state.isUnlockWithPasswordEnabled) {
|
||||
BitwardenExternalLinkRow(
|
||||
text = stringResource(id = R.string.change_master_password),
|
||||
onConfirmClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(AccountSecurityAction.ChangeMasterPasswordClick) }
|
||||
},
|
||||
withDivider = false,
|
||||
dialogTitle = stringResource(id = R.string.continue_to_web_app),
|
||||
dialogMessage = stringResource(
|
||||
id = R.string.change_master_password_description_long,
|
||||
),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
if (state.hasUnlockMechanism) {
|
||||
BitwardenTextRow(
|
||||
text = stringResource(id = R.string.lock_now),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(AccountSecurityAction.LockNowClick) }
|
||||
},
|
||||
modifier = Modifier
|
||||
.semantics { testTag = "LockNowLabel" }
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
BitwardenTextRow(
|
||||
text = stringResource(id = R.string.log_out),
|
||||
onClick = remember(viewModel) {
|
||||
@@ -695,6 +700,7 @@ private fun SessionCustomTimeoutRow(
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
private fun SessionTimeoutActionRow(
|
||||
isEnabled: Boolean,
|
||||
vaultTimeoutPolicyAction: String?,
|
||||
selectedVaultTimeoutAction: VaultTimeoutAction,
|
||||
onVaultTimeoutActionSelect: (VaultTimeoutAction) -> Unit,
|
||||
@@ -703,7 +709,12 @@ private fun SessionTimeoutActionRow(
|
||||
var shouldShowSelectionDialog by rememberSaveable { mutableStateOf(false) }
|
||||
var shouldShowLogoutActionConfirmationDialog by rememberSaveable { mutableStateOf(false) }
|
||||
BitwardenTextRow(
|
||||
isEnabled = isEnabled,
|
||||
text = stringResource(id = R.string.session_timeout_action),
|
||||
description = stringResource(
|
||||
id = R.string.set_up_an_unlock_option_to_change_your_vault_timeout_action,
|
||||
)
|
||||
.takeUnless { isEnabled },
|
||||
onClick = {
|
||||
// The option is not selectable if there's a policy in place.
|
||||
if (vaultTimeoutPolicyAction != null) return@BitwardenTextRow
|
||||
@@ -714,7 +725,9 @@ private fun SessionTimeoutActionRow(
|
||||
Text(
|
||||
text = selectedVaultTimeoutAction.displayLabel(),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(
|
||||
alpha = if (isEnabled) 1.0f else 0.38f,
|
||||
),
|
||||
modifier = Modifier.semantics { testTag = "SessionTimeoutActionStatusLabel" },
|
||||
)
|
||||
}
|
||||
@@ -731,11 +744,11 @@ private fun SessionTimeoutActionRow(
|
||||
isSelected = option == selectedVaultTimeoutAction,
|
||||
onClick = {
|
||||
shouldShowSelectionDialog = false
|
||||
val seletedAction = vaultTimeoutActionOptions.first { it == option }
|
||||
if (seletedAction == VaultTimeoutAction.LOGOUT) {
|
||||
val selectedAction = vaultTimeoutActionOptions.first { it == option }
|
||||
if (selectedAction == VaultTimeoutAction.LOGOUT) {
|
||||
shouldShowLogoutActionConfirmationDialog = true
|
||||
} else {
|
||||
onVaultTimeoutActionSelect(seletedAction)
|
||||
onVaultTimeoutActionSelect(selectedAction)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@@ -231,13 +231,7 @@ class AccountSecurityViewModel @Inject constructor(
|
||||
private fun handleVaultTimeoutActionSelect(
|
||||
action: AccountSecurityAction.VaultTimeoutActionSelect,
|
||||
) {
|
||||
val vaultTimeoutAction = action.vaultTimeoutAction
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
vaultTimeoutAction = action.vaultTimeoutAction,
|
||||
)
|
||||
}
|
||||
settingsRepository.vaultTimeoutAction = vaultTimeoutAction
|
||||
setVaultTimeoutAction(action.vaultTimeoutAction)
|
||||
}
|
||||
|
||||
private fun handleTwoStepLoginClick() {
|
||||
@@ -261,6 +255,7 @@ class AccountSecurityViewModel @Inject constructor(
|
||||
} else {
|
||||
settingsRepository.clearBiometricsKey()
|
||||
mutableStateFlow.update { it.copy(isUnlockWithBiometricsEnabled = false) }
|
||||
validateVaultTimeoutAction()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,6 +268,7 @@ class AccountSecurityViewModel @Inject constructor(
|
||||
AccountSecurityAction.UnlockWithPinToggle.PendingEnabled -> Unit
|
||||
AccountSecurityAction.UnlockWithPinToggle.Disabled -> {
|
||||
settingsRepository.clearUnlockPin()
|
||||
validateVaultTimeoutAction()
|
||||
}
|
||||
|
||||
is AccountSecurityAction.UnlockWithPinToggle.Enabled -> {
|
||||
@@ -352,6 +348,17 @@ class AccountSecurityViewModel @Inject constructor(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun validateVaultTimeoutAction() {
|
||||
if (!state.hasUnlockMechanism) {
|
||||
setVaultTimeoutAction(VaultTimeoutAction.LOGOUT)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setVaultTimeoutAction(vaultTimeoutAction: VaultTimeoutAction) {
|
||||
mutableStateFlow.update { it.copy(vaultTimeoutAction = vaultTimeoutAction) }
|
||||
settingsRepository.vaultTimeoutAction = vaultTimeoutAction
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -369,7 +376,15 @@ data class AccountSecurityState(
|
||||
val vaultTimeoutAction: VaultTimeoutAction,
|
||||
val vaultTimeoutPolicyMinutes: Int?,
|
||||
val vaultTimeoutPolicyAction: String?,
|
||||
) : Parcelable
|
||||
) : Parcelable {
|
||||
/**
|
||||
* Indicates that there is a mechanism for unlocking your vault in place.
|
||||
*/
|
||||
val hasUnlockMechanism: Boolean
|
||||
get() = isUnlockWithPasswordEnabled ||
|
||||
isUnlockWithPinEnabled ||
|
||||
isUnlockWithBiometricsEnabled
|
||||
}
|
||||
|
||||
/**
|
||||
* Representation of the dialogs that can be displayed on account security screen.
|
||||
|
||||
Reference in New Issue
Block a user