feat: SQLCipher-Verschluesselung der pyramid.sqlite (M1) via neue Storage-Fassade app_database.dart

- AppDatabase.open()/openForPush() kapseln Factory, Schluessel (Keystore),
  Klartext->SQLCipher-Migration (Backup/Verify/atomarer Tausch) und PRAGMAs
- Android/Windows/Linux verschluesselt, iOS/macOS bewusst Klartext
- 5 neue Tests mit echter SQLCipher-DLL; Windows-Praxistest mit echter DB
  erfolgreich (23 Tabellen verifiziert, E2EE intakt); Android UNGETESTET
This commit is contained in:
Bernd Steckmeister
2026-07-06 12:31:38 +02:00
parent cead62ccb2
commit f64398d3c6
10 changed files with 787 additions and 49 deletions
+4 -30
View File
@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -7,40 +6,15 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_vodozemac/flutter_vodozemac.dart' as vod;
import 'package:matrix/encryption/utils/key_verification.dart';
import 'package:matrix/matrix.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart' as sqflite_native;
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:pyramid/core/app_database.dart';
import 'package:pyramid/core/auth_log.dart';
import 'package:pyramid/core/soft_logout_guard.dart';
import 'package:pyramid/core/voip_manager.dart';
final matrixClientProvider = FutureProvider<Client>((ref) async {
final DatabaseFactory factory;
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
// Use the native sqflite plugin — Android/iOS have system SQLite built-in,
// no .so loading required.
factory = sqflite_native.databaseFactory;
} else if (!kIsWeb) {
sqfliteFfiInit();
factory = databaseFactoryFfi;
} else {
throw UnsupportedError('Web not supported');
}
final appDir = await getApplicationSupportDirectory();
final dbPath = p.join(appDir.path, 'pyramid.sqlite');
final db = await factory.openDatabase(dbPath);
// Optimization for Windows/FFI to prevent "database is locked" errors
try {
await db.execute('PRAGMA journal_mode=WAL');
await db.execute('PRAGMA busy_timeout = 5000');
} catch (e) {
if (kDebugMode) debugPrint('Could not set PRAGMAs: $e');
}
// Factory-Wahl, Verschlüsselung (SQLCipher), Migration und PRAGMAs stecken
// komplett in der Storage-Fassade — siehe docs/SQLCIPHER_MIGRATION.md.
final db = await AppDatabase.open();
final sdkDb = await MatrixSdkDatabase.init('pyramid', database: db);