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 _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 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 _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 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 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).'); } } }