345 lines
9.2 KiB
Dart
345 lines
9.2 KiB
Dart
// import 'dart:ffi';
|
|
|
|
import 'package:csv/csv.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
import 'package:local_auth/local_auth.dart';
|
|
import 'package:synchronized/synchronized.dart';
|
|
|
|
class AppState extends ChangeNotifier {
|
|
// Adiciona a variável para controle de autenticação biométrica
|
|
bool _isBiometricAuthenticated = false;
|
|
bool get isBiometricAuthenticated => _isBiometricAuthenticated;
|
|
|
|
// Instância do LocalAuthentication
|
|
final LocalAuthentication auth = LocalAuthentication();
|
|
|
|
// Verifica suporte biométrico
|
|
Future<bool> checkBiometrics() async {
|
|
try {
|
|
return await auth.canCheckBiometrics;
|
|
} catch (e) {
|
|
clearBiometricAuthentication();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Solicita autenticação biométrica
|
|
Future<void> authenticateBiometric() async {
|
|
bool authenticated = false;
|
|
try {
|
|
authenticated = await auth.authenticate(
|
|
localizedReason: 'Scan your fingerprint to authenticate',
|
|
options: const AuthenticationOptions(
|
|
biometricOnly: true,
|
|
stickyAuth: true,
|
|
useErrorDialogs: true,
|
|
sensitiveTransaction: true,
|
|
));
|
|
if (authenticated) {
|
|
_isBiometricAuthenticated = true;
|
|
notifyListeners();
|
|
return Future.value();
|
|
// Salvar o estado de autenticação biométrica, se necessário
|
|
}
|
|
} catch (e) {
|
|
clearBiometricAuthentication();
|
|
return Future.error(e);
|
|
}
|
|
return Future.error(
|
|
''); // Add this line to ensure a value is always returned
|
|
}
|
|
|
|
// Função para limpar o estado de autenticação biométrica
|
|
void clearBiometricAuthentication() {
|
|
_isBiometricAuthenticated = false;
|
|
notifyListeners();
|
|
// Limpar a informação salva, se necessário
|
|
}
|
|
|
|
static AppState _instance = AppState._internal();
|
|
|
|
factory AppState() {
|
|
return _instance;
|
|
}
|
|
|
|
AppState._internal();
|
|
|
|
static void reset() {
|
|
_instance = AppState._internal();
|
|
}
|
|
|
|
Future initializePersistedState() async {
|
|
secureStorage = const FlutterSecureStorage();
|
|
|
|
await _safeInitAsync(() async {
|
|
_email = await secureStorage.getString('ff_email') ?? _email;
|
|
});
|
|
await _safeInitAsync(() async {
|
|
_passwd = await secureStorage.getString('ff_passwd') ?? _passwd;
|
|
});
|
|
await _safeInitAsync(() async {
|
|
_deviceType =
|
|
await secureStorage.getString('ff_deviceType') ?? _deviceType;
|
|
});
|
|
await _safeInitAsync(() async {
|
|
_isLogged = await secureStorage.getBool('ff_isLogged') ?? _isLogged;
|
|
});
|
|
|
|
await _safeInitAsync(() async {
|
|
_tokenAPNS = await secureStorage.getString('ff_tokenAPNS') ?? _tokenAPNS;
|
|
});
|
|
|
|
await _safeInitAsync(() async {
|
|
_accessPass = await secureStorage.getString('accessPass') ?? _accessPass;
|
|
});
|
|
await _safeInitAsync(() async {
|
|
_panicPass = await secureStorage.getString('panicPass') ?? _panicPass;
|
|
});
|
|
await _safeInitAsync(() async {
|
|
_fingerprintPass =
|
|
await secureStorage.getString('fingerprintPass') ?? _fingerprintPass;
|
|
});
|
|
await _safeInitAsync(() async {
|
|
_context = await secureStorage.getObject('ff_context') ?? _context;
|
|
});
|
|
|
|
await _safeInitAsync(() async {
|
|
_haveLocal = await secureStorage.getBool('ff_have_local') ?? _haveLocal;
|
|
});
|
|
|
|
await _safeInitAsync(() async {
|
|
_deviceDescription = await secureStorage.getString('deviceDescription') ??
|
|
_deviceDescription;
|
|
});
|
|
}
|
|
|
|
void update(VoidCallback callback) {
|
|
callback();
|
|
notifyListeners();
|
|
}
|
|
|
|
late FlutterSecureStorage secureStorage;
|
|
|
|
String _deviceDescription = '';
|
|
String get deviceDescription => _deviceDescription;
|
|
set deviceDescription(String value) {
|
|
_deviceDescription = value;
|
|
secureStorage.setString('deviceDescription', value);
|
|
}
|
|
|
|
void deleteDeviceDescription() {
|
|
secureStorage.delete(key: 'deviceDescription');
|
|
}
|
|
|
|
BuildContext? _context;
|
|
BuildContext? get context => _context;
|
|
set context(BuildContext? value) {
|
|
_context = value;
|
|
secureStorage.setString('ff_context', value.toString());
|
|
}
|
|
|
|
void deleteContext() {
|
|
secureStorage.delete(key: 'ff_context');
|
|
}
|
|
|
|
bool? _haveLocal = null;
|
|
bool? get haveLocal => _haveLocal;
|
|
set haveLocal(bool? value) {
|
|
_haveLocal = value;
|
|
secureStorage.setBool('ff_have_local', value);
|
|
}
|
|
|
|
void deleteHaveLocal() {
|
|
secureStorage.delete(key: 'ff_have_local');
|
|
}
|
|
|
|
String _fingerprintPass = '';
|
|
String get fingerprintPass => _fingerprintPass;
|
|
set fingerprintPass(String value) {
|
|
_fingerprintPass = value;
|
|
secureStorage.setString('fingerprintPass', value);
|
|
}
|
|
|
|
void deleteFingerprintPass() {
|
|
secureStorage.delete(key: 'fingerprintPass');
|
|
}
|
|
|
|
String _accessPass = '';
|
|
String get accessPass => _accessPass;
|
|
set accessPass(String value) {
|
|
_accessPass = value;
|
|
secureStorage.setString('accessPass', value);
|
|
}
|
|
|
|
void deleteAccessPass() {
|
|
secureStorage.delete(key: 'accessPass');
|
|
}
|
|
|
|
String _panicPass = '';
|
|
String get panicPass => _panicPass;
|
|
set panicPass(String value) {
|
|
_panicPass = value;
|
|
secureStorage.setString('panicPass', value);
|
|
}
|
|
|
|
void deletePanicPass() {
|
|
secureStorage.delete(key: 'panicPass');
|
|
}
|
|
|
|
String? _tokenAPNS = '';
|
|
String? get tokenAPNS => _tokenAPNS;
|
|
|
|
set tokenAPNS(String? value) {
|
|
_tokenAPNS = value;
|
|
if (value != null) {
|
|
secureStorage.setString('ff_tokenAPNS', value);
|
|
} else {
|
|
secureStorage.delete(key: 'ff_tokenAPNS');
|
|
}
|
|
}
|
|
|
|
void deleteTokenAPNS() {
|
|
secureStorage.delete(key: 'ff_tokenAPNS');
|
|
AppState().tokenAPNS = '';
|
|
}
|
|
|
|
String _email = '';
|
|
String get email => _email;
|
|
set email(String value) {
|
|
_email = value;
|
|
secureStorage.setString('ff_email', value);
|
|
}
|
|
|
|
void deleteEmail() {
|
|
secureStorage.delete(key: 'ff_email');
|
|
AppState().email = '';
|
|
}
|
|
|
|
String _passwd = '';
|
|
String get passwd => _passwd;
|
|
set passwd(String value) {
|
|
_passwd = value;
|
|
secureStorage.setString('ff_passwd', value);
|
|
}
|
|
|
|
void deletePasswd() {
|
|
secureStorage.delete(key: 'ff_passwd');
|
|
AppState().passwd = '';
|
|
}
|
|
|
|
String _deviceType = '';
|
|
String get deviceType => _deviceType;
|
|
set deviceType(String value) {
|
|
_deviceType = value;
|
|
secureStorage.setString('ff_deviceType', value);
|
|
}
|
|
|
|
void deleteDevice() {
|
|
secureStorage.delete(key: 'ff_deviceType');
|
|
AppState().deviceType = '';
|
|
}
|
|
|
|
bool _isLogged = false;
|
|
bool get isLogged => _isLogged;
|
|
set isLogged(bool value) {
|
|
_isLogged = value;
|
|
secureStorage.setBool('ff_isLogged', value);
|
|
}
|
|
|
|
void deleteIsLogged() {
|
|
secureStorage.delete(key: 'ff_isLogged');
|
|
}
|
|
|
|
String _token = '';
|
|
String get token => _token;
|
|
set token(String value) {
|
|
_token = value;
|
|
secureStorage.setString('ff_token', value);
|
|
}
|
|
|
|
void deleteToken() {
|
|
secureStorage.delete(key: 'ff_token');
|
|
AppState().token = '';
|
|
}
|
|
|
|
void deleteAll() {
|
|
AppState().deleteAccessPass();
|
|
AppState().deleteDevice();
|
|
AppState().deleteEmail();
|
|
AppState().deleteFingerprintPass();
|
|
AppState().deleteIsLogged();
|
|
AppState().deletePasswd();
|
|
AppState().deletePanicPass();
|
|
AppState().deleteToken();
|
|
AppState().deleteTokenAPNS();
|
|
AppState().deleteContext();
|
|
secureStorage.deleteAll();
|
|
AppState().isLogged = false;
|
|
}
|
|
}
|
|
|
|
void _safeInit(Function() initializeField) {
|
|
try {
|
|
initializeField();
|
|
} catch (_) {}
|
|
}
|
|
|
|
Future _safeInitAsync(Function() initializeField) async {
|
|
try {
|
|
await initializeField();
|
|
} catch (_) {}
|
|
}
|
|
|
|
extension FlutterSecureStorageExtensions on FlutterSecureStorage {
|
|
static final _lock = Lock();
|
|
|
|
Future<void> writeSync({required String key, String? value}) async =>
|
|
await _lock.synchronized(() async {
|
|
await write(key: key, value: value);
|
|
});
|
|
|
|
void remove(String key) => delete(key: key);
|
|
|
|
Future<String?> getString(String key) async => await read(key: key);
|
|
Future<void> setString(String key, String value) async =>
|
|
await writeSync(key: key, value: value);
|
|
|
|
Future<bool?> getBool(String key) async => (await read(key: key)) == 'true';
|
|
Future<void> setBool(String key, bool? value) async =>
|
|
await writeSync(key: key, value: value.toString());
|
|
|
|
Future<int?> getInt(String key) async =>
|
|
int.tryParse(await read(key: key) ?? '');
|
|
Future<void> setInt(String key, int value) async =>
|
|
await writeSync(key: key, value: value.toString());
|
|
|
|
Future<double?> getDouble(String key) async =>
|
|
double.tryParse(await read(key: key) ?? '');
|
|
Future<void> setDouble(String key, double value) async =>
|
|
await writeSync(key: key, value: value.toString());
|
|
|
|
Future<BuildContext?> getObject(String key) async {
|
|
final value = await read(key: key);
|
|
if (value == null || value.isEmpty) {
|
|
return null;
|
|
}
|
|
return value as BuildContext;
|
|
}
|
|
|
|
Future<List<String>?> getStringList(String key) async =>
|
|
await read(key: key).then((result) {
|
|
if (result == null || result.isEmpty) {
|
|
return null;
|
|
}
|
|
return const CsvToListConverter()
|
|
.convert(result)
|
|
.first
|
|
.map((e) => e.toString())
|
|
.toList();
|
|
});
|
|
Future<void> setStringList(String key, List<String> value) async =>
|
|
await writeSync(
|
|
key: key, value: const ListToCsvConverter().convert([value]));
|
|
}
|