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. /// 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 { try {
return await _localAuth.authenticate( // Prefer strict biometric (fingerprint). If the device only has
localizedReason: 'Gunakan sidik jari untuk membuka Login Vault', // 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( options: const AuthenticationOptions(
biometricOnly: true, biometricOnly: true,
stickyAuth: true, stickyAuth: true,
), ),
); );
} catch (_) { } 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; return false;
} }
} }

View File

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