From c690da7c3c2daab6f195790917a6960e52feade1 Mon Sep 17 00:00:00 2001 From: Elias Bonnici Date: Fri, 9 Feb 2024 09:23:36 +0100 Subject: [PATCH 1/3] Change FIDO `ActionListItem` subtitles and logic for actions notifier. --- lib/fido/views/fingerprints_screen.dart | 8 ++++---- lib/fido/views/key_actions.dart | 17 ++++++++++------- lib/fido/views/passkeys_screen.dart | 12 ++++++------ 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/lib/fido/views/fingerprints_screen.dart b/lib/fido/views/fingerprints_screen.dart index 30c6efaa..73b3afb0 100644 --- a/lib/fido/views/fingerprints_screen.dart +++ b/lib/fido/views/fingerprints_screen.dart @@ -110,7 +110,7 @@ class _FidoLockedPage extends ConsumerWidget { header: l10n.s_fingerprints_get_started, message: l10n.p_set_fingerprints_desc, keyActionsBuilder: hasActions ? _buildActions : null, - keyActionsBadge: fidoShowActionsNotifier(state), + keyActionsBadge: fingerprintsShowActionsNotifier(state), ); } @@ -121,7 +121,7 @@ class _FidoLockedPage extends ConsumerWidget { header: l10n.s_pin_change_required, message: l10n.l_pin_change_required_desc, keyActionsBuilder: hasActions ? _buildActions : null, - keyActionsBadge: fidoShowActionsNotifier(state), + keyActionsBadge: fingerprintsShowActionsNotifier(state), actionsBuilder: (context, expanded) => [ if (!expanded) ActionChip( @@ -201,7 +201,7 @@ class _FidoUnlockedPageState extends ConsumerState<_FidoUnlockedPage> { ? (context) => fingerprintsBuildActions(context, widget.node, widget.state, 0) : null, - keyActionsBadge: fidoShowActionsNotifier(widget.state), + keyActionsBadge: fingerprintsShowActionsNotifier(widget.state), ); } @@ -296,7 +296,7 @@ class _FidoUnlockedPageState extends ConsumerState<_FidoUnlockedPage> { ? (context) => fingerprintsBuildActions( context, widget.node, widget.state, fingerprints.length) : null, - keyActionsBadge: fidoShowActionsNotifier(widget.state), + keyActionsBadge: fingerprintsShowActionsNotifier(widget.state), builder: (context, expanded) { // De-select if window is resized to be non-expanded. if (!expanded && _selected != null) { diff --git a/lib/fido/views/key_actions.dart b/lib/fido/views/key_actions.dart index 409dc172..ee711f80 100755 --- a/lib/fido/views/key_actions.dart +++ b/lib/fido/views/key_actions.dart @@ -26,10 +26,12 @@ import '../models.dart'; import 'add_fingerprint_dialog.dart'; import 'pin_dialog.dart'; -bool fidoShowActionsNotifier(FidoState state) { - return (state.alwaysUv && !state.hasPin) || - state.bioEnroll == false || - state.forcePinChange; +bool passkeysShowActionsNotifier(FidoState state) { + return (state.alwaysUv && !state.hasPin) || state.forcePinChange; +} + +bool fingerprintsShowActionsNotifier(FidoState state) { + return !state.hasPin || state.bioEnroll == false || state.forcePinChange; } Widget passkeysBuildActions( @@ -63,8 +65,9 @@ Widget _fidoBuildActions(BuildContext context, DeviceNode node, FidoState state, : state.hasPin ? l10n.l_unlock_pin_first : l10n.l_set_pin_first, - trailing: fingerprints == 0 - ? Icon(Icons.warning_amber, color: colors.tertiary) + trailing: fingerprints == 0 || fingerprints == -1 + ? Icon(Icons.warning_amber, + color: state.unlocked ? colors.tertiary : null) : null, onTap: state.unlocked && fingerprints < 5 ? (context) { @@ -90,7 +93,7 @@ Widget _fidoBuildActions(BuildContext context, DeviceNode node, FidoState state, ? (state.forcePinChange ? l10n.s_pin_change_required : l10n.s_fido_pin_protection) - : l10n.l_fido_pin_protection_optional, + : l10n.s_fido_pin_protection, trailing: state.alwaysUv && !state.hasPin || state.forcePinChange ? Icon(Icons.warning_amber, color: colors.tertiary) : null, diff --git a/lib/fido/views/passkeys_screen.dart b/lib/fido/views/passkeys_screen.dart index 9fe405d9..dc719939 100644 --- a/lib/fido/views/passkeys_screen.dart +++ b/lib/fido/views/passkeys_screen.dart @@ -132,7 +132,7 @@ class _FidoLockedPage extends ConsumerWidget { : l10n.l_register_sk_on_websites, footnote: isBio ? null : l10n.l_non_passkeys_note, keyActionsBuilder: hasActions ? _buildActions : null, - keyActionsBadge: fidoShowActionsNotifier(state), + keyActionsBadge: passkeysShowActionsNotifier(state), ); } @@ -144,7 +144,7 @@ class _FidoLockedPage extends ConsumerWidget { message: l10n.l_register_sk_on_websites, footnote: l10n.l_non_passkeys_note, keyActionsBuilder: hasActions ? _buildActions : null, - keyActionsBadge: fidoShowActionsNotifier(state), + keyActionsBadge: passkeysShowActionsNotifier(state), ); } @@ -167,7 +167,7 @@ class _FidoLockedPage extends ConsumerWidget { header: l10n.s_pin_change_required, message: l10n.l_pin_change_required_desc, keyActionsBuilder: hasActions ? _buildActions : null, - keyActionsBadge: fidoShowActionsNotifier(state), + keyActionsBadge: passkeysShowActionsNotifier(state), ); } @@ -220,7 +220,7 @@ class _FidoUnlockedPageState extends ConsumerState<_FidoUnlockedPage> { ? (context) => passkeysBuildActions(context, widget.node, widget.state) : null, - keyActionsBadge: fidoShowActionsNotifier(widget.state), + keyActionsBadge: passkeysShowActionsNotifier(widget.state), ); } @@ -257,7 +257,7 @@ class _FidoUnlockedPageState extends ConsumerState<_FidoUnlockedPage> { ? (context) => passkeysBuildActions(context, widget.node, widget.state) : null, - keyActionsBadge: fidoShowActionsNotifier(widget.state), + keyActionsBadge: passkeysShowActionsNotifier(widget.state), footnote: l10n.l_non_passkeys_note, ); } @@ -358,7 +358,7 @@ class _FidoUnlockedPageState extends ConsumerState<_FidoUnlockedPage> { ? (context) => passkeysBuildActions(context, widget.node, widget.state) : null, - keyActionsBadge: fidoShowActionsNotifier(widget.state), + keyActionsBadge: passkeysShowActionsNotifier(widget.state), builder: (context, expanded) { // De-select if window is resized to be non-expanded. if (!expanded && _selected != null) { From 4e43ed81ee7a02c02f3a0d9b28b9d88c46ea4cf6 Mon Sep 17 00:00:00 2001 From: Elias Bonnici Date: Fri, 9 Feb 2024 10:03:49 +0100 Subject: [PATCH 2/3] Add warning when using default PIN and PUK in PIV. --- lib/l10n/app_de.arb | 2 ++ lib/l10n/app_en.arb | 2 ++ lib/l10n/app_fr.arb | 2 ++ lib/l10n/app_ja.arb | 2 ++ lib/l10n/app_pl.arb | 2 ++ lib/piv/views/key_actions.dart | 27 ++++++++++++++++++++++----- lib/piv/views/piv_screen.dart | 1 + 7 files changed, 33 insertions(+), 5 deletions(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 08425f47..3f4f59ab 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -310,6 +310,8 @@ "s_generate_random": null, "s_use_default": null, "l_warning_default_key": null, + "l_warning_default_pin": null, + "l_warning_default_puk": null, "s_protect_key": null, "l_pin_protected_key": null, "l_wrong_key": null, diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index a3b27234..45ef867c 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -310,6 +310,8 @@ "s_generate_random": "Generate random", "s_use_default": "Use default", "l_warning_default_key": "Warning: Default key used", + "l_warning_default_pin": "Warning: Default PIN used", + "l_warning_default_puk": "Warning: Default PUK used", "s_protect_key": "Protect with PIN", "l_pin_protected_key": "PIN can be used instead", "l_wrong_key": "Wrong key", diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 018f37cf..00fbd1f1 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -310,6 +310,8 @@ "s_generate_random": "Génération aléatoire", "s_use_default": "Utiliser la valeur par défaut", "l_warning_default_key": "Attention: Clé par défaut utilisée", + "l_warning_default_pin": null, + "l_warning_default_puk": null, "s_protect_key": "Protection par PIN", "l_pin_protected_key": "Un PIN peut être utilisé à la place", "l_wrong_key": "Mauvaise clé", diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb index c47a18d7..d1f1fbdd 100644 --- a/lib/l10n/app_ja.arb +++ b/lib/l10n/app_ja.arb @@ -310,6 +310,8 @@ "s_generate_random": "ランダムに生成する", "s_use_default": "デフォルトの使用", "l_warning_default_key": "警告: デフォルトのキーが使用されています", + "l_warning_default_pin": null, + "l_warning_default_puk": null, "s_protect_key": "PINで保護する", "l_pin_protected_key": "代わりにPINを使用できます", "l_wrong_key": "間違ったキー", diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index 964eb69a..da4be217 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -310,6 +310,8 @@ "s_generate_random": "Generuj losowo", "s_use_default": "Użyj domyślnego", "l_warning_default_key": "Uwaga: Używany jest klucz domyślny", + "l_warning_default_pin": null, + "l_warning_default_puk": null, "s_protect_key": "Zabezpiecz kodem PIN", "l_pin_protected_key": "Zamiast tego można użyć kodu PIN", "l_wrong_key": "Błędny klucz", diff --git a/lib/piv/views/key_actions.dart b/lib/piv/views/key_actions.dart index cdf57d1e..5f31322c 100644 --- a/lib/piv/views/key_actions.dart +++ b/lib/piv/views/key_actions.dart @@ -27,12 +27,23 @@ import '../models.dart'; import 'manage_key_dialog.dart'; import 'manage_pin_puk_dialog.dart'; +bool pivShowActionsNotifier(PivState state) { + final usingDefaultPin = state.metadata?.pinMetadata.defaultValue == true; + final usingDefaultPuk = state.metadata?.pukMetadata.defaultValue == true; + final usingDefaultMgmtKey = + state.metadata?.managementKeyMetadata.defaultValue == true; + + return usingDefaultPin || usingDefaultPuk || usingDefaultMgmtKey; +} + Widget pivBuildActions(BuildContext context, DevicePath devicePath, PivState pivState, WidgetRef ref) { final colors = Theme.of(context).buttonTheme.colorScheme ?? Theme.of(context).colorScheme; final l10n = AppLocalizations.of(context)!; + final usingDefaultPin = pivState.metadata?.pinMetadata.defaultValue == true; + final usingDefaultPuk = pivState.metadata?.pukMetadata.defaultValue == true; final usingDefaultMgmtKey = pivState.metadata?.managementKeyMetadata.defaultValue == true; @@ -53,9 +64,11 @@ Widget pivBuildActions(BuildContext context, DevicePath devicePath, ? (pukAttempts != 0 ? l10n.l_piv_pin_blocked : l10n.l_piv_pin_puk_blocked) - : l10n.l_attempts_remaining(pivState.pinAttempts), + : usingDefaultPin + ? '${l10n.l_attempts_remaining(pivState.pinAttempts)}\n${l10n.l_warning_default_pin}' + : l10n.l_attempts_remaining(pivState.pinAttempts), icon: const Icon(Icons.pin_outlined), - trailing: pinBlocked ? alertIcon : null, + trailing: pinBlocked || usingDefaultPin ? alertIcon : null, onTap: !(pinBlocked && pukAttempts == 0) ? (context) { Navigator.of(context).popUntil((route) => route.isFirst); @@ -77,10 +90,14 @@ Widget pivBuildActions(BuildContext context, DevicePath devicePath, subtitle: pukAttempts != null ? (pukAttempts == 0 ? l10n.l_piv_pin_puk_blocked - : l10n.l_attempts_remaining(pukAttempts)) - : null, + : usingDefaultPuk + ? '${l10n.l_attempts_remaining(pukAttempts)}\n${l10n.l_warning_default_puk}' + : l10n.l_attempts_remaining(pukAttempts)) + : usingDefaultPuk + ? l10n.l_warning_default_puk + : null, icon: const Icon(Icons.pin_outlined), - trailing: pukAttempts == 0 ? alertIcon : null, + trailing: pukAttempts == 0 || usingDefaultPuk ? alertIcon : null, onTap: pukAttempts != 0 ? (context) { Navigator.of(context).popUntil((route) => route.isFirst); diff --git a/lib/piv/views/piv_screen.dart b/lib/piv/views/piv_screen.dart index 64a4d860..e6864203 100644 --- a/lib/piv/views/piv_screen.dart +++ b/lib/piv/views/piv_screen.dart @@ -158,6 +158,7 @@ class _PivScreenState extends ConsumerState { ? (context) => pivBuildActions( context, widget.devicePath, pivState, ref) : null, + keyActionsBadge: pivShowActionsNotifier(pivState), builder: (context, expanded) { // De-select if window is resized to be non-expanded. if (!expanded && _selected != null) { From 19404b5ce08f0ef43a3ae4e2c95f49319deb4462 Mon Sep 17 00:00:00 2001 From: Elias Bonnici Date: Fri, 9 Feb 2024 11:04:54 +0100 Subject: [PATCH 3/3] Show default PIN/PUK in `ManagePinPukDialog`. --- lib/l10n/app_de.arb | 6 ++- lib/l10n/app_en.arb | 6 ++- lib/l10n/app_fr.arb | 6 ++- lib/l10n/app_ja.arb | 6 ++- lib/l10n/app_pl.arb | 6 ++- lib/piv/models.dart | 2 + lib/piv/views/key_actions.dart | 4 +- lib/piv/views/manage_pin_puk_dialog.dart | 64 ++++++++++++++++++++---- 8 files changed, 78 insertions(+), 22 deletions(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 3f4f59ab..f190078e 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -274,6 +274,10 @@ "name": {} } }, + "l_warning_default_pin": null, + "l_warning_default_puk": null, + "l_default_pin_used": null, + "l_default_puk_used": null, "@_passwords": {}, "s_password": "Passwort", @@ -310,8 +314,6 @@ "s_generate_random": null, "s_use_default": null, "l_warning_default_key": null, - "l_warning_default_pin": null, - "l_warning_default_puk": null, "s_protect_key": null, "l_pin_protected_key": null, "l_wrong_key": null, diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 45ef867c..137bf4e7 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -274,6 +274,10 @@ "name": {} } }, + "l_warning_default_pin": "Warning: Default PIN used", + "l_warning_default_puk": "Warning: Default PUK used", + "l_default_pin_used": "Default PIN used", + "l_default_puk_used": "Default PUK used", "@_passwords": {}, "s_password": "Password", @@ -310,8 +314,6 @@ "s_generate_random": "Generate random", "s_use_default": "Use default", "l_warning_default_key": "Warning: Default key used", - "l_warning_default_pin": "Warning: Default PIN used", - "l_warning_default_puk": "Warning: Default PUK used", "s_protect_key": "Protect with PIN", "l_pin_protected_key": "PIN can be used instead", "l_wrong_key": "Wrong key", diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 00fbd1f1..5867c718 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -274,6 +274,10 @@ "name": {} } }, + "l_warning_default_pin": null, + "l_warning_default_puk": null, + "l_default_pin_used": null, + "l_default_puk_used": null, "@_passwords": {}, "s_password": "Mot de passe", @@ -310,8 +314,6 @@ "s_generate_random": "Génération aléatoire", "s_use_default": "Utiliser la valeur par défaut", "l_warning_default_key": "Attention: Clé par défaut utilisée", - "l_warning_default_pin": null, - "l_warning_default_puk": null, "s_protect_key": "Protection par PIN", "l_pin_protected_key": "Un PIN peut être utilisé à la place", "l_wrong_key": "Mauvaise clé", diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb index d1f1fbdd..d61b7553 100644 --- a/lib/l10n/app_ja.arb +++ b/lib/l10n/app_ja.arb @@ -274,6 +274,10 @@ "name": {} } }, + "l_warning_default_pin": null, + "l_warning_default_puk": null, + "l_default_pin_used": null, + "l_default_puk_used": null, "@_passwords": {}, "s_password": "パスワード", @@ -310,8 +314,6 @@ "s_generate_random": "ランダムに生成する", "s_use_default": "デフォルトの使用", "l_warning_default_key": "警告: デフォルトのキーが使用されています", - "l_warning_default_pin": null, - "l_warning_default_puk": null, "s_protect_key": "PINで保護する", "l_pin_protected_key": "代わりにPINを使用できます", "l_wrong_key": "間違ったキー", diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index da4be217..1138926d 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -274,6 +274,10 @@ "name": {} } }, + "l_warning_default_pin": null, + "l_warning_default_puk": null, + "l_default_pin_used": null, + "l_default_puk_used": null, "@_passwords": {}, "s_password": "Hasło", @@ -310,8 +314,6 @@ "s_generate_random": "Generuj losowo", "s_use_default": "Użyj domyślnego", "l_warning_default_key": "Uwaga: Używany jest klucz domyślny", - "l_warning_default_pin": null, - "l_warning_default_puk": null, "s_protect_key": "Zabezpiecz kodem PIN", "l_pin_protected_key": "Zamiast tego można użyć kodu PIN", "l_wrong_key": "Błędny klucz", diff --git a/lib/piv/models.dart b/lib/piv/models.dart index 6071b686..5076e3bd 100644 --- a/lib/piv/models.dart +++ b/lib/piv/models.dart @@ -26,6 +26,8 @@ const defaultManagementKey = '010203040506070801020304050607080102030405060708'; const defaultManagementKeyType = ManagementKeyType.tdes; const defaultKeyType = KeyType.eccp256; const defaultGenerateType = GenerateType.certificate; +const defaultPin = '123456'; +const defaultPuk = '12345678'; enum GenerateType { publicKey, diff --git a/lib/piv/views/key_actions.dart b/lib/piv/views/key_actions.dart index 5f31322c..3cdb1475 100644 --- a/lib/piv/views/key_actions.dart +++ b/lib/piv/views/key_actions.dart @@ -76,6 +76,7 @@ Widget pivBuildActions(BuildContext context, DevicePath devicePath, context: context, builder: (context) => ManagePinPukDialog( devicePath, + pivState, target: pinBlocked ? ManageTarget.unblock : ManageTarget.pin, @@ -103,7 +104,8 @@ Widget pivBuildActions(BuildContext context, DevicePath devicePath, Navigator.of(context).popUntil((route) => route.isFirst); showBlurDialog( context: context, - builder: (context) => ManagePinPukDialog(devicePath, + builder: (context) => ManagePinPukDialog( + devicePath, pivState, target: ManageTarget.puk), ); } diff --git a/lib/piv/views/manage_pin_puk_dialog.dart b/lib/piv/views/manage_pin_puk_dialog.dart index d25571ad..a289de1d 100644 --- a/lib/piv/views/manage_pin_puk_dialog.dart +++ b/lib/piv/views/manage_pin_puk_dialog.dart @@ -24,14 +24,16 @@ import '../../widgets/app_input_decoration.dart'; import '../../widgets/app_text_field.dart'; import '../../widgets/responsive_dialog.dart'; import '../keys.dart' as keys; +import '../models.dart'; import '../state.dart'; enum ManageTarget { pin, puk, unblock } class ManagePinPukDialog extends ConsumerStatefulWidget { final DevicePath path; + final PivState pivState; final ManageTarget target; - const ManagePinPukDialog(this.path, + const ManagePinPukDialog(this.path, this.pivState, {super.key, this.target = ManageTarget.pin}); @override @@ -40,7 +42,7 @@ class ManagePinPukDialog extends ConsumerStatefulWidget { } class _ManagePinPukDialogState extends ConsumerState { - String _currentPin = ''; + final _currentPinController = TextEditingController(); String _newPin = ''; String _confirmPin = ''; bool _currentIsWrong = false; @@ -48,13 +50,40 @@ class _ManagePinPukDialogState extends ConsumerState { bool _isObscureCurrent = true; bool _isObscureNew = true; bool _isObscureConfirm = true; + late bool _defaultPinUsed; + late bool _defaultPukUsed; + + @override + void initState() { + super.initState(); + + _defaultPinUsed = + widget.pivState.metadata?.pinMetadata.defaultValue ?? false; + _defaultPukUsed = + widget.pivState.metadata?.pukMetadata.defaultValue ?? false; + if (widget.target == ManageTarget.pin && _defaultPinUsed) { + _currentPinController.text = defaultPin; + } + if (widget.target != ManageTarget.pin && _defaultPukUsed) { + _currentPinController.text = defaultPuk; + } + } + + @override + void dispose() { + _currentPinController.dispose(); + super.dispose(); + } _submit() async { final notifier = ref.read(pivStateProvider(widget.path).notifier); final result = await switch (widget.target) { - ManageTarget.pin => notifier.changePin(_currentPin, _newPin), - ManageTarget.puk => notifier.changePuk(_currentPin, _newPin), - ManageTarget.unblock => notifier.unblockPin(_currentPin, _newPin), + ManageTarget.pin => + notifier.changePin(_currentPinController.text, _newPin), + ManageTarget.puk => + notifier.changePuk(_currentPinController.text, _newPin), + ManageTarget.unblock => + notifier.unblockPin(_currentPinController.text, _newPin), }; result.when(success: () { @@ -71,16 +100,17 @@ class _ManagePinPukDialogState extends ConsumerState { setState(() { _attemptsRemaining = attemptsRemaining; _currentIsWrong = true; - _currentPin = ''; }); + _currentPinController.clear(); }); } @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; + final currentPin = _currentPinController.text; final isValid = - _newPin.isNotEmpty && _newPin == _confirmPin && _currentPin.isNotEmpty; + _newPin.isNotEmpty && _newPin == _confirmPin && currentPin.isNotEmpty; final titleText = switch (widget.target) { ManageTarget.pin => l10n.s_change_pin, @@ -88,6 +118,11 @@ class _ManagePinPukDialogState extends ConsumerState { ManageTarget.unblock => l10n.s_unblock_pin, }; + final showDefaultPinUsed = + widget.target == ManageTarget.pin && _defaultPinUsed; + final showDefaultPukUsed = + widget.target != ManageTarget.pin && _defaultPukUsed; + return ResponsiveDialog( title: Text(titleText), actions: [ @@ -107,13 +142,20 @@ class _ManagePinPukDialogState extends ConsumerState { ? l10n.p_enter_current_pin_or_reset : l10n.p_enter_current_puk_or_reset), AppTextField( - autofocus: true, + autofocus: !(showDefaultPinUsed || showDefaultPukUsed), obscureText: _isObscureCurrent, maxLength: 8, autofillHints: const [AutofillHints.password], key: keys.pinPukField, + readOnly: showDefaultPinUsed || showDefaultPukUsed, + controller: _currentPinController, decoration: AppInputDecoration( border: const OutlineInputBorder(), + helperText: showDefaultPinUsed + ? l10n.l_default_pin_used + : showDefaultPukUsed + ? l10n.l_default_puk_used + : null, labelText: widget.target == ManageTarget.pin ? l10n.s_current_pin : l10n.s_current_puk, @@ -144,7 +186,6 @@ class _ManagePinPukDialogState extends ConsumerState { onChanged: (value) { setState(() { _currentIsWrong = false; - _currentPin = value; }); }, ), @@ -152,6 +193,7 @@ class _ManagePinPukDialogState extends ConsumerState { widget.target == ManageTarget.puk ? l10n.s_puk : l10n.s_pin)), AppTextField( key: keys.newPinPukField, + autofocus: showDefaultPinUsed || showDefaultPukUsed, obscureText: _isObscureNew, maxLength: 8, autofillHints: const [AutofillHints.newPassword], @@ -174,7 +216,7 @@ class _ManagePinPukDialogState extends ConsumerState { : (_isObscureNew ? l10n.s_show_puk : l10n.s_hide_puk), ), // Old YubiKeys allowed a 4 digit PIN - enabled: _currentPin.length >= 4, + enabled: currentPin.length >= 4, ), textInputAction: TextInputAction.next, onChanged: (value) { @@ -212,7 +254,7 @@ class _ManagePinPukDialogState extends ConsumerState { ? (_isObscureConfirm ? l10n.s_show_pin : l10n.s_hide_pin) : (_isObscureConfirm ? l10n.s_show_puk : l10n.s_hide_puk), ), - enabled: _currentPin.length >= 4 && _newPin.length >= 6, + enabled: currentPin.length >= 4 && _newPin.length >= 6, ), textInputAction: TextInputAction.done, onChanged: (value) {