Skip to content

Commit 8625688

Browse files
committed
feat: Fully localized local_auth messages.
1 parent e7f82e1 commit 8625688

File tree

3 files changed

+71
-6
lines changed

3 files changed

+71
-6
lines changed

lib/i18n/en/local_auth.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"common": {
3+
"goToSettings": "Go to settings"
4+
},
5+
"android": {
6+
"biometricHint": "Verify identity",
7+
"biometricNotRecognized": "Not recognized. Try again.",
8+
"signInTitle": "Authentication required",
9+
"biometricRequiredTitle": "Biometric required",
10+
"deviceCredentialsRequiredTitle": "Device credentials required",
11+
"deviceCredentialsSetupDescription": "Device credentials required",
12+
"goToSettingsDescription": "Biometric authentication is not set up on your device. Go to 'Settings > Security' to add biometric authentication."
13+
},
14+
"ios": {
15+
"lockOut": "Biometric authentication is disabled. Please lock and unlock your screen to enable it.",
16+
"goToSettingsDescription": "Biometric authentication is not set up on your device. Please either enable Touch ID or Face ID on your phone."
17+
}
18+
}

lib/i18n/fr/local_auth.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"common": {
3+
"goToSettings": "Aller dans les paramètres"
4+
},
5+
"android": {
6+
"biometricHint": "Vérifier votre identité",
7+
"biometricNotRecognized": "Non reconnu. Veuillez réessayer.",
8+
"signInTitle": "Authentification requise",
9+
"biometricRequiredTitle": "Biométrie requise",
10+
"deviceCredentialsRequiredTitle": "Identifiants de l'appareil requis",
11+
"deviceCredentialsSetupDescription": "Identifiants de l'appareil requis",
12+
"goToSettingsDescription": "L'authentification par biométrie n'est pas configurée sur votre appareil. Allez dans 'Paramètres > Sécurité' pour activer l'authentification par biométrie."
13+
},
14+
"ios": {
15+
"lockOut": "'authentification par biométrie est désactivée. Veuillez verrouiller puis déverrouiller votre appareil pour l'activer.",
16+
"goToSettingsDescription": "L'authentification par biométrie n'est pas configurée sur votre appareil. Veuillez activer Touch ID ou Face ID sur votre téléphone."
17+
}
18+
}

lib/model/app_unlock/method.dart

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import 'package:flutter/material.dart';
22
import 'package:flutter_riverpod/flutter_riverpod.dart';
33
import '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';
47
import 'package:open_authenticator/i18n/translations.g.dart';
58
import 'package:open_authenticator/model/crypto.dart';
69
import '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.
2730
class 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

Comments
 (0)