authenticate method
Authenticates the user using biometrics
Returns true
if authentication was successful, false
otherwise
Throws:
- BiometricUnavailableException if biometrics are not available
- BiometricLockoutException if biometrics are temporarily locked out
- AuthenticationFailedException if authentication fails permanently
Implementation
Future<bool> authenticate({bool allowFallback = false}) async {
final canCheck = await canCheckBiometrics;
if (!canCheck) {
throw const BiometricUnavailableException(
"Biometric authentication is not available on this device",
);
}
try {
final authenticated = await _localAuth.authenticate(
localizedReason: _config.localizedReason,
options: _config.authenticationOptions,
);
return authenticated;
} on PlatformException catch (e) {
debugPrint("Authentication CODE: ${e.code}");
debugPrint("Authentication MESSAGE: ${e.message}");
debugPrint("Authentication DETAILS: ${e.details}");
// Handle permanent lockout by automatically trying device credentials
if (e.code == 'PermanentlyLockedOut') {
debugPrint(
"π Biometrics permanently locked out, automatically trying device credentials...",
);
try {
final deviceAuthResult = await authenticateWithDeviceCredentials();
if (deviceAuthResult) {
debugPrint("β
Device credential authentication successful");
return true;
}
return false;
} catch (deviceAuthError) {
debugPrint(
"β Device credential authentication failed: $deviceAuthError",
);
throw AuthenticationFailedException(
"Biometric authentication is permanently disabled. "
"Device credential authentication also failed: ${deviceAuthError.toString().replaceAll('Exception: ', '')}",
e.code,
);
}
}
// Handle temporary lockout error by throwing a specific exception
if (e.code == 'LockedOut' || e.code == 'ERROR_LOCKOUT') {
debugPrint(
"π Biometrics temporarily locked out, throwing lockout exception...",
);
throw BiometricLockoutException(
"Biometric authentication is temporarily disabled due to too many failed attempts. Please try again later.",
e.code,
);
}
throw AuthenticationFailedException(
e.message ?? 'Unknown authentication error',
e.code,
);
} catch (e) {
throw AuthenticationFailedException("Authentication failed: $e");
}
}