Merge branch 'krille/create-rooms-methods' into 'main'
feat: More advanced create chat methods See merge request famedly/company/frontend/famedlysdk!877
This commit is contained in:
commit
b350d5ab5b
|
|
@ -556,24 +556,102 @@ class Client extends MatrixApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an existing direct room ID with this user or creates a new one.
|
/// Returns an existing direct room ID with this user or creates a new one.
|
||||||
/// Returns null on error.
|
/// By default encryption will be enabled if the client supports encryption
|
||||||
Future<String> startDirectChat(String mxid) async {
|
/// and the other user has uploaded any encryption keys.
|
||||||
|
Future<String> startDirectChat(
|
||||||
|
String mxid, {
|
||||||
|
bool? enableEncryption,
|
||||||
|
List<StateEvent>? initialState,
|
||||||
|
bool waitForSync = true,
|
||||||
|
}) async {
|
||||||
// Try to find an existing direct chat
|
// Try to find an existing direct chat
|
||||||
var roomId = getDirectChatFromUserId(mxid);
|
final directChatRoomId = getDirectChatFromUserId(mxid);
|
||||||
if (roomId != null) return roomId;
|
if (directChatRoomId != null) return directChatRoomId;
|
||||||
|
|
||||||
|
enableEncryption ??= await userOwnsEncryptionKeys(mxid);
|
||||||
|
if (enableEncryption) {
|
||||||
|
initialState ??= [];
|
||||||
|
if (!initialState.any((s) => s.type == EventTypes.Encryption)) {
|
||||||
|
initialState.add(StateEvent(
|
||||||
|
content: {
|
||||||
|
'algorithm': supportedGroupEncryptionAlgorithms.first,
|
||||||
|
},
|
||||||
|
type: EventTypes.Encryption,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Start a new direct chat
|
// Start a new direct chat
|
||||||
roomId = await createRoom(
|
final roomId = await createRoom(
|
||||||
invite: [mxid],
|
invite: [mxid],
|
||||||
isDirect: true,
|
isDirect: true,
|
||||||
preset: CreateRoomPreset.trustedPrivateChat,
|
preset: CreateRoomPreset.trustedPrivateChat,
|
||||||
|
initialState: initialState,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (waitForSync && getRoomById(roomId) == null) {
|
||||||
|
// Wait for room actually appears in sync
|
||||||
|
await onSync.stream
|
||||||
|
.firstWhere((sync) => sync.rooms?.join?.containsKey(roomId) ?? false);
|
||||||
|
}
|
||||||
|
|
||||||
await Room(id: roomId, client: this).addToDirectChat(mxid);
|
await Room(id: roomId, client: this).addToDirectChat(mxid);
|
||||||
|
|
||||||
return roomId;
|
return roomId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Simplified method to create a new group chat. By default it is a private
|
||||||
|
/// chat. The encryption is enabled if this client supports encryption and
|
||||||
|
/// the preset is not a public chat.
|
||||||
|
Future<String> createGroupChat({
|
||||||
|
String? groupName,
|
||||||
|
bool? enableEncryption,
|
||||||
|
List<String>? invite,
|
||||||
|
CreateRoomPreset preset = CreateRoomPreset.privateChat,
|
||||||
|
List<StateEvent>? initialState,
|
||||||
|
bool waitForSync = true,
|
||||||
|
}) async {
|
||||||
|
enableEncryption ??=
|
||||||
|
encryptionEnabled && preset != CreateRoomPreset.publicChat;
|
||||||
|
if (enableEncryption) {
|
||||||
|
initialState ??= [];
|
||||||
|
if (!initialState.any((s) => s.type == EventTypes.Encryption)) {
|
||||||
|
initialState.add(StateEvent(
|
||||||
|
content: {
|
||||||
|
'algorithm': supportedGroupEncryptionAlgorithms.first,
|
||||||
|
},
|
||||||
|
type: EventTypes.Encryption,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final roomId = await createRoom(
|
||||||
|
invite: invite,
|
||||||
|
preset: preset,
|
||||||
|
name: groupName,
|
||||||
|
initialState: initialState,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (waitForSync) {
|
||||||
|
if (getRoomById(roomId) == null) {
|
||||||
|
// Wait for room actually appears in sync
|
||||||
|
await onSync.stream.firstWhere(
|
||||||
|
(sync) => sync.rooms?.join?.containsKey(roomId) ?? false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return roomId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks if the given user has encryption keys. May query keys from the
|
||||||
|
/// server to answer this.
|
||||||
|
Future<bool> userOwnsEncryptionKeys(String userId) async {
|
||||||
|
if (userId == userID) return encryptionEnabled;
|
||||||
|
if (_userDeviceKeys.containsKey(userId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
final keys = await queryKeys({userId: []});
|
||||||
|
return keys.deviceKeys?.isNotEmpty ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new space and returns the Room ID. The parameters are mostly
|
/// Creates a new space and returns the Room ID. The parameters are mostly
|
||||||
/// the same like in [createRoom()].
|
/// the same like in [createRoom()].
|
||||||
/// Be aware that spaces appear in the [rooms] list. You should check if a
|
/// Be aware that spaces appear in the [rooms] list. You should check if a
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,17 @@ class User extends Event {
|
||||||
|
|
||||||
/// Returns an existing direct chat ID with this user or creates a new one.
|
/// Returns an existing direct chat ID with this user or creates a new one.
|
||||||
/// Returns null on error.
|
/// Returns null on error.
|
||||||
Future<String> startDirectChat() async => room.client.startDirectChat(id);
|
Future<String> startDirectChat({
|
||||||
|
bool? enableEncryption,
|
||||||
|
List<StateEvent>? initialState,
|
||||||
|
bool waitForSync = true,
|
||||||
|
}) async =>
|
||||||
|
room.client.startDirectChat(
|
||||||
|
id,
|
||||||
|
enableEncryption: enableEncryption,
|
||||||
|
initialState: initialState,
|
||||||
|
waitForSync: waitForSync,
|
||||||
|
);
|
||||||
|
|
||||||
/// The newest presence of this user if there is any and null if not.
|
/// The newest presence of this user if there is any and null if not.
|
||||||
Presence? get presence => room.client.presences[id];
|
Presence? get presence => room.client.presences[id];
|
||||||
|
|
|
||||||
|
|
@ -67,14 +67,25 @@ class DeviceKeysList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<KeyVerification> startVerification() async {
|
/// Starts a verification with this device. This might need to create a new
|
||||||
|
/// direct chat to send the verification request over this room. For this you
|
||||||
|
/// can set parameters here.
|
||||||
|
Future<KeyVerification> startVerification({
|
||||||
|
bool? newDirectChatEnableEncryption,
|
||||||
|
List<StateEvent>? newDirectChatInitialState,
|
||||||
|
}) async {
|
||||||
final encryption = client.encryption;
|
final encryption = client.encryption;
|
||||||
if (encryption == null) {
|
if (encryption == null) {
|
||||||
throw Exception('Encryption not enabled');
|
throw Exception('Encryption not enabled');
|
||||||
}
|
}
|
||||||
if (userId != client.userID) {
|
if (userId != client.userID) {
|
||||||
// in-room verification with someone else
|
// in-room verification with someone else
|
||||||
final roomId = await client.startDirectChat(userId);
|
final roomId = await client.startDirectChat(
|
||||||
|
userId,
|
||||||
|
enableEncryption: newDirectChatEnableEncryption,
|
||||||
|
initialState: newDirectChatInitialState,
|
||||||
|
waitForSync: false,
|
||||||
|
);
|
||||||
|
|
||||||
final room =
|
final room =
|
||||||
client.getRoomById(roomId) ?? Room(id: roomId, client: client);
|
client.getRoomById(roomId) ?? Room(id: roomId, client: client);
|
||||||
|
|
|
||||||
|
|
@ -560,6 +560,12 @@ void main() {
|
||||||
bunnyContent);
|
bunnyContent);
|
||||||
await client.dispose(closeDatabase: true);
|
await client.dispose(closeDatabase: true);
|
||||||
});
|
});
|
||||||
|
test('startDirectChat', () async {
|
||||||
|
await matrix.startDirectChat('@alice:example.com', waitForSync: false);
|
||||||
|
});
|
||||||
|
test('createGroupChat', () async {
|
||||||
|
await matrix.createGroupChat(groupName: 'Testgroup', waitForSync: false);
|
||||||
|
});
|
||||||
test('Test the fake store api', () async {
|
test('Test the fake store api', () async {
|
||||||
final database = await getDatabase(null);
|
final database = await getDatabase(null);
|
||||||
final client1 = Client(
|
final client1 = Client(
|
||||||
|
|
|
||||||
|
|
@ -252,7 +252,7 @@ void main() {
|
||||||
expect(req?.room != null, false);
|
expect(req?.room != null, false);
|
||||||
|
|
||||||
req = await client.userDeviceKeys['@alice:example.com']
|
req = await client.userDeviceKeys['@alice:example.com']
|
||||||
?.startVerification();
|
?.startVerification(newDirectChatEnableEncryption: false);
|
||||||
expect(req != null, true);
|
expect(req != null, true);
|
||||||
expect(req?.room != null, true);
|
expect(req?.room != null, true);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,9 @@ void main() {
|
||||||
client1.userDeviceKeys[client1.userID]!.masterKey!
|
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||||
.setDirectVerified(false);
|
.setDirectVerified(false);
|
||||||
final req1 =
|
final req1 =
|
||||||
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
await client1.userDeviceKeys[client2.userID]!.startVerification(
|
||||||
|
newDirectChatEnableEncryption: false,
|
||||||
|
);
|
||||||
var evt = getLastSentEvent(req1);
|
var evt = getLastSentEvent(req1);
|
||||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||||
|
|
||||||
|
|
@ -221,8 +223,8 @@ void main() {
|
||||||
client1.userDeviceKeys[client1.userID]!.masterKey!
|
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||||
.setDirectVerified(true);
|
.setDirectVerified(true);
|
||||||
await client1.encryption!.ssss.clearCache();
|
await client1.encryption!.ssss.clearCache();
|
||||||
final req1 =
|
final req1 = await client1.userDeviceKeys[client2.userID]!
|
||||||
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
.startVerification(newDirectChatEnableEncryption: false);
|
||||||
expect(req1.state, KeyVerificationState.askSSSS);
|
expect(req1.state, KeyVerificationState.askSSSS);
|
||||||
await req1.openSSSS(recoveryKey: ssssKey);
|
await req1.openSSSS(recoveryKey: ssssKey);
|
||||||
await Future.delayed(Duration(seconds: 1));
|
await Future.delayed(Duration(seconds: 1));
|
||||||
|
|
@ -241,8 +243,8 @@ void main() {
|
||||||
// the other one has to have their master key verified to trigger asking for ssss
|
// the other one has to have their master key verified to trigger asking for ssss
|
||||||
client2.userDeviceKeys[client2.userID]!.masterKey!
|
client2.userDeviceKeys[client2.userID]!.masterKey!
|
||||||
.setDirectVerified(true);
|
.setDirectVerified(true);
|
||||||
final req1 =
|
final req1 = await client1.userDeviceKeys[client2.userID]!
|
||||||
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
.startVerification(newDirectChatEnableEncryption: false);
|
||||||
var evt = getLastSentEvent(req1);
|
var evt = getLastSentEvent(req1);
|
||||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||||
|
|
||||||
|
|
@ -345,8 +347,8 @@ void main() {
|
||||||
// make sure our master key is *not* verified to not triger SSSS for now
|
// make sure our master key is *not* verified to not triger SSSS for now
|
||||||
client1.userDeviceKeys[client1.userID]!.masterKey!
|
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||||
.setDirectVerified(false);
|
.setDirectVerified(false);
|
||||||
final req1 =
|
final req1 = await client1.userDeviceKeys[client2.userID]!
|
||||||
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
.startVerification(newDirectChatEnableEncryption: false);
|
||||||
var evt = getLastSentEvent(req1);
|
var evt = getLastSentEvent(req1);
|
||||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||||
|
|
||||||
|
|
@ -375,8 +377,8 @@ void main() {
|
||||||
// make sure our master key is *not* verified to not triger SSSS for now
|
// make sure our master key is *not* verified to not triger SSSS for now
|
||||||
client1.userDeviceKeys[client1.userID]!.masterKey!
|
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||||
.setDirectVerified(false);
|
.setDirectVerified(false);
|
||||||
final req1 =
|
final req1 = await client1.userDeviceKeys[client2.userID]!
|
||||||
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
.startVerification(newDirectChatEnableEncryption: false);
|
||||||
var evt = getLastSentEvent(req1);
|
var evt = getLastSentEvent(req1);
|
||||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||||
|
|
||||||
|
|
@ -436,8 +438,8 @@ void main() {
|
||||||
// make sure our master key is *not* verified to not triger SSSS for now
|
// make sure our master key is *not* verified to not triger SSSS for now
|
||||||
client1.userDeviceKeys[client1.userID]!.masterKey!
|
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||||
.setDirectVerified(false);
|
.setDirectVerified(false);
|
||||||
final req1 =
|
final req1 = await client1.userDeviceKeys[client2.userID]!
|
||||||
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
.startVerification(newDirectChatEnableEncryption: false);
|
||||||
final evt = getLastSentEvent(req1);
|
final evt = getLastSentEvent(req1);
|
||||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ void main() {
|
||||||
await user1.setPower(50);
|
await user1.setPower(50);
|
||||||
});
|
});
|
||||||
test('startDirectChat', () async {
|
test('startDirectChat', () async {
|
||||||
await user1.startDirectChat();
|
await user1.startDirectChat(waitForSync: false);
|
||||||
});
|
});
|
||||||
test('getPresence', () async {
|
test('getPresence', () async {
|
||||||
await client.handleSync(SyncUpdate.fromJson({
|
await client.handleSync(SyncUpdate.fromJson({
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue