112 lines
4 KiB
Dart
112 lines
4 KiB
Dart
// lib/remote/remote_settings.dart
|
||
import 'package:flutter/foundation.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||
|
||
class RemoteSettings {
|
||
static const _storage = FlutterSecureStorage(
|
||
aOptions: AndroidOptions(
|
||
encryptedSharedPreferences: true,
|
||
resetOnError: true, // auto-reset della singola voce cifrata se fallisce la decrittazione
|
||
),
|
||
);
|
||
|
||
static const _kEnabled = 'remote_enabled';
|
||
static const _kBaseUrl = 'remote_base_url';
|
||
static const _kIndexPath = 'remote_index_path';
|
||
static const _kEmail = 'remote_email';
|
||
static const _kPassword = 'remote_password';
|
||
|
||
static final bool defaultEnabled = kDebugMode ? true : false;
|
||
static final String defaultBaseUrl = kDebugMode ? 'https://prova.patachina.it' : '';
|
||
static final String defaultIndexPath = kDebugMode ? 'photos/' : '';
|
||
static final String defaultEmail = kDebugMode ? 'fabio@gmail.com' : '';
|
||
static final String defaultPassword = kDebugMode ? 'master66' : '';
|
||
|
||
bool enabled;
|
||
String baseUrl;
|
||
String indexPath;
|
||
String email;
|
||
String password;
|
||
|
||
RemoteSettings({
|
||
required this.enabled,
|
||
required this.baseUrl,
|
||
required this.indexPath,
|
||
required this.email,
|
||
required this.password,
|
||
});
|
||
|
||
// 🔎 helper: leggi una chiave in modo “safe” e, se fallisce, cancella solo quella
|
||
static Future<String?> _readKeySafe(String key) async {
|
||
try {
|
||
return await _storage.read(key: key);
|
||
} on PlatformException {
|
||
// solo questa chiave è corrotta → la pulisco
|
||
await _storage.delete(key: key);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// 🧼 helper: rimuove caratteri invisibili/di controllo tipici che “sporcano” gli URL
|
||
static String _sanitizeUrl(String s) {
|
||
// rimuove BOM, LRM/RLM e altri ‘format characters’ comuni negli incolla
|
||
const _invisibles = r'[\u200B-\u200F\u202A-\u202E\u2060-\u2064\uFEFF]';
|
||
final cleaned = s.replaceAll(RegExp(_invisibles), '');
|
||
return cleaned.trim();
|
||
}
|
||
|
||
static Future<RemoteSettings> load() async {
|
||
// legge *per singola chiave* con fallback ai default
|
||
final enabledStr = await _readKeySafe(_kEnabled);
|
||
final rawBase = await _readKeySafe(_kBaseUrl);
|
||
final indexPath = await _readKeySafe(_kIndexPath) ?? defaultIndexPath;
|
||
final email = await _readKeySafe(_kEmail) ?? defaultEmail;
|
||
final password = await _readKeySafe(_kPassword) ?? defaultPassword;
|
||
|
||
final enabled = (enabledStr ?? (defaultEnabled ? 'true' : 'false')) == 'true';
|
||
|
||
// sanitize della base URL (toglie caratteri non alfabetici “invisibili”)
|
||
final baseUrl = _sanitizeUrl(rawBase ?? defaultBaseUrl);
|
||
|
||
return RemoteSettings(
|
||
enabled: enabled,
|
||
baseUrl: baseUrl,
|
||
indexPath: indexPath,
|
||
email: email,
|
||
password: password,
|
||
);
|
||
}
|
||
|
||
Future<void> save() async {
|
||
// Sanitize prima di salvare, così evitiamo che restino in storage caratteri strani
|
||
await _storage.write(key: _kEnabled, value: enabled ? 'true' : 'false');
|
||
await _storage.write(key: _kBaseUrl, value: _sanitizeUrl(baseUrl));
|
||
await _storage.write(key: _kIndexPath, value: indexPath.trim());
|
||
await _storage.write(key: _kEmail, value: email.trim());
|
||
await _storage.write(key: _kPassword, value: password);
|
||
}
|
||
|
||
static Future<void> debugSeedIfEmpty() async {
|
||
if (!kDebugMode) return;
|
||
|
||
Future<void> _seed(String key, String value) async {
|
||
try {
|
||
final existing = await _storage.read(key: key);
|
||
if (existing == null) {
|
||
await _storage.write(key: key, value: value);
|
||
}
|
||
} on PlatformException {
|
||
// chiave “sporca” → reset di quella sola chiave e poi scrittura
|
||
await _storage.delete(key: key);
|
||
await _storage.write(key: key, value: value);
|
||
}
|
||
}
|
||
|
||
await _seed(_kEnabled, defaultEnabled ? 'true' : 'false');
|
||
await _seed(_kBaseUrl, defaultBaseUrl);
|
||
await _seed(_kIndexPath, defaultIndexPath);
|
||
await _seed(_kEmail, defaultEmail);
|
||
await _seed(_kPassword, defaultPassword);
|
||
}
|
||
}
|