Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Fix start DM with pending third party invite #10347

Merged
merged 3 commits into from
Mar 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions src/utils/dm/findDMForUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,20 @@ import { isLocalRoom } from "../localRoom/isLocalRoom";
import { isJoinedOrNearlyJoined } from "../membership";
import { getFunctionalMembers } from "../room/getFunctionalMembers";

function extractSuitableRoom(rooms: Room[], userId: string): Room | undefined {
/**
* Iterates the rooms and tries to find a DM room with the user identified by UserId.
* A DM room is assumed if one of the following matches:
* - Has two members and contains a membership for the user identified by userId
* - findRoomWithThirdpartyInvites is true and has one member and a third pending third party invite
*
* If multiple rooms match it will return the one with the most recent event.
*
* @param rooms - Rooms to iterate
* @param userId - User Id of the other user
* @param [findRoomWithThirdpartyInvites] - Whether to find a DM for a pending thirdparty invite
* @returns DM room if found or undefined if not
*/
function extractSuitableRoom(rooms: Room[], userId: string, findRoomWithThirdpartyInvites: boolean): Room | undefined {
const suitableRooms = rooms
.filter((r) => {
// Validate that we are joined and the other person is also joined. We'll also make sure
Expand All @@ -46,7 +59,7 @@ function extractSuitableRoom(rooms: Room[], userId: string): Room | undefined {
const thirdPartyInvites = r.currentState.getStateEvents("m.room.third_party_invite") || [];

// match room with pending third-party invite
return joinedMembers.length === 1 && thirdPartyInvites.length === 1;
return findRoomWithThirdpartyInvites && joinedMembers.length === 1 && thirdPartyInvites.length === 1;
}
return false;
})
Expand All @@ -71,7 +84,10 @@ function extractSuitableRoom(rooms: Room[], userId: string): Room | undefined {
export function findDMForUser(client: MatrixClient, userId: string): Room | undefined {
const roomIdsForUserId = DMRoomMap.shared().getDMRoomsForUserId(userId);
const roomsForUserId = roomIdsForUserId.map((id) => client.getRoom(id)).filter((r): r is Room => r !== null);
const suitableRoomForUserId = extractSuitableRoom(roomsForUserId, userId);
// Call with findRoomWithThirdpartyInvites = true to also include rooms with pending thirdparty invites.
// roomsForUserId can only contain rooms with the other user here,
// because they have been queried by getDMRoomsForUserId().
const suitableRoomForUserId = extractSuitableRoom(roomsForUserId, userId, true);

if (suitableRoomForUserId) {
return suitableRoomForUserId;
justjanne marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -82,5 +98,5 @@ export function findDMForUser(client: MatrixClient, userId: string): Room | unde
const allRooms = Array.from(allRoomIds)
.map((id) => client.getRoom(id))
.filter((r): r is Room => r !== null);
return extractSuitableRoom(allRooms, userId);
return extractSuitableRoom(allRooms, userId, false);
}
8 changes: 8 additions & 0 deletions test/utils/dm/findDMForUser-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ describe("findDMForUser", () => {
return [room1.roomId, room2.roomId, room3.roomId, room4.roomId, room5.roomId, unknownRoomId];
}

if (userId === thirdPartyId) {
return [room7.roomId];
}

return [];
});
});
Expand Down Expand Up @@ -174,4 +178,8 @@ describe("findDMForUser", () => {
it("should find a room with a pending third-party invite", () => {
expect(findDMForUser(mockClient, thirdPartyId)).toBe(room7);
});

it("should not find a room for an unknown Id", () => {
expect(findDMForUser(mockClient, "@unknown:example.com")).toBe(undefined);
});
});