Fix fingerprint toggle: fallback to device credentials, clearer error messages

This commit is contained in:
cania
2026-08-13 02:49:11 +02:00
parent 7d4843dc0a
commit 235458702e
2 changed files with 33 additions and 12 deletions

View File

@@ -61,16 +61,36 @@ class AuthService {
}
/// Prompt the OS biometric dialog. Returns true on success.
Future<bool> authenticateWithBiometrics() async {
/// [errorOut] receives a human-readable reason when it fails.
Future<bool> authenticateWithBiometrics({String? errorOut}) async {
try {
return await _localAuth.authenticate(
localizedReason: 'Gunakan sidik jari untuk membuka Login Vault',
options: const AuthenticationOptions(
biometricOnly: true,
stickyAuth: true,
),
);
} catch (_) {
// Prefer strict biometric (fingerprint). If the device only has
// weaker biometrics (face) or none enrolled, fall back to allowing
// device credentials so the user isn't hard-blocked.
bool ok = false;
try {
ok = await _localAuth.authenticate(
localizedReason: 'Gunakan biometrik untuk membuka Login Vault',
options: const AuthenticationOptions(
biometricOnly: true,
stickyAuth: true,
),
);
} catch (_) {
ok = false;
}
if (!ok) {
ok = await _localAuth.authenticate(
localizedReason: 'Gunakan biometrik / kredensial perangkat',
options: const AuthenticationOptions(
biometricOnly: false,
stickyAuth: true,
),
);
}
return ok;
} catch (e) {
if (errorOut != null) errorOut = e.toString();
return false;
}
}

View File

@@ -64,13 +64,14 @@ class _SettingsScreenState extends State<SettingsScreen> {
Future<void> _toggleBiometric(bool value) async {
if (value && !_biometricAvailable) {
setState(() => _msg = 'Perangkat tidak mendukung sidik jari');
setState(() => _msg = 'Perangkat tidak mendukung biometrik');
return;
}
if (value) {
final ok = await widget.auth.authenticateWithBiometrics();
String? err;
final ok = await widget.auth.authenticateWithBiometrics(errorOut: err);
if (!ok) {
setState(() => _msg = 'Verifikasi sidik jari gagal');
setState(() => _msg = 'Verifikasi biometrik gagal: ${err ?? "dibatalkan"}');
return;
}
}