Initial commit
This commit is contained in:
163
lib/pages/chat/trust_user_key_dialog.dart
Normal file
163
lib/pages/chat/trust_user_key_dialog.dart
Normal file
@@ -0,0 +1,163 @@
|
||||
// SPDX-FileCopyrightText: 2019-Present Christian Kußowski
|
||||
// SPDX-FileCopyrightText: 2019-Present Contributors to FluffyChat
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import 'package:tatchat/l10n/l10n.dart';
|
||||
import 'package:tatchat/pages/key_verification/key_verification_dialog.dart';
|
||||
import 'package:tatchat/utils/beautify_string_extension.dart';
|
||||
import 'package:tatchat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
|
||||
import 'package:tatchat/widgets/adaptive_dialogs/dialog_text_field.dart';
|
||||
import 'package:tatchat/widgets/avatar.dart';
|
||||
import 'package:material_ui/material_ui.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
Future<bool> showTrustUserInRoomDialog(BuildContext context, Room room) async {
|
||||
if (!room.encrypted) return true;
|
||||
|
||||
final users = await room.requestParticipants();
|
||||
if (!context.mounted) return false;
|
||||
|
||||
users.removeWhere((user) {
|
||||
if (user.id == room.client.userID) return true;
|
||||
final keys = room.client.userDeviceKeys[user.id];
|
||||
final masterKey = keys?.masterKey;
|
||||
|
||||
if (keys == null ||
|
||||
masterKey == null ||
|
||||
masterKey.verified ||
|
||||
masterKey.trustOnFirstUseSince != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (users.isEmpty) return true;
|
||||
|
||||
final l10n = L10n.of(context);
|
||||
final theme = Theme.of(context);
|
||||
|
||||
final action = await showAdaptiveDialog<_Action>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog.adaptive(
|
||||
title: Center(
|
||||
child: Icon(
|
||||
Icons.lock_outlined,
|
||||
size: 32,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
content: ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: 128),
|
||||
child: SelectionArea(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: .stretch,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
Center(
|
||||
child: Text(
|
||||
users.length == 1
|
||||
? l10n.messageCanOnlyBeReadByUser
|
||||
: l10n.messageCanOnlyBeReadByUsers,
|
||||
style: TextStyle(fontSize: 16),
|
||||
textAlign: .center,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
for (final user in users) ...[
|
||||
Row(
|
||||
children: [
|
||||
Avatar(
|
||||
name: user.calcDisplayname(),
|
||||
mxContent: user.avatarUrl,
|
||||
size: 14,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Expanded(
|
||||
child: Text(
|
||||
user.calcDisplayname(),
|
||||
style: theme.textTheme.labelSmall,
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.start,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Builder(
|
||||
builder: (context) {
|
||||
final controller = TextEditingController(
|
||||
text: l10n.publicKey(
|
||||
room
|
||||
.client
|
||||
.userDeviceKeys[user.id]
|
||||
?.masterKey
|
||||
?.publicKey
|
||||
?.beautifiedOneLine ??
|
||||
'???',
|
||||
),
|
||||
);
|
||||
return DialogTextField(
|
||||
controller: controller,
|
||||
textStyle: theme.textTheme.labelSmall,
|
||||
readOnly: true,
|
||||
maxLines: 3,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
AdaptiveDialogAction(
|
||||
autofocus: true,
|
||||
bigButtons: true,
|
||||
onPressed: () {
|
||||
for (final user in users) {
|
||||
room.client.userDeviceKeys[user.id]?.masterKey?.trustOnFirstUse();
|
||||
}
|
||||
Navigator.of(context).pop(_Action.allow);
|
||||
},
|
||||
child: Text(L10n.of(context).continueText),
|
||||
),
|
||||
if (room.isDirectChat)
|
||||
AdaptiveDialogAction(
|
||||
bigButtons: true,
|
||||
onPressed: () => Navigator.of(context).pop(_Action.verification),
|
||||
child: Text(L10n.of(context).interactiveVerification),
|
||||
),
|
||||
AdaptiveDialogAction(
|
||||
bigButtons: true,
|
||||
onPressed: () => Navigator.of(context).pop(_Action.deny),
|
||||
child: Text(l10n.cancel),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
if (action == null) return false;
|
||||
|
||||
switch (action) {
|
||||
case _Action.allow:
|
||||
for (final user in users) {
|
||||
room.client.userDeviceKeys[user.id]?.masterKey?.trustOnFirstUse();
|
||||
}
|
||||
case _Action.deny:
|
||||
return false;
|
||||
case _Action.verification:
|
||||
final req = await room.client.userDeviceKeys[room.directChatMatrixID]
|
||||
?.startVerification();
|
||||
if (req == null) return false;
|
||||
if (!context.mounted) return false;
|
||||
final success = await KeyVerificationDialog(request: req).show(context);
|
||||
return success == true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
enum _Action { allow, deny, verification }
|
||||
Reference in New Issue
Block a user