Skip to content

Commit b4b4f75

Browse files
PM-8953: Require 4 digits for pin entry (#4914)
1 parent 22376bf commit b4b4f75

File tree

4 files changed

+15
-26
lines changed

4 files changed

+15
-26
lines changed

app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/PinInputDialog.kt

+3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ import com.x8bit.bitwarden.ui.platform.components.model.CardStyle
3838
import com.x8bit.bitwarden.ui.platform.components.util.maxDialogHeight
3939
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
4040

41+
private const val MINIMUM_PIN_LENGTH: Int = 4
42+
4143
/**
4244
* A dialog for setting a user's PIN.
4345
*
@@ -138,6 +140,7 @@ fun PinInputDialog(
138140

139141
BitwardenFilledButton(
140142
label = stringResource(id = R.string.submit),
143+
isEnabled = !isPinCreation || pin.length >= MINIMUM_PIN_LENGTH,
141144
onClick = { onSubmitClick(pin) },
142145
modifier = Modifier.testTag(tag = "AcceptAlertButton"),
143146
)

app/src/main/res/values/strings.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ Scanning will happen automatically.</string>
480480
<string name="unlock">Unlock</string>
481481
<string name="unlock_vault">Unlock vault</string>
482482
<string name="thirty_minutes">30 minutes</string>
483-
<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>
483+
<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>
484484
<string name="logged_in_as_on">Logged in as %1$s on %2$s.</string>
485485
<string name="vault_locked_master_password">Your vault is locked. Verify your master password to continue.</string>
486486
<string name="vault_locked_pin">Your vault is locked. Verify your PIN code to continue.</string>

app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/accountsetup/SetupUnlockScreenTest.kt

+5-12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.x8bit.bitwarden.ui.auth.feature.accountsetup
22

33
import androidx.compose.ui.test.assertIsDisplayed
44
import androidx.compose.ui.test.assertIsEnabled
5+
import androidx.compose.ui.test.assertIsNotEnabled
56
import androidx.compose.ui.test.assertIsOff
67
import androidx.compose.ui.test.assertIsOn
78
import androidx.compose.ui.test.filterToOne
@@ -257,8 +258,8 @@ class SetupUnlockScreenTest : BaseComposeTest() {
257258
.assertIsDisplayed()
258259
composeTestRule
259260
.onAllNodesWithText(
260-
text = "Set your PIN code for unlocking Bitwarden. Your PIN settings will be reset if " +
261-
"you ever fully log out of the application.",
261+
text = "Your PIN must be at least 4 characters. Your PIN settings will be reset " +
262+
"if you ever fully log out of the application.",
262263
)
263264
.filterToOne(hasAnyAncestor(isDialog()))
264265
.assertIsDisplayed()
@@ -306,9 +307,8 @@ class SetupUnlockScreenTest : BaseComposeTest() {
306307
composeTestRule.assertNoDialogExists()
307308
}
308309

309-
@Suppress("MaxLineLength")
310310
@Test
311-
fun `PIN input dialog Submit click with empty pin should clear the dialog and send UnlockWithPinToggle Disabled`() {
311+
fun `PIN input dialog with empty pin should disable submit button`() {
312312
mutableStateFlow.update {
313313
it.copy(isUnlockWithPinEnabled = false)
314314
}
@@ -320,14 +320,7 @@ class SetupUnlockScreenTest : BaseComposeTest() {
320320
composeTestRule
321321
.onAllNodesWithText(text = "Submit")
322322
.filterToOne(hasAnyAncestor(isDialog()))
323-
.performClick()
324-
325-
verify {
326-
viewModel.trySendAction(
327-
SetupUnlockAction.UnlockWithPinToggle(UnlockWithPinState.Disabled),
328-
)
329-
}
330-
composeTestRule.assertNoDialogExists()
323+
.assertIsNotEnabled()
331324
}
332325

333326
@Suppress("MaxLineLength")

app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityScreenTest.kt

+6-13
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.x8bit.bitwarden.ui.platform.feature.settings.accountsecurity
33
import androidx.compose.ui.test.assert
44
import androidx.compose.ui.test.assertIsDisplayed
55
import androidx.compose.ui.test.assertIsFocused
6+
import androidx.compose.ui.test.assertIsNotEnabled
67
import androidx.compose.ui.test.assertIsOff
78
import androidx.compose.ui.test.assertIsOn
89
import androidx.compose.ui.test.filterToOne
@@ -352,8 +353,8 @@ class AccountSecurityScreenTest : BaseComposeTest() {
352353
.assertIsDisplayed()
353354
composeTestRule
354355
.onAllNodesWithText(
355-
"Set your PIN code for unlocking Bitwarden. Your PIN settings will be reset if " +
356-
"you ever fully log out of the application.",
356+
text = "Your PIN must be at least 4 characters. Your PIN settings will be reset " +
357+
"if you ever fully log out of the application.",
357358
)
358359
.filterToOne(hasAnyAncestor(isDialog()))
359360
.assertIsDisplayed()
@@ -402,9 +403,8 @@ class AccountSecurityScreenTest : BaseComposeTest() {
402403
composeTestRule.assertNoDialogExists()
403404
}
404405

405-
@Suppress("MaxLineLength")
406406
@Test
407-
fun `PIN input dialog Submit click with empty pin should clear the dialog and send UnlockWithPinToggle Disabled`() {
407+
fun `PIN input dialog with empty pin should disable the Submit button`() {
408408
mutableStateFlow.update {
409409
it.copy(isUnlockWithPinEnabled = false)
410410
}
@@ -414,16 +414,9 @@ class AccountSecurityScreenTest : BaseComposeTest() {
414414
.performClick()
415415

416416
composeTestRule
417-
.onAllNodesWithText("Submit")
417+
.onAllNodesWithText(text = "Submit")
418418
.filterToOne(hasAnyAncestor(isDialog()))
419-
.performClick()
420-
421-
verify {
422-
viewModel.trySendAction(
423-
AccountSecurityAction.UnlockWithPinToggle(UnlockWithPinState.Disabled),
424-
)
425-
}
426-
composeTestRule.assertNoDialogExists()
419+
.assertIsNotEnabled()
427420
}
428421

429422
@Suppress("MaxLineLength")

0 commit comments

Comments
 (0)