134 lines
3.5 KiB
Dart
134 lines
3.5 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'package:crypto/crypto.dart';
|
|
import 'package:path/path.dart' as path;
|
|
|
|
const defaultEndpoint = 'http://localhost:7700';
|
|
const defaultApiKey = 'masterKey';
|
|
|
|
// Cache for configuration
|
|
String? _cachedEndpoint;
|
|
String? _cachedApiKey;
|
|
bool _isInitialized = false;
|
|
|
|
// Get the config file path in the user's home directory
|
|
Future<String> _getConfigPath() async {
|
|
final home =
|
|
Platform.environment['HOME'] ?? Platform.environment['USERPROFILE'];
|
|
if (home == null) {
|
|
throw Exception('Could not find home directory');
|
|
}
|
|
final configDir = Directory(path.join(home, '.journaler'));
|
|
if (!await configDir.exists()) {
|
|
await configDir.create(recursive: true);
|
|
}
|
|
return path.join(configDir.path, 'meilisearch_config.enc');
|
|
}
|
|
|
|
// Simple encryption key derived from machine-specific data
|
|
String _getEncryptionKey() {
|
|
final machineId =
|
|
Platform.operatingSystem +
|
|
Platform.operatingSystemVersion +
|
|
Platform.localHostname;
|
|
return sha256.convert(utf8.encode(machineId)).toString();
|
|
}
|
|
|
|
// Encrypt data
|
|
String _encrypt(String data) {
|
|
final key = _getEncryptionKey();
|
|
final bytes = utf8.encode(data);
|
|
final encrypted = <int>[];
|
|
for (var i = 0; i < bytes.length; i++) {
|
|
encrypted.add(bytes[i] ^ key.codeUnitAt(i % key.length));
|
|
}
|
|
return base64.encode(encrypted);
|
|
}
|
|
|
|
// Decrypt data
|
|
String _decrypt(String encrypted) {
|
|
final key = _getEncryptionKey();
|
|
final bytes = base64.decode(encrypted);
|
|
final decrypted = <int>[];
|
|
for (var i = 0; i < bytes.length; i++) {
|
|
decrypted.add(bytes[i] ^ key.codeUnitAt(i % key.length));
|
|
}
|
|
return utf8.decode(decrypted);
|
|
}
|
|
|
|
// Initialize cache from file
|
|
Future<void> _initializeCache() async {
|
|
if (_isInitialized) return;
|
|
|
|
try {
|
|
final configPath = await _getConfigPath();
|
|
final file = File(configPath);
|
|
if (!await file.exists()) {
|
|
_cachedEndpoint = defaultEndpoint;
|
|
_cachedApiKey = defaultApiKey;
|
|
_isInitialized = true;
|
|
return;
|
|
}
|
|
|
|
final encrypted = await file.readAsString();
|
|
final decrypted = _decrypt(encrypted);
|
|
final config = jsonDecode(decrypted);
|
|
|
|
_cachedEndpoint = config['endpoint'] ?? defaultEndpoint;
|
|
_cachedApiKey = config['apiKey'] ?? defaultApiKey;
|
|
} catch (e) {
|
|
_cachedEndpoint = defaultEndpoint;
|
|
_cachedApiKey = defaultApiKey;
|
|
}
|
|
|
|
_isInitialized = true;
|
|
}
|
|
|
|
Future<String> getMeilisearchEndpoint() async {
|
|
await _initializeCache();
|
|
return _cachedEndpoint!;
|
|
}
|
|
|
|
Future<String> getMeilisearchApiKey() async {
|
|
await _initializeCache();
|
|
return _cachedApiKey!;
|
|
}
|
|
|
|
Future<void> setMeilisearchEndpoint(String endpoint) async {
|
|
final configPath = await _getConfigPath();
|
|
final file = File(configPath);
|
|
|
|
Map<String, dynamic> config = {};
|
|
if (await file.exists()) {
|
|
final encrypted = await file.readAsString();
|
|
final decrypted = _decrypt(encrypted);
|
|
config = jsonDecode(decrypted);
|
|
}
|
|
|
|
config['endpoint'] = endpoint;
|
|
final encrypted = _encrypt(jsonEncode(config));
|
|
await file.writeAsString(encrypted);
|
|
|
|
// Update cache
|
|
_cachedEndpoint = endpoint;
|
|
}
|
|
|
|
Future<void> setMeilisearchApiKey(String apiKey) async {
|
|
final configPath = await _getConfigPath();
|
|
final file = File(configPath);
|
|
|
|
Map<String, dynamic> config = {};
|
|
if (await file.exists()) {
|
|
final encrypted = await file.readAsString();
|
|
final decrypted = _decrypt(encrypted);
|
|
config = jsonDecode(decrypted);
|
|
}
|
|
|
|
config['apiKey'] = apiKey;
|
|
final encrypted = _encrypt(jsonEncode(config));
|
|
await file.writeAsString(encrypted);
|
|
|
|
// Update cache
|
|
_cachedApiKey = apiKey;
|
|
}
|