Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Commit ac27f0a

Browse files
authored
Merge pull request #14 from minhdanh/dev
Various fixes and improvements
2 parents 7423e9e + 63fd9ac commit ac27f0a

File tree

4 files changed

+52
-16
lines changed

4 files changed

+52
-16
lines changed

lib/src/entities/authenticator.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,7 @@ abstract class Authenticator with WidgetsBindingObserver {
8383
/// Make an attempt to unlock the app using provided [pin]. If the [pin] is correct,
8484
/// [lockState] will be changed and lock screen dismissed
8585
Future<Either<LocalAuthFailure, Unit>> unlockWithPin({required Pin pin});
86+
87+
/// Check if provided [pin] is correct.
88+
Future<bool> isCorrectPin({required Pin pin});
8689
}

lib/src/entities/authenticator_impl.dart

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,9 @@ class AuthenticatorImpl with WidgetsBindingObserver implements Authenticator {
7070
final lastActive = await _repository.getPausedTimestamp();
7171
if (lastActive != null) {
7272
final now = DateTime.now();
73-
if (now.millisecondsSinceEpoch - lastActive.millisecondsSinceEpoch > lockAfterDuration.inMilliseconds) {
74-
_lockController.lock(
75-
availableMethods: await getAvailableBiometricMethods(),
76-
);
73+
if (now.millisecondsSinceEpoch - lastActive.millisecondsSinceEpoch >
74+
lockAfterDuration.inMilliseconds) {
75+
_lockWithBiometricMethods();
7776
}
7877
}
7978
break;
@@ -209,6 +208,12 @@ class AuthenticatorImpl with WidgetsBindingObserver implements Authenticator {
209208
case BiometricType.iris:
210209
methods.add(BiometricMethod.iris);
211210
break;
211+
case BiometricType.weak:
212+
methods.add(BiometricMethod.weak);
213+
break;
214+
case BiometricType.strong:
215+
methods.add(BiometricMethod.strong);
216+
break;
212217
default:
213218
break;
214219
}
@@ -295,6 +300,26 @@ class AuthenticatorImpl with WidgetsBindingObserver implements Authenticator {
295300
return const Left(LocalAuthFailure.unknown);
296301
}
297302

303+
@override
304+
Future<bool> isCorrectPin({required Pin pin}) async {
305+
final isEnabled = await isPinAuthenticationEnabled();
306+
if (!isEnabled) {
307+
return true;
308+
}
309+
if (await _isLockedDueToTooManyAttempts()) {
310+
return false;
311+
}
312+
313+
final userPin = await _repository.getPin(forUser: userId);
314+
if (userPin?.value != pin.value) {
315+
await _repository.addFailedAttempt(DateTime.now(), forUser: userId);
316+
return false;
317+
}
318+
await _repository.resetFailedAttempts(ofUser: userId);
319+
_repository.clearLastPausedTimestamp();
320+
return true;
321+
}
322+
298323
/// -- Helpers --
299324
300325
Future<bool> _supportsBiometricAuthentication() {
@@ -316,15 +341,21 @@ class AuthenticatorImpl with WidgetsBindingObserver implements Authenticator {
316341
if (!isEnabled) {
317342
_lockController.unlock();
318343
} else {
319-
final biometric = await getBiometricAuthenticationAvailability();
320-
if (biometric is Available) {
321-
_lockController.lock(
322-
availableMethods: biometric.isEnabled ? await getAvailableBiometricMethods() : const [],
323-
);
324-
}
325-
if (biometric is Unavailable) {
326-
_lockController.lock(availableMethods: const []);
327-
}
344+
_lockWithBiometricMethods();
345+
}
346+
}
347+
348+
Future<void> _lockWithBiometricMethods() async {
349+
final biometric = await getBiometricAuthenticationAvailability();
350+
if (biometric is Available) {
351+
_lockController.lock(
352+
availableMethods: biometric.isEnabled
353+
? await getAvailableBiometricMethods()
354+
: const [],
355+
);
356+
}
357+
if (biometric is Unavailable) {
358+
_lockController.lock(availableMethods: const []);
328359
}
329360
}
330361
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
enum BiometricMethod { fingerprint, face, iris }
1+
enum BiometricMethod { fingerprint, face, iris, weak, strong }

lib/src/presentation/authenticator_widget.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,17 @@ class _AuthenticatorWidgetState extends State<AuthenticatorWidget> {
7070
late final StreamSubscription lockSubscription;
7171
OverlayEntry? overlayEntry;
7272
bool _isShowingSplashScreen = true;
73+
late final Stream<LockState> lockState ;
7374

7475
@override
7576
void initState() {
7677
super.initState();
78+
lockState = widget.authenticator.lockState;
7779
PinLock.setHideAppContent(
7880
preference: widget.hideAppContent,
7981
iosAssetImage: widget.iosImageAsset,
8082
);
81-
lockSubscription = widget.authenticator.lockState.listen((event) {
83+
lockSubscription = lockState.listen((event) {
8284
if (event is Unlocked) {
8385
overlayEntry?.remove();
8486
overlayEntry = null;
@@ -122,7 +124,7 @@ class _AuthenticatorWidgetState extends State<AuthenticatorWidget> {
122124
@override
123125
Widget build(BuildContext context) {
124126
return StreamBuilder<LockState>(
125-
stream: widget.authenticator.lockState,
127+
stream: lockState,
126128
builder: (context, snapshot) {
127129
if (snapshot.hasData && !_isShowingSplashScreen) {
128130
return widget.child;

0 commit comments

Comments
 (0)