diff --git a/packages/widget_toolkit_pin/CHANGELOG.md b/packages/widget_toolkit_pin/CHANGELOG.md index cb707fd9..c7cf495f 100644 --- a/packages/widget_toolkit_pin/CHANGELOG.md +++ b/packages/widget_toolkit_pin/CHANGELOG.md @@ -1,3 +1,13 @@ +## [0.3.0] +Fixes and improvements: +* Fixed a bug where biometrics authentication would not work if encryption was used +* Added biometrics authentication to the example application +* Added `autoPromptBiometric` parameter to `PinCodeKeyboard` to automatically authenticate with biometrics if available + +Breaking changes: +* Added `savePinCodeInSecureStorage` to `PinCodeService` for saving the pin code in secure storage +* Removed `isPinCodeInSecureStorage` method from `PinCodeService`. Now this flag is set automatically when the pin code is saved in secure storage and accessed through the `getPinCode` method + ## [0.2.2] * Fixed a bug where a newly input pin could get deleted if the user starts typing again immediately after an error shake animation starts diff --git a/packages/widget_toolkit_pin/README.md b/packages/widget_toolkit_pin/README.md index 881d8ad5..953a7baf 100644 --- a/packages/widget_toolkit_pin/README.md +++ b/packages/widget_toolkit_pin/README.md @@ -107,15 +107,7 @@ class AppPinCodeService implements PinCodeService { static const _isPinCodeInStorage = 'pinCode'; FlutterSecureStorage get flutterSecureStorage => const FlutterSecureStorage(); - - @override - Future isPinCodeInSecureStorage() async { - var isPinCodeInSecureStorage = - await flutterSecureStorage.read(key: _isPinCodeInStorage); - - return isPinCodeInSecureStorage != null; - } - + @override Future encryptPinCode(String pinCode) async { // App specific encryption @@ -192,7 +184,7 @@ mapBiometricMessageToString: (message) { Optionally you can provide `onError` to handle errors out of the package, or to show a notification, in practice this would only get called if the implementations of `BiometricsLocalDataSource.areBiometricsEnabled()`, -`BiometricsLocalDataSource.setBiometricsEnabled(enable)`,`PinCodeService.isPinCodeInSecureStorage()`, +`BiometricsLocalDataSource.setBiometricsEnabled(enable)`, `PinCodeService.encryptPinCode()`, `PinCodeService.getPinLength()`, `PinCodeService.verifyPinCode()`, `PinCodeService.getPinCode()`, throw. @@ -251,6 +243,12 @@ to the user when they are prompted to confirm that they want to enable biometri localizedReason: 'Activate the biometrics of your device', ``` +Optionally you can provide `autoPromptBiometric` and set it to true. In this case the biometrics authentication will +be triggered automatically when the keyboard is opened +```dart +autoPromptBiometric: true, +``` + ## Functional specifications When the widget is loaded for the first time on the bottom right of the page, there is no button. diff --git a/packages/widget_toolkit_pin/example/lib/main.dart b/packages/widget_toolkit_pin/example/lib/main.dart index 19205ac7..15b154dc 100644 --- a/packages/widget_toolkit_pin/example/lib/main.dart +++ b/packages/widget_toolkit_pin/example/lib/main.dart @@ -21,26 +21,28 @@ class MyApp extends StatelessWidget { theme: ThemeData.light().copyWith( colorScheme: ColorScheme.fromSwatch(), extensions: [ - PinCodeTheme.light(), + PinCodeTheme.light().copyWith( + pinCodeKeyTextColorPressed: Colors.lightBlue.withOpacity(0.5), + ), WidgetToolkitTheme.light(), ], ), darkTheme: ThemeData.dark().copyWith( colorScheme: ColorScheme.fromSwatch(), extensions: [ - PinCodeTheme.dark(), + PinCodeTheme.dark().copyWith( + pinCodeKeyTextColorPressed: Colors.blue[700], + ), WidgetToolkitTheme.dark(), ], ), - home: const MyHomePage(title: 'Widget Toolkit Pin Demo'), + home: const MyHomePage(), ); } } class MyHomePage extends StatelessWidget { - const MyHomePage({super.key, required this.title}); - - final String title; + const MyHomePage({super.key}); @override Widget build(BuildContext context) => MultiProvider( @@ -54,10 +56,6 @@ class MyHomePage extends StatelessWidget { ], child: Builder( builder: (context) => Scaffold( - appBar: AppBar( - title: Text(title), - ), - extendBodyBehindAppBar: true, body: SizedBox( height: MediaQuery.of(context).size.height, child: Column( @@ -92,11 +90,14 @@ class MyHomePage extends StatelessWidget { // or to show a notification, in practice this would only get called if the // implementations of [BiometricsLocalDataSource.areBiometricsEnabled()], // [BiometricsLocalDataSource.setBiometricsEnabled(enable)], - // [PinCodeService.isPinCodeInSecureStorage()], [PinCodeService.encryptPinCode()], + // [PinCodeService.encryptPinCode()], // [PinCodeService.getPinLength()], [PinCodeService.verifyPinCode()], // [PinCodeService.getPinCode()], throw. onError: (error, translatedError) => _onError(error, translatedError, context), + // Optionally you can provide [autoPromptBiometric] and set it to true. + // In this case the biometric authentication will be triggered automatically + autoPromptBiometric: false, ), ), ], @@ -155,19 +156,10 @@ class AppPinCodeService implements PinCodeService { /// This pin is intended to be stored in the secured storage for production /// applications - String? _pinCode; - - @override - Future isPinCodeInSecureStorage() async { - if (_pinCode == '1111') { - return Future.value(true); - } - return Future.value(false); - } + final String _pinCode = '1111'; @override Future encryptPinCode(String pinCode) async { - _pinCode = pinCode; return Future.value(pinCode); } @@ -176,6 +168,7 @@ class AppPinCodeService implements PinCodeService { @override Future verifyPinCode(String pinCode) async { + await Future.delayed(const Duration(seconds: 1)); if (pinCode != '1111') { throw WrongPinCodeException(pinCode); } @@ -185,11 +178,13 @@ class AppPinCodeService implements PinCodeService { @override Future getPinCode() async { - if (_pinCode == null) { - return Future.value(null); - } return Future.value(_pinCode); } + + @override + Future savePinCodeInSecureStorage(String pinCode) async { + return true; + } } /// You have to implement and provide a [BiometricsLocalDataSource], you can @@ -199,10 +194,10 @@ class ProfileLocalDataSource implements BiometricsLocalDataSource { /// This bool check is intended to be stored in the secured storage for production /// applications - bool? _areBiometricsEnabled; + bool _areBiometricsEnabled = true; @override - Future areBiometricsEnabled() async => _areBiometricsEnabled ?? false; + Future areBiometricsEnabled() async => _areBiometricsEnabled; @override Future setBiometricsEnabled(bool enable) async => diff --git a/packages/widget_toolkit_pin/example/pubspec.lock b/packages/widget_toolkit_pin/example/pubspec.lock index b634de33..e8fd8331 100644 --- a/packages/widget_toolkit_pin/example/pubspec.lock +++ b/packages/widget_toolkit_pin/example/pubspec.lock @@ -268,10 +268,10 @@ packages: dependency: transitive description: name: flutter_svg - sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2" + sha256: "936d9c1c010d3e234d1672574636f3352b4941ca3decaddd3cafaeb9ad49c471" url: "https://pub.dev" source: hosted - version: "2.0.10+1" + version: "2.0.15" flutter_test: dependency: "direct dev" description: flutter @@ -606,10 +606,10 @@ packages: dependency: transitive description: name: rx_bloc_list - sha256: "82584d12118a79edaaea05592c5f869010c32add858d663359a455c6af0596c1" + sha256: a23eea42a8ae172a87787c523ec8f9db834629fcd2c3a4c0c1a74cdbaa4606d8 url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "5.0.1" rxdart: dependency: transitive description: @@ -622,10 +622,10 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051" + sha256: "95f9997ca1fb9799d494d0cb2a780fd7be075818d59f00c43832ed112b158a82" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.3" shared_preferences_android: dependency: transitive description: @@ -851,10 +851,10 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3" + sha256: "27d5fefe86fb9aace4a9f8375b56b3c292b64d8c04510df230f849850d912cb7" url: "https://pub.dev" source: hosted - version: "1.1.11+1" + version: "1.1.15" vector_graphics_codec: dependency: transitive description: @@ -867,10 +867,10 @@ packages: dependency: transitive description: name: vector_graphics_compiler - sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81" + sha256: ab9ff38fc771e9ee1139320adbe3d18a60327370c218c60752068ebee4b49ab1 url: "https://pub.dev" source: hosted - version: "1.1.11+1" + version: "1.1.15" vector_math: dependency: transitive description: @@ -939,7 +939,7 @@ packages: path: ".." relative: true source: path - version: "0.2.1" + version: "0.3.0" xdg_directories: dependency: transitive description: diff --git a/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/blocs/pin_code_bloc.dart b/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/blocs/pin_code_bloc.dart index c6d9f11e..991bf445 100644 --- a/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/blocs/pin_code_bloc.dart +++ b/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/blocs/pin_code_bloc.dart @@ -49,28 +49,32 @@ class PinCodeBloc extends $PinCodeBloc { required this.biometricAuthenticationService, required this.pinCodeService, required this.localizedReason, + required this.autoPromptBiometric, }) { authenticated.connect().addTo(_compositeSubscription); + Rx.merge([ + _$addDigitEvent + .asyncMap((digit) async => ( + digit: digit, + allowedLength: await pinCodeService.getPinLength() + )) + .where((data) => _pinCode.value.length <= data.allowedLength) + .map((data) => _pinCode.value + data.digit), + _$deleteDigitEvent + .map((_) => _pinCode.value.substring(0, _pinCode.value.length - 1)), + ]).listen(_pinCode.add).addTo(_compositeSubscription); } final PinBiometricsService biometricAuthenticationService; final PinCodeService pinCodeService; final String localizedReason; + final bool autoPromptBiometric; final BehaviorSubject _pinCode = BehaviorSubject.seeded(''); @override - Stream _mapToDigitsCountState() => Rx.merge([ - _$addDigitEvent.switchMap((digit) => _addDigit(digit).asResultStream()), - _$deleteDigitEvent.switchMap( - (_) { - _pinCode.add(_pinCode.value.substring( - 0, _pinCode.value.isNotEmpty ? _pinCode.value.length - 1 : 0)); - return Stream.value(_pinCode.value.length); - }, - ).asResultStream(), - errorState.mapTo(0).asResultStream(), - ]).whereSuccess().startWith(0).share(); + Stream _mapToDigitsCountState() => + _pinCode.map((pinCode) => pinCode.length).share(); @override Stream _mapToPlaceholderDigitsCountState() => pinCodeService @@ -87,10 +91,20 @@ class PinCodeBloc extends $PinCodeBloc { @override ConnectableStream _mapToAuthenticatedState() => Rx.merge([ - _digitsCountState.switchMap((digitsCount) => - _checkPin(_pinCode.value, digitsCount).asResultStream()), + digitsCount + .switchMap((_) => pinCodeService.getPinLength().asStream()) + .where( + (storedPinLength) => storedPinLength == _pinCode.value.length) + .switchMap((digitsCount) => _checkPin(_pinCode.value) + .asResultStream() + .doOnData((result) => _pinCode.add(''))), _$biometricsButtonPressedEvent - .switchMap((_) => _authenticateWithBiometrics().asResultStream()), + .mapTo(true) + .startWith(autoPromptBiometric) + .where((shouldPrompt) => shouldPrompt) + .asyncMap((_) => _getAreBiometricsEnabled()) + .where((biometricsEnabled) => biometricsEnabled) + .switchMap((_) => _authenticateWithBiometrics().asResultStream()) ]).setResultStateHandler(this).whereSuccess().publish(); @override @@ -128,50 +142,25 @@ class PinCodeBloc extends $PinCodeBloc { pinCode != null; } - /// Adds a digit to the pin code, returning the new length of the pin code - Future _addDigit(String digit) async { - final pinLength = await pinCodeService.getPinLength(); - if (_pinCode.value.length < pinLength) { - _pinCode.add(_pinCode.value + digit); - } - return _pinCode.value.length; - } - - /// Encrypts and verifies the provided pin code - Future _encryptAndVerify(String pinCode) async { + // Checks the validity of the pin code + Future _checkPin(String pinCode) async { final encryptedPin = await pinCodeService.encryptPinCode(pinCode); - final verifiedPin = await pinCodeService.verifyPinCode(encryptedPin); - return verifiedPin; - } - - /// Checks the validity of the pin code - Future _checkPin(String pinCode, int digits) async { - final storedPinLength = await pinCodeService.getPinLength(); - if (storedPinLength != 0 && digits == storedPinLength) { - try { - final authValue = await _encryptAndVerify(pinCode); - final isSaved = await pinCodeService.isPinCodeInSecureStorage(); - if (isSaved) { - return authValue; - } - } catch (_) { - _pinCode.value = ''; - rethrow; - } - } - return false; + await pinCodeService.savePinCodeInSecureStorage(encryptedPin); + final verificationResult = await pinCodeService.verifyPinCode(encryptedPin); + return verificationResult; } /// Authenticates the user with biometrics after which the pin code is /// retrieved from the device and checked. - Future _authenticateWithBiometrics() async { + Future _authenticateWithBiometrics() async { if (!await biometricAuthenticationService.isDeviceSupported) { throw ErrorEnableBiometrics(BiometricsMessage.notSupported); } if (await biometricAuthenticationService.authenticate(localizedReason)) { final pinCode = await pinCodeService.getPinCode(); if (pinCode != null) { - return await _checkPin(pinCode, pinCode.length); + final verificationResult = await pinCodeService.verifyPinCode(pinCode); + return verificationResult; } } return false; diff --git a/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/di/pin_code_dependencies.dart b/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/di/pin_code_dependencies.dart index e6611b58..361edc73 100644 --- a/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/di/pin_code_dependencies.dart +++ b/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/di/pin_code_dependencies.dart @@ -14,6 +14,7 @@ class PinCodeDependencies { this.biometricsLocalDataSource, this.localizedReason, this.biometricsAuthDataSource, + this.autoPromptBiometric, ); factory PinCodeDependencies.from({ @@ -21,18 +22,21 @@ class PinCodeDependencies { required BiometricsLocalDataSource? biometricsLocalDataSource, required String localizedReason, PinBiometricsAuthDataSource? biometricsAuthDataSource, + bool autoPromptBiometric = false, }) => PinCodeDependencies._( pinCodeService, biometricsLocalDataSource, localizedReason, biometricsAuthDataSource, + autoPromptBiometric, ); final String localizedReason; final PinCodeService pinCodeService; final BiometricsLocalDataSource? biometricsLocalDataSource; final PinBiometricsAuthDataSource? biometricsAuthDataSource; + final bool autoPromptBiometric; late List providers = [ ..._localAuthentication, @@ -88,6 +92,7 @@ class PinCodeDependencies { biometricAuthenticationService: context.read(), pinCodeService: pinCodeService, localizedReason: localizedReason, + autoPromptBiometric: autoPromptBiometric, ), ), ]; diff --git a/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/services/pin_code_service.dart b/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/services/pin_code_service.dart index 2ae39d17..a84b5444 100644 --- a/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/services/pin_code_service.dart +++ b/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/services/pin_code_service.dart @@ -1,8 +1,4 @@ abstract class PinCodeService { - /// Reads from device internal storage and - /// returns the stored pin code to the bloc - Future isPinCodeInSecureStorage(); - /// Receives the encrypted pinCode from user input. /// Returns the value verified by the server Future verifyPinCode(String pinCode); @@ -11,11 +7,13 @@ abstract class PinCodeService { /// the length should be less than 10 digits Future getPinLength(); - /// Encrypts the string and stores it in the device secure storage. It has a - /// add a default implementation to return what is the input. Returns the - /// encrypted pinCode from the device secure storage. + /// Encrypts the provided pin code and returns the encrypted string. It has a + /// default implementation to return what is the input. Future encryptPinCode(String pinCode) => Future.value(pinCode); /// Returns the pin code or null if it is not saved in the device memory yet. Future getPinCode(); + + /// Stores the encrypted pin code in the device secure storage. + Future savePinCodeInSecureStorage(String pinCode); } diff --git a/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/ui_components/pin_code_component.dart b/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/ui_components/pin_code_component.dart index ec899dc0..b1e889cc 100644 --- a/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/ui_components/pin_code_component.dart +++ b/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/ui_components/pin_code_component.dart @@ -66,7 +66,6 @@ class _PinCodeComponentState extends State late AnimationController _controller; bool isShakeAnimation = false; bool hasErrorText = false; - bool authenticatedPin = false; static final _shakeTweenSequence = TweenSequence( >[ TweenSequenceItem( @@ -144,16 +143,11 @@ class _PinCodeComponentState extends State ), RxBlocListener( state: (bloc) => bloc.states.authenticated, - condition: (oldState, newState) => oldState != newState, listener: (context, authValue) { if (authValue == false) { return; } - setState(() { - authenticatedPin = true; - }); - widget.onAuthenticated?.call(authValue); }, ), @@ -411,9 +405,7 @@ class _PinCodeComponentState extends State number: index + number, isLoading: isLoading, onPressed: (key) { - if (!authenticatedPin) { - context.read().events.addDigit(key.toString()); - } + context.read().events.addDigit(key.toString()); }, ); diff --git a/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/ui_components/pin_code_keyboard.dart b/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/ui_components/pin_code_keyboard.dart index 7c93924c..07df5bb7 100644 --- a/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/ui_components/pin_code_keyboard.dart +++ b/packages/widget_toolkit_pin/lib/src/lib_pin_code_with_biometrics/ui_components/pin_code_keyboard.dart @@ -55,6 +55,7 @@ class PinCodeKeyboard extends StatelessWidget { this.localizedReason, this.addDependencies = true, this.onError, + this.autoPromptBiometric = false, super.key, }); @@ -105,6 +106,12 @@ class PinCodeKeyboard extends StatelessWidget { /// [onError] is optional function that enable error handling out of the package final Function(Object error, String translatedError)? onError; + /// If set to true the biometric authentication will be triggered automatically + /// when the widget is loaded, requires [biometricsLocalDataSource] to be provided + /// otherwise the biometric authentication will be disabled + /// Default to false + final bool autoPromptBiometric; + static const String _enterPinWithBiometrics = 'Enter your pin code by authenticating with biometrics'; @@ -137,6 +144,7 @@ class PinCodeKeyboard extends StatelessWidget { biometricsLocalDataSource: biometricsLocalDataSource, biometricsAuthDataSource: biometricsAuthDataSource, localizedReason: localizedReason ?? _enterPinWithBiometrics, + autoPromptBiometric: autoPromptBiometric, ).providers, ], child: child, diff --git a/packages/widget_toolkit_pin/pubspec.yaml b/packages/widget_toolkit_pin/pubspec.yaml index b8a7e708..b08b8347 100644 --- a/packages/widget_toolkit_pin/pubspec.yaml +++ b/packages/widget_toolkit_pin/pubspec.yaml @@ -1,7 +1,7 @@ name: widget_toolkit_pin description: This package provide out of the box entering PIN code functionality, which can be used with biometric authentication. -version: 0.2.2 +version: 0.3.0 homepage: https://primeholding.com/ environment: @@ -25,7 +25,7 @@ dependencies: widget_toolkit_biometrics: ^0.1.0 dev_dependencies: - build_runner: ^2.4.12 + build_runner: ^2.4.13 clean_coverage: ^0.0.3 flutter_lints: ^4.0.0 flutter_test: diff --git a/packages/widget_toolkit_pin/test/lib_pin_code/blocs/pin_code_test.dart b/packages/widget_toolkit_pin/test/lib_pin_code/blocs/pin_code_test.dart index 8260ccb6..4b6d3c8d 100644 --- a/packages/widget_toolkit_pin/test/lib_pin_code/blocs/pin_code_test.dart +++ b/packages/widget_toolkit_pin/test/lib_pin_code/blocs/pin_code_test.dart @@ -30,7 +30,6 @@ void main() { List? biometrics, String pinCode = '', bool isPinVerified = true, - bool isPinCodeInSecureStorage = true, bool enableBiometrics = true, BiometricsMessage biometricsMessage = BiometricsMessage.enabled, ErrorModel? biometricsError, @@ -62,9 +61,6 @@ void main() { when(pinCodeService.verifyPinCode(pinCode)) .thenAnswer((_) => Future.value(isPinVerified)); - when(pinCodeService.isPinCodeInSecureStorage()) - .thenAnswer((_) => Future.value(isPinCodeInSecureStorage)); - when(pinCodeService.encryptPinCode(pinCode)) .thenAnswer((_) => Future.value(pinCode)); @@ -77,6 +73,7 @@ void main() { biometricAuthenticationService: biometricAuthenticationService, localizedReason: '', pinCodeService: pinCodeService, + autoPromptBiometric: false, ); group('test pin_code_bloc_dart state digitsCount', () { @@ -92,21 +89,23 @@ void main() { state: (bloc) => bloc.states.digitsCount, expect: [6]); - rxBlocTest( + rxBlocFakeAsyncTest( 'test pin_code_bloc_dart state digitsCount with addDigit and deleteDigit event', - build: () async { + build: () { defineWhen(); return pinCodeBloc(); }, - act: (bloc) async { + act: (bloc, fakeAsync) async { bloc.events.addDigit('1'); + fakeAsync.elapse(const Duration(milliseconds: 1)); bloc.events.deleteDigit(); bloc.events.addDigit('2'); bloc.events.addDigit('1'); + fakeAsync.elapse(const Duration(milliseconds: 1)); bloc.events.deleteDigit(); }, state: (bloc) => bloc.states.digitsCount, - expect: [0, 0, 2]); + expect: [0, 1, 0, 1, 2, 1]); }); group('test pin_code_bloc_dart state authenticated', () { @@ -132,7 +131,6 @@ void main() { build: () async { defineWhen( isDeviceSupported: true, - isPinCodeInSecureStorage: true, isPinVerified: true, canCheckBiometrics: true, pinCode: Stubs.pinCode, @@ -154,7 +152,6 @@ void main() { pinCode: Stubs.pinCode, isPinVerified: true, enableBiometrics: true, - isPinCodeInSecureStorage: true, ); return pinCodeBloc(); @@ -171,7 +168,6 @@ void main() { defineWhen( pinCode: Stubs.pinCode2, isPinVerified: false, - isPinCodeInSecureStorage: false, areBiometricsEnabled: false, ); @@ -187,7 +183,6 @@ void main() { defineWhen( pinCode: Stubs.pinCode2, isPinVerified: false, - isPinCodeInSecureStorage: false, areBiometricsEnabled: false, biometricsError: Stubs.error, ); diff --git a/packages/widget_toolkit_pin/test/lib_pin_code/blocs/pin_code_test.mocks.dart b/packages/widget_toolkit_pin/test/lib_pin_code/blocs/pin_code_test.mocks.dart index 4968a124..130571be 100644 --- a/packages/widget_toolkit_pin/test/lib_pin_code/blocs/pin_code_test.mocks.dart +++ b/packages/widget_toolkit_pin/test/lib_pin_code/blocs/pin_code_test.mocks.dart @@ -146,15 +146,6 @@ class MockPinCodeService extends _i1.Mock implements _i7.PinCodeService { _i1.throwOnMissingStub(this); } - @override - _i4.Future isPinCodeInSecureStorage() => (super.noSuchMethod( - Invocation.method( - #isPinCodeInSecureStorage, - [], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - @override _i4.Future verifyPinCode(String? pinCode) => (super.noSuchMethod( Invocation.method( @@ -196,4 +187,14 @@ class MockPinCodeService extends _i1.Mock implements _i7.PinCodeService { ), returnValue: _i4.Future.value(), ) as _i4.Future); + + @override + _i4.Future savePinCodeInSecureStorage(String? pinCode) => + (super.noSuchMethod( + Invocation.method( + #savePinCodeInSecureStorage, + [pinCode], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); } diff --git a/packages/widget_toolkit_pin/test/mocks/pin_code_mock.dart b/packages/widget_toolkit_pin/test/mocks/pin_code_mock.dart index 7bc2e662..0c24107b 100644 --- a/packages/widget_toolkit_pin/test/mocks/pin_code_mock.dart +++ b/packages/widget_toolkit_pin/test/mocks/pin_code_mock.dart @@ -35,7 +35,7 @@ PinCodeBlocType pinCodeMockFactory({ when(statesMock.showBiometricsButton).thenAnswer( (_) { service.verifyPinCode(Stubs.pinCode3); - service.isPinCodeInSecureStorage(); + final state = showBiometricsButton != null ? Stream.value(showBiometricsButton) : Stream.value(false); @@ -65,8 +65,6 @@ PinCodeBlocType pinCodeMockFactory({ when(service.verifyPinCode(Stubs.pinCode3)).thenAnswer((_) async => true); - when(service.isPinCodeInSecureStorage()).thenAnswer((_) async => true); - when(service.encryptPinCode(Stubs.pinCode3)) .thenAnswer((_) async => Stubs.pinCode3);