feat: Logout-Warnung bei fehlendem Key-Backup (M1)
Beide Logout-Bestätigungsdialoge prüfen jetzt vorab per neuem isKeyBackupMissing(client) (bootstrap_dialog.dart), ob Cross-Signing/ Key-Backup eingerichtet ist. Fehlt es, zeigt der Dialog eine Klartext-Warnung: alte verschlüsselte Nachrichten wären nach dem Logout auf keinem Gerät mehr lesbar. Ohne fehlendes Backup bleibt der bisherige Text unverändert.
This commit is contained in:
@@ -3,6 +3,15 @@ import 'package:matrix/encryption.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:pyramid/core/theme.dart';
|
||||
|
||||
/// Ob Cross-Signing/Key-Backup fehlt oder nicht entsperrt ist — wenn ja, würde
|
||||
/// ein Logout den Zugriff auf ältere verschlüsselte Nachrichten kosten.
|
||||
Future<bool> isKeyBackupMissing(Client client) async {
|
||||
final enc = client.encryption;
|
||||
if (enc == null) return true;
|
||||
if (!enc.crossSigning.enabled) return true;
|
||||
return !(await enc.keyManager.isCached().catchError((_) => false));
|
||||
}
|
||||
|
||||
Future<void> showBootstrapDialog(
|
||||
BuildContext context,
|
||||
Client client, {
|
||||
|
||||
@@ -23,6 +23,7 @@ import 'package:pointycastle/export.dart' as pc;
|
||||
import 'package:pyramid/core/app_state.dart';
|
||||
import 'package:pyramid/core/auth_log.dart';
|
||||
import 'package:pyramid/core/e2ee_diagnostics.dart';
|
||||
import 'package:pyramid/features/auth/bootstrap_dialog.dart' show isKeyBackupMissing;
|
||||
import 'package:pyramid/core/livekit_call_manager.dart';
|
||||
import 'package:pyramid/core/matrix_client.dart';
|
||||
import 'package:pyramid/core/voip_manager.dart';
|
||||
@@ -567,6 +568,9 @@ class _LogoutNavButtonState extends ConsumerState<_LogoutNavButton> {
|
||||
|
||||
Future<void> _logout() async {
|
||||
final pt = widget.pt;
|
||||
final client = await ref.read(matrixClientProvider.future);
|
||||
final backupMissing = await isKeyBackupMissing(client);
|
||||
if (!mounted) return;
|
||||
final confirmed = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
@@ -575,8 +579,14 @@ class _LogoutNavButtonState extends ConsumerState<_LogoutNavButton> {
|
||||
borderRadius: BorderRadius.circular(pt.rXl), side: BorderSide(color: pt.border)),
|
||||
title: Text('Abmelden?',
|
||||
style: TextStyle(color: pt.fg, fontSize: 16, fontWeight: FontWeight.w700)),
|
||||
content: Text('Du wirst von diesem Gerät abgemeldet.',
|
||||
style: TextStyle(color: pt.fgMuted, fontSize: 13)),
|
||||
content: Text(
|
||||
backupMissing
|
||||
? 'Du wirst von diesem Gerät abgemeldet. Es ist kein Schlüssel-Backup eingerichtet — '
|
||||
'ältere verschlüsselte Nachrichten sind danach auf keinem Gerät mehr lesbar.'
|
||||
: 'Du wirst von diesem Gerät abgemeldet.',
|
||||
style: TextStyle(
|
||||
color: backupMissing ? pt.danger : pt.fgMuted, fontSize: 13, height: 1.4),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(ctx, false),
|
||||
@@ -596,7 +606,6 @@ class _LogoutNavButtonState extends ConsumerState<_LogoutNavButton> {
|
||||
setState(() => _loading = true);
|
||||
try {
|
||||
widget.onClose();
|
||||
final client = await ref.read(matrixClientProvider.future);
|
||||
unawaited(AuthLog.write('User-initiated logout (Settings-Sidebar)'));
|
||||
await client.logout();
|
||||
} catch (_) {}
|
||||
@@ -5108,6 +5117,9 @@ class _AboutSection extends ConsumerWidget {
|
||||
}
|
||||
|
||||
Future<void> _confirmLogout(BuildContext context, WidgetRef ref) async {
|
||||
final client = await ref.read(matrixClientProvider.future);
|
||||
final backupMissing = await isKeyBackupMissing(client);
|
||||
if (!context.mounted) return;
|
||||
final confirm = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
@@ -5118,8 +5130,12 @@ class _AboutSection extends ConsumerWidget {
|
||||
title: Text('Abmelden?',
|
||||
style: TextStyle(color: pt.fg, fontSize: 16, fontWeight: FontWeight.w700)),
|
||||
content: Text(
|
||||
'Du wirst auf diesem Gerät abgemeldet. Deine Nachrichten bleiben erhalten.',
|
||||
style: TextStyle(color: pt.fgMuted, fontSize: 13),
|
||||
backupMissing
|
||||
? 'Du wirst auf diesem Gerät abgemeldet. Es ist kein Schlüssel-Backup eingerichtet — '
|
||||
'ältere verschlüsselte Nachrichten sind danach auf keinem Gerät mehr lesbar.'
|
||||
: 'Du wirst auf diesem Gerät abgemeldet. Deine Nachrichten bleiben erhalten.',
|
||||
style: TextStyle(
|
||||
color: backupMissing ? pt.danger : pt.fgMuted, fontSize: 13, height: 1.4),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
@@ -5139,7 +5155,6 @@ class _AboutSection extends ConsumerWidget {
|
||||
),
|
||||
);
|
||||
if (confirm == true) {
|
||||
final client = await ref.read(matrixClientProvider.future);
|
||||
unawaited(AuthLog.write('User-initiated logout (Settings)'));
|
||||
await client.logout().catchError((_) {});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user