Files
PeachDeployments/lib/Peach/memory/ConfigStore.dart
alvocool 38881d1fe1 Add app source and tests
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 10:15:30 +03:00

53 lines
1.7 KiB
Dart

import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import '../about/internal/application/ServerProfile.dart';
import 'SecretStore.dart';
/// Persists server profiles (with their nested services) locally. Non-secret
/// data goes to shared_preferences; passwords go to encrypted [SecretStore].
class ConfigStore {
static const _key = 'peach.servers.v2';
/// The key used before the app was renamed. Read once and migrated forward,
/// so an existing install keeps its servers.
static const _legacyKey = 'jarpilot.servers.v2';
final _secrets = SecretStore();
Future<List<ServerProfile>> load() async {
final prefs = await SharedPreferences.getInstance();
var raw = prefs.getString(_key);
if (raw == null || raw.isEmpty) {
raw = prefs.getString(_legacyKey);
if (raw != null && raw.isNotEmpty) {
await prefs.setString(_key, raw);
await prefs.remove(_legacyKey);
}
}
if (raw == null || raw.isEmpty) return [];
final list = jsonDecode(raw) as List<dynamic>;
final servers = list
.map((e) => ServerProfile.fromJson(e as Map<String, dynamic>))
.toList();
// Hydrate passwords from encrypted storage.
for (final s in servers) {
s.password = await _secrets.readPassword(s.id) ?? '';
}
return servers;
}
Future<void> save(List<ServerProfile> servers) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(
_key,
jsonEncode(servers.map((s) => s.toJson()).toList()),
);
for (final s in servers) {
await _secrets.writePassword(s.id, s.password);
}
}
Future<void> deleteSecret(String serverId) =>
_secrets.deletePassword(serverId);
}