Merge pull request #10352 from matrix-org/backport-10347-to-staging

[Backport staging] Fix start DM with pending third party invite
This commit is contained in:
Andy Balaam 2023-03-10 15:01:42 +00:00 committed by GitHub
commit f6682b864c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 4 deletions

View file

@ -21,7 +21,20 @@ import { isLocalRoom } from "../localRoom/isLocalRoom";
import { isJoinedOrNearlyJoined } from "../membership"; import { isJoinedOrNearlyJoined } from "../membership";
import { getFunctionalMembers } from "../room/getFunctionalMembers"; 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 const suitableRooms = rooms
.filter((r) => { .filter((r) => {
// Validate that we are joined and the other person is also joined. We'll also make sure // Validate that we are joined and the other person is also joined. We'll also make sure
@ -46,7 +59,7 @@ function extractSuitableRoom(rooms: Room[], userId: string): Room | undefined {
const thirdPartyInvites = r.currentState.getStateEvents("m.room.third_party_invite") || []; const thirdPartyInvites = r.currentState.getStateEvents("m.room.third_party_invite") || [];
// match room with pending 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; return false;
}) })
@ -71,7 +84,10 @@ function extractSuitableRoom(rooms: Room[], userId: string): Room | undefined {
export function findDMForUser(client: MatrixClient, userId: string): Room | undefined { export function findDMForUser(client: MatrixClient, userId: string): Room | undefined {
const roomIdsForUserId = DMRoomMap.shared().getDMRoomsForUserId(userId); const roomIdsForUserId = DMRoomMap.shared().getDMRoomsForUserId(userId);
const roomsForUserId = roomIdsForUserId.map((id) => client.getRoom(id)).filter((r): r is Room => r !== null); 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) { if (suitableRoomForUserId) {
return suitableRoomForUserId; return suitableRoomForUserId;
@ -82,5 +98,5 @@ export function findDMForUser(client: MatrixClient, userId: string): Room | unde
const allRooms = Array.from(allRoomIds) const allRooms = Array.from(allRoomIds)
.map((id) => client.getRoom(id)) .map((id) => client.getRoom(id))
.filter((r): r is Room => r !== null); .filter((r): r is Room => r !== null);
return extractSuitableRoom(allRooms, userId); return extractSuitableRoom(allRooms, userId, false);
} }

View file

@ -135,6 +135,10 @@ describe("findDMForUser", () => {
return [room1.roomId, room2.roomId, room3.roomId, room4.roomId, room5.roomId, unknownRoomId]; return [room1.roomId, room2.roomId, room3.roomId, room4.roomId, room5.roomId, unknownRoomId];
} }
if (userId === thirdPartyId) {
return [room7.roomId];
}
return []; return [];
}); });
}); });
@ -174,4 +178,8 @@ describe("findDMForUser", () => {
it("should find a room with a pending third-party invite", () => { it("should find a room with a pending third-party invite", () => {
expect(findDMForUser(mockClient, thirdPartyId)).toBe(room7); expect(findDMForUser(mockClient, thirdPartyId)).toBe(room7);
}); });
it("should not find a room for an unknown Id", () => {
expect(findDMForUser(mockClient, "@unknown:example.com")).toBe(undefined);
});
}); });