Skip to content

Commit

Permalink
Fix a case where joinRoom creates a duplicate Room object (#3747)
Browse files Browse the repository at this point in the history
When calling MatrixClient.joinRoom with a room alias, the method would create a new Room object, even if you were already present in that room. This changes its behavior to no-op, as the doc comment promises.
  • Loading branch information
robintown committed Sep 25, 2023
1 parent d29b852 commit 8f90159
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 5 deletions.
28 changes: 26 additions & 2 deletions spec/integ/matrix-client-methods.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ describe("MatrixClient", function () {
});

describe("joinRoom", function () {
it("should no-op if you've already joined a room", function () {
it("should no-op given the ID of a room you've already joined", async () => {
const roomId = "!foo:bar";
const room = new Room(roomId, client, userId);
client.fetchRoomEvent = () =>
Expand All @@ -168,8 +168,32 @@ describe("MatrixClient", function () {
]);
httpBackend.verifyNoOutstandingRequests();
store.storeRoom(room);
client.joinRoom(roomId);

const joinPromise = client.joinRoom(roomId);
httpBackend.verifyNoOutstandingRequests();
expect(await joinPromise).toBe(room);
});

it("should no-op given the alias of a room you've already joined", async () => {
const roomId = "!roomId:server";
const roomAlias = "#my-fancy-room:server";
const room = new Room(roomId, client, userId);
room.addLiveEvents([
utils.mkMembership({
user: userId,
room: roomId,
mship: "join",
event: true,
}),
]);
store.storeRoom(room);

// The method makes a request to resolve the alias
httpBackend.when("POST", "/join/" + encodeURIComponent(roomAlias)).respond(200, { room_id: roomId });

const joinPromise = client.joinRoom(roomAlias);
await httpBackend.flushAllExpected();
expect(await joinPromise).toBe(room);
});

it("should send request to inviteSignUrl if specified", async () => {
Expand Down
10 changes: 7 additions & 3 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4187,9 +4187,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
}

const room = this.getRoom(roomIdOrAlias);
if (room?.hasMembershipState(this.credentials.userId!, "join")) {
return Promise.resolve(room);
}
if (room?.hasMembershipState(this.credentials.userId!, "join")) return room;

let signPromise: Promise<IThirdPartySigned | void> = Promise.resolve();

Expand All @@ -4214,6 +4212,12 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
const res = await this.http.authedRequest<{ room_id: string }>(Method.Post, path, queryString, data);

const roomId = res.room_id;
// In case we were originally given an alias, check the room cache again
// with the resolved ID - this method is supposed to no-op if we already
// were in the room, after all.
const resolvedRoom = this.getRoom(roomId);
if (resolvedRoom?.hasMembershipState(this.credentials.userId!, "join")) return resolvedRoom;

const syncApi = new SyncApi(this, this.clientOpts, this.buildSyncApiOptions());
const syncRoom = syncApi.createRoom(roomId);
if (opts.syncRoom) {
Expand Down

0 comments on commit 8f90159

Please sign in to comment.