mirror of
https://github.com/bitwarden/android.git
synced 2026-03-21 13:52:07 -05:00
PM-8953: Require 4 digits for pin entry (#4914)
This commit is contained in:
@@ -38,6 +38,8 @@ import com.x8bit.bitwarden.ui.platform.components.model.CardStyle
|
|||||||
import com.x8bit.bitwarden.ui.platform.components.util.maxDialogHeight
|
import com.x8bit.bitwarden.ui.platform.components.util.maxDialogHeight
|
||||||
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
|
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
|
||||||
|
|
||||||
|
private const val MINIMUM_PIN_LENGTH: Int = 4
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A dialog for setting a user's PIN.
|
* A dialog for setting a user's PIN.
|
||||||
*
|
*
|
||||||
@@ -138,6 +140,7 @@ fun PinInputDialog(
|
|||||||
|
|
||||||
BitwardenFilledButton(
|
BitwardenFilledButton(
|
||||||
label = stringResource(id = R.string.submit),
|
label = stringResource(id = R.string.submit),
|
||||||
|
isEnabled = !isPinCreation || pin.length >= MINIMUM_PIN_LENGTH,
|
||||||
onClick = { onSubmitClick(pin) },
|
onClick = { onSubmitClick(pin) },
|
||||||
modifier = Modifier.testTag(tag = "AcceptAlertButton"),
|
modifier = Modifier.testTag(tag = "AcceptAlertButton"),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -480,7 +480,7 @@ Scanning will happen automatically.</string>
|
|||||||
<string name="unlock">Unlock</string>
|
<string name="unlock">Unlock</string>
|
||||||
<string name="unlock_vault">Unlock vault</string>
|
<string name="unlock_vault">Unlock vault</string>
|
||||||
<string name="thirty_minutes">30 minutes</string>
|
<string name="thirty_minutes">30 minutes</string>
|
||||||
<string name="set_pin_description">Set your PIN code for unlocking Bitwarden. Your PIN settings will be reset if you ever fully log out of the application.</string>
|
<string name="set_pin_description">Your PIN must be at least 4 characters. Your PIN settings will be reset if you ever fully log out of the application.</string>
|
||||||
<string name="logged_in_as_on">Logged in as %1$s on %2$s.</string>
|
<string name="logged_in_as_on">Logged in as %1$s on %2$s.</string>
|
||||||
<string name="vault_locked_master_password">Your vault is locked. Verify your master password to continue.</string>
|
<string name="vault_locked_master_password">Your vault is locked. Verify your master password to continue.</string>
|
||||||
<string name="vault_locked_pin">Your vault is locked. Verify your PIN code to continue.</string>
|
<string name="vault_locked_pin">Your vault is locked. Verify your PIN code to continue.</string>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.x8bit.bitwarden.ui.auth.feature.accountsetup
|
|||||||
|
|
||||||
import androidx.compose.ui.test.assertIsDisplayed
|
import androidx.compose.ui.test.assertIsDisplayed
|
||||||
import androidx.compose.ui.test.assertIsEnabled
|
import androidx.compose.ui.test.assertIsEnabled
|
||||||
|
import androidx.compose.ui.test.assertIsNotEnabled
|
||||||
import androidx.compose.ui.test.assertIsOff
|
import androidx.compose.ui.test.assertIsOff
|
||||||
import androidx.compose.ui.test.assertIsOn
|
import androidx.compose.ui.test.assertIsOn
|
||||||
import androidx.compose.ui.test.filterToOne
|
import androidx.compose.ui.test.filterToOne
|
||||||
@@ -257,8 +258,8 @@ class SetupUnlockScreenTest : BaseComposeTest() {
|
|||||||
.assertIsDisplayed()
|
.assertIsDisplayed()
|
||||||
composeTestRule
|
composeTestRule
|
||||||
.onAllNodesWithText(
|
.onAllNodesWithText(
|
||||||
text = "Set your PIN code for unlocking Bitwarden. Your PIN settings will be reset if " +
|
text = "Your PIN must be at least 4 characters. Your PIN settings will be reset " +
|
||||||
"you ever fully log out of the application.",
|
"if you ever fully log out of the application.",
|
||||||
)
|
)
|
||||||
.filterToOne(hasAnyAncestor(isDialog()))
|
.filterToOne(hasAnyAncestor(isDialog()))
|
||||||
.assertIsDisplayed()
|
.assertIsDisplayed()
|
||||||
@@ -306,9 +307,8 @@ class SetupUnlockScreenTest : BaseComposeTest() {
|
|||||||
composeTestRule.assertNoDialogExists()
|
composeTestRule.assertNoDialogExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
|
||||||
@Test
|
@Test
|
||||||
fun `PIN input dialog Submit click with empty pin should clear the dialog and send UnlockWithPinToggle Disabled`() {
|
fun `PIN input dialog with empty pin should disable submit button`() {
|
||||||
mutableStateFlow.update {
|
mutableStateFlow.update {
|
||||||
it.copy(isUnlockWithPinEnabled = false)
|
it.copy(isUnlockWithPinEnabled = false)
|
||||||
}
|
}
|
||||||
@@ -320,14 +320,7 @@ class SetupUnlockScreenTest : BaseComposeTest() {
|
|||||||
composeTestRule
|
composeTestRule
|
||||||
.onAllNodesWithText(text = "Submit")
|
.onAllNodesWithText(text = "Submit")
|
||||||
.filterToOne(hasAnyAncestor(isDialog()))
|
.filterToOne(hasAnyAncestor(isDialog()))
|
||||||
.performClick()
|
.assertIsNotEnabled()
|
||||||
|
|
||||||
verify {
|
|
||||||
viewModel.trySendAction(
|
|
||||||
SetupUnlockAction.UnlockWithPinToggle(UnlockWithPinState.Disabled),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
composeTestRule.assertNoDialogExists()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.x8bit.bitwarden.ui.platform.feature.settings.accountsecurity
|
|||||||
import androidx.compose.ui.test.assert
|
import androidx.compose.ui.test.assert
|
||||||
import androidx.compose.ui.test.assertIsDisplayed
|
import androidx.compose.ui.test.assertIsDisplayed
|
||||||
import androidx.compose.ui.test.assertIsFocused
|
import androidx.compose.ui.test.assertIsFocused
|
||||||
|
import androidx.compose.ui.test.assertIsNotEnabled
|
||||||
import androidx.compose.ui.test.assertIsOff
|
import androidx.compose.ui.test.assertIsOff
|
||||||
import androidx.compose.ui.test.assertIsOn
|
import androidx.compose.ui.test.assertIsOn
|
||||||
import androidx.compose.ui.test.filterToOne
|
import androidx.compose.ui.test.filterToOne
|
||||||
@@ -352,8 +353,8 @@ class AccountSecurityScreenTest : BaseComposeTest() {
|
|||||||
.assertIsDisplayed()
|
.assertIsDisplayed()
|
||||||
composeTestRule
|
composeTestRule
|
||||||
.onAllNodesWithText(
|
.onAllNodesWithText(
|
||||||
"Set your PIN code for unlocking Bitwarden. Your PIN settings will be reset if " +
|
text = "Your PIN must be at least 4 characters. Your PIN settings will be reset " +
|
||||||
"you ever fully log out of the application.",
|
"if you ever fully log out of the application.",
|
||||||
)
|
)
|
||||||
.filterToOne(hasAnyAncestor(isDialog()))
|
.filterToOne(hasAnyAncestor(isDialog()))
|
||||||
.assertIsDisplayed()
|
.assertIsDisplayed()
|
||||||
@@ -402,9 +403,8 @@ class AccountSecurityScreenTest : BaseComposeTest() {
|
|||||||
composeTestRule.assertNoDialogExists()
|
composeTestRule.assertNoDialogExists()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
|
||||||
@Test
|
@Test
|
||||||
fun `PIN input dialog Submit click with empty pin should clear the dialog and send UnlockWithPinToggle Disabled`() {
|
fun `PIN input dialog with empty pin should disable the Submit button`() {
|
||||||
mutableStateFlow.update {
|
mutableStateFlow.update {
|
||||||
it.copy(isUnlockWithPinEnabled = false)
|
it.copy(isUnlockWithPinEnabled = false)
|
||||||
}
|
}
|
||||||
@@ -414,16 +414,9 @@ class AccountSecurityScreenTest : BaseComposeTest() {
|
|||||||
.performClick()
|
.performClick()
|
||||||
|
|
||||||
composeTestRule
|
composeTestRule
|
||||||
.onAllNodesWithText("Submit")
|
.onAllNodesWithText(text = "Submit")
|
||||||
.filterToOne(hasAnyAncestor(isDialog()))
|
.filterToOne(hasAnyAncestor(isDialog()))
|
||||||
.performClick()
|
.assertIsNotEnabled()
|
||||||
|
|
||||||
verify {
|
|
||||||
viewModel.trySendAction(
|
|
||||||
AccountSecurityAction.UnlockWithPinToggle(UnlockWithPinState.Disabled),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
composeTestRule.assertNoDialogExists()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
|
|||||||
Reference in New Issue
Block a user