feat: Try out FluffyBox 2 database

This commit is contained in:
Krille 2023-11-22 07:51:16 +01:00
commit 129c1ab697
No known key found for this signature in database
9 changed files with 135 additions and 15 deletions

View file

@ -10,6 +10,7 @@ import 'package:fluffychat/utils/custom_http_client.dart';
import 'package:fluffychat/utils/custom_image_resizer.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'matrix_sdk_extensions/flutter_matrix_sdk_database_builder.dart';
abstract class ClientManager {
static const String clientNamespace = 'im.fluffychat.store.clients';
@ -102,7 +103,8 @@ abstract class ClientManager {
EventTypes.RoomPowerLevels,
},
logLevel: kReleaseMode ? Level.warning : Level.verbose,
databaseBuilder: FlutterHiveCollectionsDatabase.databaseBuilder,
databaseBuilder: flutterMatrixSdkDatabaseBuilder,
legacyDatabaseBuilder: FlutterHiveCollectionsDatabase.databaseBuilder,
supportedLoginTypes: {
AuthenticationTypes.password,
AuthenticationTypes.sso,

View file

@ -64,7 +64,7 @@ class FlutterHiveCollectionsDatabase extends HiveCollectionsDatabase {
final db = FlutterHiveCollectionsDatabase(
'hive_collections_${client.clientName.replaceAll(' ', '_').toLowerCase()}',
await _findDatabasePath(client),
await findDatabasePath(client),
key: hiverCipher,
);
try {
@ -80,7 +80,7 @@ class FlutterHiveCollectionsDatabase extends HiveCollectionsDatabase {
return db;
}
static Future<String> _findDatabasePath(Client client) async {
static Future<String> findDatabasePath(Client client) async {
String path = client.clientName;
if (!kIsWeb) {
Directory directory;

View file

@ -0,0 +1,86 @@
import 'dart:convert';
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:matrix/matrix.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart' as ffi;
import 'package:sqflite_sqlcipher/sqflite.dart';
import 'package:universal_html/html.dart' as html;
import 'package:fluffychat/utils/platform_infos.dart';
Future<MatrixSdkDatabase> flutterMatrixSdkDatabaseBuilder(Client client) async {
final database = await _constructDatabase(client);
await database.open();
return database;
}
Future<MatrixSdkDatabase> _constructDatabase(Client client) async {
if (kIsWeb) {
html.window.navigator.storage?.persist();
return MatrixSdkDatabase(client.clientName);
}
if (PlatformInfos.isDesktop) {
final path = await getApplicationSupportDirectory();
return MatrixSdkDatabase(
client.clientName,
database: await ffi.databaseFactoryFfi.openDatabase(
'$path/${client.clientName}',
),
maxFileSize: 1024 * 1024 * 10,
fileStoragePath: path,
deleteFilesAfterDuration: const Duration(days: 30),
);
}
final path = await getDatabasesPath();
const passwordStorageKey = 'database_password';
String? password;
try {
// Workaround for secure storage is calling Platform.operatingSystem on web
if (kIsWeb) throw MissingPluginException();
const secureStorage = FlutterSecureStorage();
final containsEncryptionKey =
await secureStorage.read(key: passwordStorageKey) != null;
if (!containsEncryptionKey) {
final rng = Random.secure();
final list = Uint8List(32);
list.setAll(0, Iterable.generate(list.length, (i) => rng.nextInt(256)));
final newPassword = base64UrlEncode(list);
await secureStorage.write(
key: passwordStorageKey,
value: newPassword,
);
}
// workaround for if we just wrote to the key and it still doesn't exist
password = await secureStorage.read(key: passwordStorageKey);
if (password == null) throw MissingPluginException();
} on MissingPluginException catch (_) {
const FlutterSecureStorage()
.delete(key: passwordStorageKey)
.catchError((_) {});
Logs().i('Database encryption is not supported on this platform');
} catch (e, s) {
const FlutterSecureStorage()
.delete(key: passwordStorageKey)
.catchError((_) {});
Logs().w('Unable to init database encryption', e, s);
}
return MatrixSdkDatabase(
client.clientName,
database: await openDatabase(
'$path/${client.clientName}',
password: password,
),
maxFileSize: 1024 * 1024 * 10,
fileStoragePath: await getTemporaryDirectory(),
deleteFilesAfterDuration: const Duration(days: 30),
);
}