try: fix repeated auth (#294)

This commit is contained in:
lollipopkit
2024-03-21 01:24:07 -06:00
parent 32da0c8283
commit 7feebb8c1f
3 changed files with 57 additions and 39 deletions

View File

@@ -2,14 +2,22 @@ import 'dart:io';
import 'package:flutter/services.dart';
import 'package:local_auth/local_auth.dart';
// ignore: depend_on_referenced_packages
import 'package:local_auth_android/local_auth_android.dart';
// ignore: depend_on_referenced_packages
import 'package:local_auth_ios/types/auth_messages_ios.dart';
import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/core/utils/platform/base.dart';
import 'package:local_auth/error_codes.dart' as errs;
import 'package:toolbox/data/res/store.dart';
abstract final class BioAuth {
static final _auth = LocalAuthentication();
static bool get isPlatformSupported => isAndroid || isIOS || isWindows;
static bool _isAuthing = false;
static Future<bool> get isAvail async {
if (!isPlatformSupported) return false;
if (!await _auth.canCheckBiometrics) {
@@ -24,16 +32,55 @@ abstract final class BioAuth {
biometrics.contains(BiometricType.fingerprint);
}
static Future<AuthResult> auth([String? msg]) async {
static void auth([int count = 0]) async {
if (Stores.setting.useBioAuth.fetch()) {
if (!_isAuthing) {
_isAuthing = true;
final val = await authWithResult();
switch (val) {
case AuthResult.success:
// wait for animation
Future.delayed(
count >= 3 ? const Duration(milliseconds: 500) : const Duration(seconds: 1),
() => _isAuthing = false,
);
break;
case AuthResult.fail:
case AuthResult.cancel:
_isAuthing = false;
auth(count + 1);
break;
case AuthResult.notAvail:
_isAuthing = false;
Stores.setting.useBioAuth.put(false);
break;
}
}
}
}
static Future<AuthResult> authWithResult() async {
if (!await isAvail) return AuthResult.notAvail;
try {
await _auth.stopAuthentication();
final reuslt = await _auth.authenticate(
localizedReason: msg ?? 'Auth required',
localizedReason: l10n.authRequired,
options: const AuthenticationOptions(
stickyAuth: true,
biometricOnly: true,
),
);
authMessages: [
AndroidAuthMessages(
biometricHint: l10n.bioAuth,
biometricNotRecognized: l10n.failed,
biometricRequiredTitle: l10n.authRequired,
biometricSuccess: l10n.success,
cancelButton: l10n.cancel,
),
IOSAuthMessages(
lockOut: l10n.authRequired,
cancelButton: l10n.ok,
),
]);
if (reuslt) {
return AuthResult.success;
}

View File

@@ -47,7 +47,6 @@ class _HomePageState extends State<HomePage>
final _selectIndex = ValueNotifier(0);
bool _switchingPage = false;
bool _isAuthing = false;
@override
void initState() {
@@ -83,7 +82,7 @@ class _HomePageState extends State<HomePage>
switch (state) {
case AppLifecycleState.resumed:
_auth();
BioAuth.auth();
if (!Pros.server.isAutoRefreshOn) {
Pros.server.startAutoRefresh();
}
@@ -316,7 +315,7 @@ ${GithubIds.participants.map((e) => '[$e](${e.url})').join(' ')}
@override
Future<void> afterFirstLayout(BuildContext context) async {
// Auth required for first launch
_auth();
BioAuth.auth();
if (Stores.setting.autoCheckAppUpdate.fetch()) {
doUpdate(context);
@@ -357,32 +356,4 @@ ${GithubIds.participants.map((e) => '[$e](${e.url})').join(' ')}
Loggers.app.warning('Update json settings failed', e, trace);
}
}
void _auth() {
if (Stores.setting.useBioAuth.fetch()) {
if (!_isAuthing) {
_isAuthing = true;
BioAuth.auth(l10n.authRequired).then(
(val) {
switch (val) {
case AuthResult.success:
// wait for animation
Future.delayed(
const Duration(seconds: 1), () => _isAuthing = false);
break;
case AuthResult.fail:
case AuthResult.cancel:
_isAuthing = false;
_auth();
break;
case AuthResult.notAvail:
_isAuthing = false;
Stores.setting.useBioAuth.put(false);
break;
}
},
);
}
}
}
}

View File

@@ -36,7 +36,7 @@ abstract final class PlatformPublicSettings {
return;
}
// Only auth when turn off (val == false)
final result = await BioAuth.auth(l10n.authRequired);
final result = await BioAuth.authWithResult();
// If failed, turn on again
if (result != AuthResult.success) {
Stores.setting.useBioAuth.put(true);