diff --git a/lib/ui/account/other_operations/change_name/changing_name_sheet.dart b/lib/ui/account/other_operations/change_name/changing_name_sheet.dart index 6e2c02a..d9fade1 100644 --- a/lib/ui/account/other_operations/change_name/changing_name_sheet.dart +++ b/lib/ui/account/other_operations/change_name/changing_name_sheet.dart @@ -381,20 +381,16 @@ class _ChangingNameSheetState extends State { } } - Future authenticate() async { - String message = AppLocalization.of(context) - .authenticateToChangeNameParagraph - .replaceAll("%1", widget.newName.toString()); - // Authenticate - AuthUtil authUtil = AuthUtil(); - if (await authUtil.useBiometrics()) { - // Biometric auth - bool authenticated = await authUtil.authenticateWithBiometrics(message); - if (authenticated) { - HapticUtil.fingerprintSucess(); - } - return authenticated; - } else { + Future _authenticateBiometrics(AuthUtil authUtil, String message) async { + // Biometric auth + bool authenticated = await authUtil.authenticateWithBiometrics(message); + if (authenticated) { + HapticUtil.fingerprintSucess(); + } + return authenticated; + } + + Future _authenticatePin(String message) async { String expectedPin = await sl.get().getPin(); bool result = await Navigator.of(context) .push(MaterialPageRoute(builder: (BuildContext context) { @@ -408,7 +404,24 @@ class _ChangingNameSheetState extends State { ); })); await Future.delayed(Duration(milliseconds: 200)); - return result != null && result; + return result != null && result; + } + + Future authenticate() async { + String message = AppLocalization.of(context) + .authenticateToChangeNameParagraph + .replaceAll("%1", widget.newName.toString()); + // Authenticate + AuthUtil authUtil = AuthUtil(); + if (await authUtil.useBiometrics()) { + // Biometric auth + try { + return await _authenticateBiometrics(authUtil, message); + } catch (e) { + return await _authenticatePin(message); + } + } else { + return await _authenticatePin(message); } } } diff --git a/lib/ui/account/other_operations/delist_for_sale/delisting_for_sale.dart b/lib/ui/account/other_operations/delist_for_sale/delisting_for_sale.dart index 94c3daf..a0bf62f 100644 --- a/lib/ui/account/other_operations/delist_for_sale/delisting_for_sale.dart +++ b/lib/ui/account/other_operations/delist_for_sale/delisting_for_sale.dart @@ -377,18 +377,16 @@ class _DelistingForSaleSheetState extends State { } } - Future authenticate() async { - String message = "Authenticate to delist account for sale"; - // Authenticate - AuthUtil authUtil = AuthUtil(); - if (await authUtil.useBiometrics()) { - // Biometric auth - bool authenticated = await authUtil.authenticateWithBiometrics(message); - if (authenticated) { - HapticUtil.fingerprintSucess(); - } - return authenticated; - } else { + Future _authenticateBiometrics(AuthUtil authUtil, String message) async { + // Biometric auth + bool authenticated = await authUtil.authenticateWithBiometrics(message); + if (authenticated) { + HapticUtil.fingerprintSucess(); + } + return authenticated; + } + + Future _authenticatePin(String message) async { String expectedPin = await sl.get().getPin(); bool result = await Navigator.of(context) .push(MaterialPageRoute(builder: (BuildContext context) { @@ -402,7 +400,22 @@ class _DelistingForSaleSheetState extends State { ); })); await Future.delayed(Duration(milliseconds: 200)); - return result != null && result; + return result != null && result; + } + + Future authenticate() async { + String message = AppLocalization.of(context).authenticateToDelistParagraph; + // Authenticate + AuthUtil authUtil = AuthUtil(); + if (await authUtil.useBiometrics()) { + // Biometric auth + try { + return await _authenticateBiometrics(authUtil, message); + } catch (e) { + return await _authenticatePin(message); + } + } else { + return await _authenticatePin(message); } } } diff --git a/lib/ui/account/other_operations/list_for_sale/listing_for_sale_sheet.dart b/lib/ui/account/other_operations/list_for_sale/listing_for_sale_sheet.dart index db5bcc2..20bd76c 100644 --- a/lib/ui/account/other_operations/list_for_sale/listing_for_sale_sheet.dart +++ b/lib/ui/account/other_operations/list_for_sale/listing_for_sale_sheet.dart @@ -486,18 +486,16 @@ class _ListingForSaleSheetState extends State { } } - Future authenticate() async { - String message = AppLocalization.of(context).authenticateToListForSaleParagraph; - // Authenticate - AuthUtil authUtil = AuthUtil(); - if (await authUtil.useBiometrics()) { - // Biometric auth - bool authenticated = await authUtil.authenticateWithBiometrics(message); - if (authenticated) { - HapticUtil.fingerprintSucess(); - } - return authenticated; - } else { + Future _authenticateBiometrics(AuthUtil authUtil, String message) async { + // Biometric auth + bool authenticated = await authUtil.authenticateWithBiometrics(message); + if (authenticated) { + HapticUtil.fingerprintSucess(); + } + return authenticated; + } + + Future _authenticatePin(String message) async { String expectedPin = await sl.get().getPin(); bool result = await Navigator.of(context) .push(MaterialPageRoute(builder: (BuildContext context) { @@ -511,7 +509,22 @@ class _ListingForSaleSheetState extends State { ); })); await Future.delayed(Duration(milliseconds: 200)); - return result != null && result; + return result != null && result; + } + + Future authenticate() async { + String message = AppLocalization.of(context).authenticateToListForSaleParagraph; + // Authenticate + AuthUtil authUtil = AuthUtil(); + if (await authUtil.useBiometrics()) { + // Biometric auth + try { + return await _authenticateBiometrics(authUtil, message); + } catch (e) { + return await _authenticatePin(message); + } + } else { + return await _authenticatePin(message); } } } diff --git a/lib/ui/account/other_operations/private_sale/creating_private_sale_sheet.dart b/lib/ui/account/other_operations/private_sale/creating_private_sale_sheet.dart index 29ebbd0..407f6ea 100644 --- a/lib/ui/account/other_operations/private_sale/creating_private_sale_sheet.dart +++ b/lib/ui/account/other_operations/private_sale/creating_private_sale_sheet.dart @@ -541,19 +541,16 @@ class _CreatingPrivateSaleSheetState extends State { } } - Future authenticate() async { - String message = - AppLocalization.of(context).authenticateToCreatePrivateSaleParagraph; - // Authenticate - AuthUtil authUtil = AuthUtil(); - if (await authUtil.useBiometrics()) { - // Biometric auth - bool authenticated = await authUtil.authenticateWithBiometrics(message); - if (authenticated) { - HapticUtil.fingerprintSucess(); - } - return authenticated; - } else { + Future _authenticateBiometrics(AuthUtil authUtil, String message) async { + // Biometric auth + bool authenticated = await authUtil.authenticateWithBiometrics(message); + if (authenticated) { + HapticUtil.fingerprintSucess(); + } + return authenticated; + } + + Future _authenticatePin(String message) async { String expectedPin = await sl.get().getPin(); bool result = await Navigator.of(context) .push(MaterialPageRoute(builder: (BuildContext context) { @@ -567,7 +564,23 @@ class _CreatingPrivateSaleSheetState extends State { ); })); await Future.delayed(Duration(milliseconds: 200)); - return result != null && result; + return result != null && result; + } + + Future authenticate() async { + String message = + AppLocalization.of(context).authenticateToCreatePrivateSaleParagraph; + // Authenticate + AuthUtil authUtil = AuthUtil(); + if (await authUtil.useBiometrics()) { + // Biometric auth + try { + return await _authenticateBiometrics(authUtil, message); + } catch (e) { + return await _authenticatePin(message); + } + } else { + return await _authenticatePin(message); } } } diff --git a/lib/ui/account/other_operations/transfer_account/transferring_account_sheet.dart b/lib/ui/account/other_operations/transfer_account/transferring_account_sheet.dart index df8df26..7690e5f 100644 --- a/lib/ui/account/other_operations/transfer_account/transferring_account_sheet.dart +++ b/lib/ui/account/other_operations/transfer_account/transferring_account_sheet.dart @@ -384,19 +384,16 @@ class _TransferringAccountSheetState extends State { } } - Future authenticate() async { - String message = - AppLocalization.of(context).authenticateToTransferParagraph; - // Authenticate - AuthUtil authUtil = AuthUtil(); - if (await authUtil.useBiometrics()) { - // Biometric auth - bool authenticated = await authUtil.authenticateWithBiometrics(message); - if (authenticated) { - HapticUtil.fingerprintSucess(); - } - return authenticated; - } else { + Future _authenticateBiometrics(AuthUtil authUtil, String message) async { + // Biometric auth + bool authenticated = await authUtil.authenticateWithBiometrics(message); + if (authenticated) { + HapticUtil.fingerprintSucess(); + } + return authenticated; + } + + Future _authenticatePin(String message) async { String expectedPin = await sl.get().getPin(); bool result = await Navigator.of(context) .push(MaterialPageRoute(builder: (BuildContext context) { @@ -410,7 +407,23 @@ class _TransferringAccountSheetState extends State { ); })); await Future.delayed(Duration(milliseconds: 200)); - return result != null && result; + return result != null && result; + } + + Future authenticate() async { + String message = + AppLocalization.of(context).authenticateToTransferParagraph; + // Authenticate + AuthUtil authUtil = AuthUtil(); + if (await authUtil.useBiometrics()) { + // Biometric auth + try { + return await _authenticateBiometrics(authUtil, message); + } catch (e) { + return await _authenticatePin(message); + } + } else { + return await _authenticatePin(message); } } } diff --git a/lib/ui/account/send/sending_sheet.dart b/lib/ui/account/send/sending_sheet.dart index 8f098b0..102516d 100644 --- a/lib/ui/account/send/sending_sheet.dart +++ b/lib/ui/account/send/sending_sheet.dart @@ -666,20 +666,16 @@ class _SendingSheetState extends State { } } - Future authenticate() async { - String message = AppLocalization.of(context) - .authenticateToSendParagraph - .replaceAll("%1", widget.amount); - // Authenticate - AuthUtil authUtil = AuthUtil(); - if (await authUtil.useBiometrics()) { - // Biometric auth - bool authenticated = await authUtil.authenticateWithBiometrics(message); - if (authenticated) { - HapticUtil.fingerprintSucess(); - } - return authenticated; - } else { + Future _authenticateBiometrics(AuthUtil authUtil, String message) async { + // Biometric auth + bool authenticated = await authUtil.authenticateWithBiometrics(message); + if (authenticated) { + HapticUtil.fingerprintSucess(); + } + return authenticated; + } + + Future _authenticatePin(String message) async { String expectedPin = await sl.get().getPin(); bool result = await Navigator.of(context) .push(MaterialPageRoute(builder: (BuildContext context) { @@ -693,7 +689,24 @@ class _SendingSheetState extends State { ); })); await Future.delayed(Duration(milliseconds: 200)); - return result != null && result; + return result != null && result; + } + + Future authenticate() async { + String message = AppLocalization.of(context) + .authenticateToSendParagraph + .replaceAll("%1", widget.amount); + // Authenticate + AuthUtil authUtil = AuthUtil(); + if (await authUtil.useBiometrics()) { + // Biometric auth + try { + return await _authenticateBiometrics(authUtil, message); + } catch (e) { + return await _authenticatePin(message); + } + } else { + return await _authenticatePin(message); } } } diff --git a/lib/ui/lockscreen/lock_screen.dart b/lib/ui/lockscreen/lock_screen.dart index 3eebc9a..745e208 100644 --- a/lib/ui/lockscreen/lock_screen.dart +++ b/lib/ui/lockscreen/lock_screen.dart @@ -105,6 +105,57 @@ class _LockScreenPageState extends State { } } + Future _authenticateBiometrics() async { + setState(() { + _showUnlockButton = true; + }); + bool authenticated = await AuthUtil().authenticateWithBiometrics(AppLocalization.of(context).authenticateToUnlockParagraph); + if (authenticated) { + _goHome(); + } else { + setState(() { + _showUnlockButton = true; + }); + } + } + + Future _authenticatePin({bool transitions = false}) async { + // PIN authentication + String expectedPin = await sl.get().getPin(); + if (transitions) { + Navigator.of(context).push( + MaterialPageRoute(builder: (BuildContext context) { + return PinScreen( + type: PinOverlayType.ENTER_PIN, + expectedPin: expectedPin, + description: AppLocalization.of(context).enterPINToUnlockParagraph, + onSuccess: (pin) { + _goHome(); + }); + }), + ); + } else { + Navigator.of(context).push( + NoPushTransitionRoute(builder: (BuildContext context) { + return PinScreen( + type: PinOverlayType.ENTER_PIN, + expectedPin: expectedPin, + description: AppLocalization.of(context).enterPINToUnlockParagraph, + onSuccess: (pin) { + _goHome(); + }); + }), + ); + } + Future.delayed(Duration(milliseconds: 200), () { + if (mounted) { + setState(() { + _showUnlockButton = true; + }); + } + }); + } + Future _authenticate({bool transitions = false}) async { // Test if user is locked out // Get duration of lockout @@ -122,55 +173,15 @@ class _LockScreenPageState extends State { setState(() { _lockedOut = false; }); - AuthenticationMethod authMethod = await sl.get().getAuthMethod(); - bool hasBiometrics = await AuthUtil().hasBiometrics(); - if (authMethod.method == AuthMethod.BIOMETRICS && hasBiometrics) { - setState(() { - _showUnlockButton = true; - }); - bool authenticated = await AuthUtil().authenticateWithBiometrics(AppLocalization.of(context).authenticateToUnlockParagraph); - if (authenticated) { - _goHome(); - } else { - setState(() { - _showUnlockButton = true; - }); + bool useBiometrics = await AuthUtil().useBiometrics(); + if (useBiometrics) { + try { + await _authenticateBiometrics(); + } catch (e) { + await _authenticatePin(transitions: transitions); } } else { - // PIN authentication - String expectedPin = await sl.get().getPin(); - if (transitions) { - Navigator.of(context).push( - MaterialPageRoute(builder: (BuildContext context) { - return PinScreen( - type: PinOverlayType.ENTER_PIN, - expectedPin: expectedPin, - description: AppLocalization.of(context).enterPINToUnlockParagraph, - onSuccess: (pin) { - _goHome(); - }); - }), - ); - } else { - Navigator.of(context).push( - NoPushTransitionRoute(builder: (BuildContext context) { - return PinScreen( - type: PinOverlayType.ENTER_PIN, - expectedPin: expectedPin, - description: AppLocalization.of(context).enterPINToUnlockParagraph, - onSuccess: (pin) { - _goHome(); - }); - }), - ); - } - Future.delayed(Duration(milliseconds: 200), () { - if (mounted) { - setState(() { - _showUnlockButton = true; - }); - } - }); + await _authenticatePin(transitions: transitions); } } diff --git a/lib/ui/settings/backup_private_key/backup_private_key_sheet.dart b/lib/ui/settings/backup_private_key/backup_private_key_sheet.dart index 50964c6..1f0d6fb 100644 --- a/lib/ui/settings/backup_private_key/backup_private_key_sheet.dart +++ b/lib/ui/settings/backup_private_key/backup_private_key_sheet.dart @@ -171,46 +171,58 @@ class _BackupPrivateKeySheetState extends State { ); } + Future _authenticateBiometrics(AuthUtil authUtil, String message, bool encrypted) async { + bool authenticated = await authUtil.authenticateWithBiometrics(message); + if (authenticated) { + HapticUtil.fingerprintSucess(); + Navigator.of(context).pop(); + if (encrypted) { + AppSheets.showBottomSheet( + context: context, widget: EncryptPrivateKeySheet()); + } else { + AppSheets.showBottomSheet( + context: context, widget: UnencryptedPrivateKeySheet()); + } + } + } + + Future _authenticatePin(bool encrypted, String message) async { + String expectedPin = await sl.get().getPin(); + await Navigator.of(context).push(MaterialPageRoute( + builder: (BuildContext context) { + return PinScreen( + type: PinOverlayType.ENTER_PIN, + onSuccess: (pin) { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + if (encrypted) { + AppSheets.showBottomSheet( + context: context, widget: EncryptPrivateKeySheet()); + } else { + AppSheets.showBottomSheet( + context: context, widget: UnencryptedPrivateKeySheet()); + } + }, + expectedPin: expectedPin, + description: message, + ); + }, + )); + } + Future authenticate(bool encrypted) async { String message = AppLocalization.of(context).authenticateToBackUpParagraph; // Authenticate AuthUtil authUtil = AuthUtil(); if (await authUtil.useBiometrics()) { // Biometric auth - bool authenticated = await authUtil.authenticateWithBiometrics(message); - if (authenticated) { - HapticUtil.fingerprintSucess(); - Navigator.of(context).pop(); - if (encrypted) { - AppSheets.showBottomSheet( - context: context, widget: EncryptPrivateKeySheet()); - } else { - AppSheets.showBottomSheet( - context: context, widget: UnencryptedPrivateKeySheet()); - } + try { + await _authenticateBiometrics(authUtil, message, encrypted); + } catch (e) { + await _authenticatePin(encrypted, message); } } else { - String expectedPin = await sl.get().getPin(); - await Navigator.of(context).push(MaterialPageRoute( - builder: (BuildContext context) { - return PinScreen( - type: PinOverlayType.ENTER_PIN, - onSuccess: (pin) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - if (encrypted) { - AppSheets.showBottomSheet( - context: context, widget: EncryptPrivateKeySheet()); - } else { - AppSheets.showBottomSheet( - context: context, widget: UnencryptedPrivateKeySheet()); - } - }, - expectedPin: expectedPin, - description: message, - ); - }, - )); + await _authenticatePin(encrypted, message); } } } diff --git a/lib/util/authentication.dart b/lib/util/authentication.dart index 9364443..0ad6632 100644 --- a/lib/util/authentication.dart +++ b/lib/util/authentication.dart @@ -14,7 +14,7 @@ class AuthUtil { bool canCheck = await localAuth.canCheckBiometrics; if (canCheck) { List availableBiometrics = await localAuth.getAvailableBiometrics(); - if (Platform.isIOS && availableBiometrics.contains(BiometricType.face)) { + if (availableBiometrics.contains(BiometricType.face)) { return true; } else if (availableBiometrics.contains(BiometricType.fingerprint)) { return true; diff --git a/pubspec.yaml b/pubspec.yaml index 4755279..edc5b1f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: A new Flutter project. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.4+14 +version: 1.0.5+15 environment: sdk: ">=2.1.0 <3.0.0" @@ -69,7 +69,11 @@ dependencies: shared_preferences: ^0.5.3+4 # Biometrics - local_auth: ^0.6.0+1 + local_auth: + git: + url: https://github.com/appditto/plugins.git + path: packages/local_auth + ref: master # mobx for state mobx: ^0.3.8+1