164 lines
5.3 KiB
Dart
164 lines
5.3 KiB
Dart
// 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 }
|