11import 'package:flutter/material.dart' ;
22import 'package:flutter_riverpod/flutter_riverpod.dart' ;
33import 'package:local_auth/local_auth.dart' ;
4+ import 'package:local_auth_android/local_auth_android.dart' ;
5+ import 'package:local_auth_darwin/local_auth_darwin.dart' ;
6+ import 'package:local_auth_windows/local_auth_windows.dart' ;
47import 'package:open_authenticator/i18n/translations.g.dart' ;
58import 'package:open_authenticator/model/crypto.dart' ;
69import 'package:open_authenticator/model/password_verification/methods/password_signature.dart' ;
@@ -17,22 +20,48 @@ sealed class AppUnlockMethod {
1720
1821 /// Triggered when this method has been chosen has the app unlock method.
1922 /// [unlockResult] is the result of the [tryUnlock] call.
20- Future <void > onMethodChosen (AsyncNotifierProviderRef ref, { ResultSuccess ? enableResult }) => Future .value ();
23+ Future <void > onMethodChosen (AsyncNotifierProviderRef ref, {ResultSuccess ? enableResult}) => Future .value ();
2124
2225 /// Triggered when a new method will be used for app unlocking.
23- Future <void > onMethodChanged (AsyncNotifierProviderRef ref, { ResultSuccess ? disableResult }) => Future .value ();
26+ Future <void > onMethodChanged (AsyncNotifierProviderRef ref, {ResultSuccess ? disableResult}) => Future .value ();
2427}
2528
2629/// Local authentication.
2730class LocalAuthenticationAppUnlockMethod extends AppUnlockMethod {
2831 @override
2932 Future <Result > tryUnlock (BuildContext context, AsyncNotifierProviderRef ref, UnlockReason reason) async {
30- String message = translations.appUnlock.localAuthentication[reason.name] ?? 'Authenticate to access the app.' ;
3133 LocalAuthentication auth = LocalAuthentication ();
3234 if (! (await auth.isDeviceSupported ())) {
3335 return ResultError ();
3436 }
35- return (await auth.authenticate (localizedReason: message)) ? const ResultSuccess () : const ResultCancelled ();
37+ if (! context.mounted) {
38+ return const ResultCancelled ();
39+ }
40+ bool result = await auth.authenticate (
41+ localizedReason: translations.appUnlock.localAuthentication[reason.name] ?? 'Authenticate to access the app.' ,
42+ authMessages: [
43+ IOSAuthMessages (
44+ lockOut: translations.localAuth.ios.lockOut,
45+ goToSettingsButton: translations.localAuth.common.goToSettings,
46+ goToSettingsDescription: translations.localAuth.ios.goToSettingsDescription,
47+ cancelButton: MaterialLocalizations .of (context).cancelButtonLabel,
48+ ),
49+ AndroidAuthMessages (
50+ biometricHint: translations.localAuth.android.biometricHint,
51+ biometricNotRecognized: translations.localAuth.android.biometricNotRecognized,
52+ biometricRequiredTitle: translations.localAuth.android.biometricRequiredTitle,
53+ biometricSuccess: translations.error.noError,
54+ cancelButton: MaterialLocalizations .of (context).cancelButtonLabel,
55+ deviceCredentialsRequiredTitle: translations.localAuth.android.deviceCredentialsRequiredTitle,
56+ deviceCredentialsSetupDescription: translations.localAuth.android.deviceCredentialsSetupDescription,
57+ goToSettingsButton: translations.localAuth.common.goToSettings,
58+ goToSettingsDescription: translations.localAuth.android.goToSettingsDescription,
59+ signInTitle: translations.localAuth.android.signInTitle,
60+ ),
61+ const WindowsAuthMessages (),
62+ ],
63+ );
64+ return result ? const ResultSuccess () : const ResultCancelled ();
3665 }
3766
3867 /// Returns whether this unlock method is supported;
@@ -78,15 +107,15 @@ class MasterPasswordAppUnlockMethod extends AppUnlockMethod {
78107 }
79108
80109 @override
81- Future <void > onMethodChosen (AsyncNotifierProviderRef ref, { ResultSuccess ? enableResult }) async {
110+ Future <void > onMethodChosen (AsyncNotifierProviderRef ref, {ResultSuccess ? enableResult}) async {
82111 String ? password = enableResult? .valueOrNull;
83112 if (await ref.read (passwordSignatureVerificationMethodProvider.notifier).enable (password)) {
84113 await ref.read (cryptoStoreProvider.notifier).deleteFromLocalStorage ();
85114 }
86115 }
87116
88117 @override
89- Future <void > onMethodChanged (AsyncNotifierProviderRef ref, { ResultSuccess ? disableResult }) async {
118+ Future <void > onMethodChanged (AsyncNotifierProviderRef ref, {ResultSuccess ? disableResult}) async {
90119 await ref.read (passwordSignatureVerificationMethodProvider.notifier).disable ();
91120 await ref.read (cryptoStoreProvider.notifier).saveCurrentOnLocalStorage (checkSettings: false );
92121 }
0 commit comments