Files
PilotVault/Fly App/lib/biometric_auth.dart
T
tajniak81andClaude Opus 4.8 afc6952eda Initial commit: PilotVault multi-service project
Add API Server (Go/PocketBase), Web App (Go BFF + Vue), Fly App
(Flutter/DJI MSDK), Adobe Plugin, and Docker/Docker AIO deployment
configs. Design assets and build artifacts are gitignored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 11:43:33 +02:00

59 lines
2.2 KiB
Dart

import 'package:local_auth/local_auth.dart';
/// Thin wrapper over [LocalAuthentication] for the login screen. Exposes what
/// the device can do (fingerprint vs. face) and a single [authenticate] call.
class BiometricAuth {
final LocalAuthentication _auth = LocalAuthentication();
bool _supported = false;
bool _canCheck = false;
List<BiometricType> _types = const <BiometricType>[];
/// Whether any biometric login can be offered (device supports it and the
/// user has at least one biometric enrolled).
bool get available => _supported && _canCheck;
/// The device advertises a face enrolment. On some Androids the platform only
/// reports weak/strong instead of the specific modality — see [showFace].
bool get hasFace => _types.contains(BiometricType.face);
bool get _hasFingerprint =>
_types.contains(BiometricType.fingerprint) ||
_types.contains(BiometricType.strong) ||
_types.contains(BiometricType.weak);
/// Show the face button when face is reported, or when the device supports
/// biometrics but reports no specific modality (BiometricPrompt still lets the
/// user use whatever strong biometric — often face — is enrolled).
bool get showFace => available && (hasFace || _types.isEmpty);
/// Show the fingerprint button when fingerprint is reported, or as the generic
/// fallback when no specific modality is advertised.
bool get showFingerprint => available && (_hasFingerprint || _types.isEmpty);
/// Refreshes the capability flags. Safe to call repeatedly.
Future<void> refresh() async {
try {
_supported = await _auth.isDeviceSupported();
_canCheck = await _auth.canCheckBiometrics;
_types = _supported ? await _auth.getAvailableBiometrics() : const <BiometricType>[];
} catch (_) {
_supported = false;
_canCheck = false;
_types = const <BiometricType>[];
}
}
/// Prompts the OS biometric sheet. Returns true only on a verified match.
Future<bool> authenticate({required String reason}) {
return _auth.authenticate(
localizedReason: reason,
options: const AuthenticationOptions(
biometricOnly: true,
stickyAuth: true,
useErrorDialogs: true,
),
);
}
}