From 71bdfb3e5bfaeb4033281a9485e296c48f33a4cc Mon Sep 17 00:00:00 2001 From: Oleksandr Sobol Date: Tue, 21 Jan 2020 19:51:37 +0200 Subject: [PATCH] CWA-164 | added biometric authentication --- android/app/src/main/AndroidManifest.xml | 1 + .../cakewallet/cake_wallet/MainActivity.java | 4 ++-- lib/generated/i18n.dart | 21 ++++++++++++++++ lib/src/domain/common/biometric_auth.dart | 24 +++++++++++++++++++ lib/src/screens/auth/auth_page.dart | 22 +++++++++++++++++ lib/src/stores/auth/auth_store.dart | 5 ++++ pubspec.lock | 7 ++++++ pubspec.yaml | 1 + res/values/strings_de.arb | 4 +++- res/values/strings_en.arb | 4 +++- res/values/strings_es.arb | 4 +++- res/values/strings_hi.arb | 4 +++- res/values/strings_ja.arb | 4 +++- res/values/strings_ko.arb | 4 +++- res/values/strings_nl.arb | 4 +++- res/values/strings_pl.arb | 4 +++- res/values/strings_pt.arb | 4 +++- res/values/strings_ru.arb | 4 +++- res/values/strings_zh.arb | 4 +++- 19 files changed, 116 insertions(+), 13 deletions(-) create mode 100644 lib/src/domain/common/biometric_auth.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 86893fd1b..bee0fa2b6 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,6 +7,7 @@ FlutterApplication and put your custom class here. --> + "Authenticated"; String get authentication => "Authentication"; String get available_balance => "Available Balance"; + String get biometric_auth_reason => "Scan your fingerprint to authenticate"; String get cancel => "Cancel"; String get change => "Change"; String get change_currency => "Change Currency"; @@ -315,6 +316,8 @@ class $de extends S { @override String get hidden_balance => "Verstecktes Gleichgewicht"; @override + String get biometric_auth_reason => "Scannen Sie Ihren Fingerabdruck zur Authentifizierung"; + @override String get transaction_sent => "Transaktion gesendet!"; @override String get password => "Passwort"; @@ -861,6 +864,8 @@ class $hi extends S { @override String get hidden_balance => "छिपा हुआ संतुलन"; @override + String get biometric_auth_reason => "प्रमाणित करने के लिए अपने फ़िंगरप्रिंट को स्कैन करें"; + @override String get transaction_sent => "भेजा गया लेन-देन"; @override String get password => "पारण शब्द"; @@ -1407,6 +1412,8 @@ class $ru extends S { @override String get hidden_balance => "Скрытый баланс"; @override + String get biometric_auth_reason => "Отсканируйте свой отпечаток пальца для аутентификации"; + @override String get transaction_sent => "Tранзакция отправлена!"; @override String get password => "Password"; @@ -1953,6 +1960,8 @@ class $ko extends S { @override String get hidden_balance => "숨겨진 균형"; @override + String get biometric_auth_reason => "지문을 스캔하여 인증"; + @override String get transaction_sent => "거래가 전송되었습니다!"; @override String get password => "암호"; @@ -2499,6 +2508,8 @@ class $pt extends S { @override String get hidden_balance => "Saldo escondido"; @override + String get biometric_auth_reason => "Digitalize sua impressão digital para autenticar"; + @override String get transaction_sent => "Transação enviada!"; @override String get password => "Senha"; @@ -3045,6 +3056,8 @@ class $ja extends S { @override String get hidden_balance => "隠れたバランス"; @override + String get biometric_auth_reason => "प指紋をスキャンして認証する"; + @override String get transaction_sent => "トランザクションが送信されました!"; @override String get password => "パスワード"; @@ -3595,6 +3608,8 @@ class $pl extends S { @override String get hidden_balance => "Ukryta równowaga"; @override + String get biometric_auth_reason => "Zeskanuj swój odcisk palca, aby go uwierzytelnić"; + @override String get transaction_sent => "Transakcja wysłana!"; @override String get password => "Hasło"; @@ -4141,6 +4156,8 @@ class $es extends S { @override String get hidden_balance => "Balance oculto"; @override + String get biometric_auth_reason => "Escanee su huella digital para autenticar"; + @override String get transaction_sent => "Transacción enviada!"; @override String get password => "Contraseña"; @@ -4687,6 +4704,8 @@ class $nl extends S { @override String get hidden_balance => "Verborgen balans"; @override + String get biometric_auth_reason => "Scan uw vingerafdruk om te verifiëren"; + @override String get transaction_sent => "Transactie verzonden!"; @override String get password => "Wachtwoord"; @@ -5233,6 +5252,8 @@ class $zh extends S { @override String get hidden_balance => "隐藏余额"; @override + String get biometric_auth_reason => "掃描指紋以進行身份驗證"; + @override String get transaction_sent => "交易已发送"; @override String get password => "密码"; diff --git a/lib/src/domain/common/biometric_auth.dart b/lib/src/domain/common/biometric_auth.dart new file mode 100644 index 000000000..50fff4cf8 --- /dev/null +++ b/lib/src/domain/common/biometric_auth.dart @@ -0,0 +1,24 @@ +import 'package:local_auth/local_auth.dart'; +import 'package:flutter/services.dart'; +import 'package:cake_wallet/generated/i18n.dart'; + +class BiometricAuth { + + Future isAuthenticated() async { + final LocalAuthentication _localAuth = LocalAuthentication(); + + try { + return await _localAuth.authenticateWithBiometrics( + localizedReason: S.current.biometric_auth_reason, + useErrorDialogs: true, + stickyAuth: false + ); + } on PlatformException + catch(e) { + print(e); + } + + return false; + } + +} \ No newline at end of file diff --git a/lib/src/screens/auth/auth_page.dart b/lib/src/screens/auth/auth_page.dart index 5711b8b5e..e963577c8 100644 --- a/lib/src/screens/auth/auth_page.dart +++ b/lib/src/screens/auth/auth_page.dart @@ -6,6 +6,8 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/src/stores/auth/auth_state.dart'; import 'package:cake_wallet/src/stores/auth/auth_store.dart'; import 'package:cake_wallet/src/screens/pin_code/pin_code.dart'; +import 'package:cake_wallet/src/stores/settings/settings_store.dart'; +import 'package:cake_wallet/src/domain/common/biometric_auth.dart'; typedef OnAuthenticationFinished = void Function(bool, AuthPageState); @@ -33,6 +35,26 @@ class AuthPageState extends State { @override Widget build(BuildContext context) { final authStore = Provider.of(context); + final settingsStore = Provider.of(context); + + if (settingsStore.allowBiometricalAuthentication) { + WidgetsBinding.instance.addPostFrameCallback((_) { + final biometricAuth = BiometricAuth(); + biometricAuth.isAuthenticated().then( + (isAuth) { + if (isAuth) { + authStore.biometricAuth(); + _key.currentState.showSnackBar( + SnackBar( + content: Text(S.of(context).authenticated), + backgroundColor: Colors.green, + ), + ); + } + } + ); + }); + } reaction((_) => authStore.state, (AuthState state) { if (state is AuthenticatedSuccessfully) { diff --git a/lib/src/stores/auth/auth_store.dart b/lib/src/stores/auth/auth_store.dart index 966ccc0b1..91912d7da 100644 --- a/lib/src/stores/auth/auth_store.dart +++ b/lib/src/stores/auth/auth_store.dart @@ -91,4 +91,9 @@ abstract class AuthStoreBase with Store { return Duration(milliseconds: timeout); } + + @action + void biometricAuth() { + state = AuthenticatedSuccessfully(); + } } diff --git a/pubspec.lock b/pubspec.lock index a8b5c8ba7..72b66ac7a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -406,6 +406,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.3.19" + local_auth: + dependency: "direct main" + description: + name: local_auth + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.1" logging: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 306c34298..eccfe4fce 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -45,6 +45,7 @@ dependencies: path: ./cw_monero hive: ^1.2.0 hive_flutter: ^0.2.1 + local_auth: ^0.6.1 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index eeb48b405..23e3cb8b2 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -336,5 +336,7 @@ "paste" : "Einfügen", "restore_from_seed_placeholder" : "Bitte geben Sie hier Ihren Code ein", "add_new_word" : "Neues Wort hinzufügen", - "incorrect_seed" : "Der eingegebene Text ist ungültig." + "incorrect_seed" : "Der eingegebene Text ist ungültig.", + + "biometric_auth_reason" : "Scannen Sie Ihren Fingerabdruck zur Authentifizierung" } \ No newline at end of file diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index e107a4a9e..a0667d43b 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -336,5 +336,7 @@ "paste" : "Paste", "restore_from_seed_placeholder" : "Please enter or paste your seed here", "add_new_word" : "Add new word", - "incorrect_seed" : "The text entered is not valid." + "incorrect_seed" : "The text entered is not valid.", + + "biometric_auth_reason" : "Scan your fingerprint to authenticate" } \ No newline at end of file diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index fa46ee111..e22cfa02d 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -336,5 +336,7 @@ "paste" : "Pegar", "restore_from_seed_placeholder" : "Ingrese o pegue su frase de código aquí", "add_new_word" : "Agregar palabra nueva", - "incorrect_seed" : "El texto ingresado no es válido." + "incorrect_seed" : "El texto ingresado no es válido.", + + "biometric_auth_reason" : "Escanee su huella digital para autenticar" } \ No newline at end of file diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index b6343da7d..68e7191be 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -336,5 +336,7 @@ "paste" : "पेस्ट करें", "restore_from_seed_placeholder" : "कृपया अपना कोड वाक्यांश यहां दर्ज करें या पेस्ट करें", "add_new_word" : "नया शब्द जोड़ें", - "incorrect_seed" : "दर्ज किया गया पाठ मान्य नहीं है।" + "incorrect_seed" : "दर्ज किया गया पाठ मान्य नहीं है।", + + "biometric_auth_reason" : "प्रमाणित करने के लिए अपने फ़िंगरप्रिंट को स्कैन करें" } \ No newline at end of file diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index e40aaa2b1..7f209f1d1 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -336,5 +336,7 @@ "paste" : "ペースト", "restore_from_seed_placeholder" : "ここにコードフレーズを入力または貼り付けてください", "add_new_word" : "新しい単語を追加", - "incorrect_seed" : "入力されたテキストは無効です。" + "incorrect_seed" : "入力されたテキストは無効です。", + + "biometric_auth_reason" : "प指紋をスキャンして認証する" } \ No newline at end of file diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 6c594ea13..7f4e75c1a 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -336,5 +336,7 @@ "paste" : "풀", "restore_from_seed_placeholder" : "여기에 코드 문구를 입력하거나 붙여 넣으십시오.", "add_new_word" : "새로운 단어 추가", - "incorrect_seed" : "입력하신 텍스트가 유효하지 않습니다." + "incorrect_seed" : "입력하신 텍스트가 유효하지 않습니다.", + + "biometric_auth_reason" : "지문을 스캔하여 인증" } \ No newline at end of file diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 986ebfa8e..2f683e0c0 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -336,5 +336,7 @@ "paste" : "Plakken", "restore_from_seed_placeholder" : "Voer hier uw codefrase in of plak deze", "add_new_word" : "Nieuw woord toevoegen", - "incorrect_seed" : "De ingevoerde tekst is niet geldig." + "incorrect_seed" : "De ingevoerde tekst is niet geldig.", + + "biometric_auth_reason" : "Scan uw vingerafdruk om te verifiëren" } \ No newline at end of file diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index bcfcffe1b..e38761024 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -336,5 +336,7 @@ "paste" : "Pasta", "restore_from_seed_placeholder" : "Wpisz lub wklej tutaj swoją frazę kodową", "add_new_word" : "Dodaj nowe słowo", - "incorrect_seed" : "Wprowadzony tekst jest nieprawidłowy." + "incorrect_seed" : "Wprowadzony tekst jest nieprawidłowy.", + + "biometric_auth_reason" : "Zeskanuj swój odcisk palca, aby go uwierzytelnić" } \ No newline at end of file diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 8a6d6d4c8..7463bbd03 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -336,5 +336,7 @@ "paste" : "Colar", "restore_from_seed_placeholder" : "Digite ou cole sua frase de código aqui", "add_new_word" : "Adicionar nova palavra", - "incorrect_seed" : "O texto digitado não é válido." + "incorrect_seed" : "O texto digitado não é válido.", + + "biometric_auth_reason" : "Digitalize sua impressão digital para autenticar" } diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 5ca7c9bcb..0dc4c4bde 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -336,5 +336,7 @@ "paste" : "Вставить", "restore_from_seed_placeholder" : "Введите или вставте код фразу вашего кошелька", "add_new_word" : "Добавить новое слово", - "incorrect_seed" : "Введенный текст некорректный." + "incorrect_seed" : "Введенный текст некорректный.", + + "biometric_auth_reason" : "Отсканируйте свой отпечаток пальца для аутентификации" } \ No newline at end of file diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 69c5e886f..23cc240e3 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -336,5 +336,7 @@ "paste" : "糊", "restore_from_seed_placeholder" : "请在此处输入或粘贴您的代码短语", "add_new_word" : "添加新词", - "incorrect_seed" : "输入的文字无效。" + "incorrect_seed" : "输入的文字无效。", + + "biometric_auth_reason" : "掃描指紋以進行身份驗證" } \ No newline at end of file