This commit is contained in:
Riccardo Usardi committed 2025-07-18 22:24:01 +02:00
commit e833bcaec4
224 files changed
+11812

No files matched your search

+125
View File
@@ -0,0 +1,125 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:local_auth/local_auth.dart';
import 'package:shared_preferences/shared_preferences.dart';
class AuthService {
static final AuthService _instance = AuthService._internal();
static AuthService get instance => _instance;
AuthService._internal();
final _secureStorage = const FlutterSecureStorage(); // Per piattaforme mobili
// Non inizializzare SharedPreferences qui direttamente, perché è async
String? _token;
static const String _tokenKey = 'AuthToken'; // Chiave comune per storage
String? get token => _token;
// Questa funzione ora serve solo per la logica specifica mobile (es. biometrica)
// Non usarla per decidere dove salvare il token, usa kIsWeb direttamente
Future<bool> _isMobileOrDesktopPlatform() async {
if (kIsWeb) return false;
// Android, iOS, Windows, Linux, macOS
//final deviceInfo = DeviceInfoPlugin();
if (defaultTargetPlatform == TargetPlatform.android ||
defaultTargetPlatform == TargetPlatform.iOS ||
defaultTargetPlatform == TargetPlatform.windows ||
defaultTargetPlatform == TargetPlatform.linux ||
defaultTargetPlatform == TargetPlatform.macOS) {
return true;
}
return false;
}
// Nuova funzione per salvare il token
Future<void> saveToken(String token) async {
_token = token; // Aggiorna il token in memoria
print('AuthToken: Tentativo di salvataggio token: $token');
if (kIsWeb) {
// Per Web: usa SharedPreferences (che su web usa localStorage)
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_tokenKey, token);
print('AuthToken: Token salvato in SharedPreferences (Web).');
} else if (await _isMobileOrDesktopPlatform()) {
// Per Mobile/Desktop: usa FlutterSecureStorage
await _secureStorage.write(key: _tokenKey, value: token);
print('AuthToken: Token salvato in FlutterSecureStorage (Mobile/Desktop).');
}
}
// Nuova funzione per caricare il token (senza biometria)
Future<String?> _loadTokenFromStorage() async {
if (kIsWeb) {
final prefs = await SharedPreferences.getInstance();
return prefs.getString(_tokenKey);
} else if (await _isMobileOrDesktopPlatform()) {
return _secureStorage.read(key: _tokenKey);
}
return null; // Caso non supportato
}
Future<bool> loadTokenWithBiometric() async {
// Prima, prova sempre a caricare il token dallo storage generale
// Questo è il token che verra' utilizzato se la biometria fallisce o non è disponibile.
_token = await _loadTokenFromStorage();
if (_token != null && !await _isMobileOrDesktopPlatform()) {
// Se siamo su web e il token è stato caricato, l'autenticazione è implicita (no biometria)
print('AuthToken: Token caricato da storage (Web), biometria non applicabile.');
return true;
}
// Se non è una piattaforma mobile/desktop supportata per la biometria, o se il token non c'è,
// o se la biometria non è disponibile/non supportata, gestisci di conseguenza.
if (!await _isMobileOrDesktopPlatform()) {
print('AuthToken: Biometria non disponibile su questa piattaforma.');
return false;
}
try {
final auth = LocalAuthentication();
final canAuth = await auth.canCheckBiometrics || await auth.isDeviceSupported();
if (!canAuth) {
print('AuthToken: Dispositivo non supporta biometria.');
// Se la biometria non è supportata, ma un token esiste, consideralo loggato
return _token != null;
}
final authenticated = await auth.authenticate(
localizedReason: 'Autenticati per accedere',
options: const AuthenticationOptions(
biometricOnly: true,
stickyAuth: true,
),
);
if (authenticated) {
final stored = await _secureStorage.read(key: _tokenKey); // Rileggi da secure storage
_token = stored; // Aggiorna il token in memoria con quello autenticato biometricamente
print('AuthToken: Biometria riuscita, token da storage sicuro: $_token');
return stored != null;
} else {
print('AuthToken: Autenticazione biometrica fallita.');
_token = null; // Se la biometria fallisce, resetta il token in memoria
}
} catch (e) {
debugPrint('AuthToken: Errore autenticazione biometrica: $e');
_token = null; // In caso di errore, resetta il token
}
return false;
}
Future<void> clear() async {
_token = null;
print('AuthToken: Tentativo di cancellazione token.');
if (kIsWeb) {
final prefs = await SharedPreferences.getInstance();
await prefs.remove(_tokenKey);
print('AuthToken: Token cancellato da SharedPreferences (Web).');
} else if (await _isMobileOrDesktopPlatform()) {
await _secureStorage.delete(key: _tokenKey);
print('AuthToken: Token cancellato da FlutterSecureStorage (Mobile/Desktop).');
}
}
}