From 8e82e11e1dea42deecb53b885fce42da3c8c21c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=B6ller?= Date: Mon, 8 Aug 2022 14:09:26 +0200 Subject: [PATCH] Follow Matrix spec for MatrixClient.getRoomMembers arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The /rooms/{roomId}/members API only allows to filter for at most one membership kind and the same goes for not_membership. This deprecates the function signature with arrays and adds a new signature with single membership arguments. Signed-off-by: Fabian Möller --- src/MatrixClient.ts | 42 ++++++++++++++++++++++++++--- src/e2ee/CryptoClient.ts | 2 +- test/MatrixClientTest.ts | 10 +++---- test/encryption/CryptoClientTest.ts | 4 +-- 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/MatrixClient.ts b/src/MatrixClient.ts index 6a04dd8e..3f4115c0 100644 --- a/src/MatrixClient.ts +++ b/src/MatrixClient.ts @@ -1073,6 +1073,23 @@ export class MatrixClient extends EventEmitter { return (await this.doRequest("GET", "/_matrix/client/v3/rooms/" + encodeURIComponent(roomId) + "/joined_members")).joined; } + /** + * Gets the membership events of users in the room. Defaults to all membership + * types, though this can be controlled with the membership and notMembership + * arguments. To change the point in time, use the batchToken. + * @param {string} roomId The room ID to get members in. + * @param {string} batchToken The point in time to get members at (or null for 'now') + * @param {Membership} membership The membership kind to search for. + * @param {Membership} notMembership The membership kind to not search for. + * @returns {Promise} Resolves to the membership events of the users in the room. + */ + public getRoomMembers( + roomId: string, + batchToken?: string, + membership?: Membership, + notMembership?: Membership, + ): Promise; + /** * Gets the membership events of users in the room. Defaults to all membership * types, though this can be controlled with the membership and notMembership @@ -1081,9 +1098,28 @@ export class MatrixClient extends EventEmitter { * @param {string} batchToken The point in time to get members at (or null for 'now') * @param {string[]} membership The membership kinds to search for. * @param {string[]} notMembership The membership kinds to not search for. - * @returns {Promise} Resolves to the membership events of the users in the room. - */ - public getRoomMembers(roomId: string, batchToken: string = null, membership: Membership[] = null, notMembership: Membership[] = null): Promise { + * @returns {Promise} Resolves to the membership events of the users in the room. + * @deprecated The method should not be used, because the Matrix API doesn't allow to filter for multiple membership kinds. + */ + public getRoomMembers( + roomId: string, + batchToken?: string, + membership?: Membership[], + notMembership?: Membership[], + ): Promise; + + public getRoomMembers( + roomId: string, + batchToken?: string, + membership?: Membership | Membership[], + notMembership?: Membership | Membership[], + ): Promise { + if (membership?.length > 1) { + LogService.warn("MatrixClientLite", "getRoomMembers called with multiple membership kinds."); + } + if (notMembership?.length > 1) { + LogService.warn("MatrixClientLite", "getRoomMembers called with multiple notMembership kinds."); + } const qs = {}; if (batchToken) qs["at"] = batchToken; if (membership) qs["membership"] = membership; diff --git a/src/e2ee/CryptoClient.ts b/src/e2ee/CryptoClient.ts index 0adcc4b0..590ecc4f 100644 --- a/src/e2ee/CryptoClient.ts +++ b/src/e2ee/CryptoClient.ts @@ -111,7 +111,7 @@ export class CryptoClient { if (membership.effectiveMembership !== 'join' && membership.effectiveMembership !== 'invite') return; await this.engine.addTrackedUsers([membership.membershipFor]); } else if (event['type'] === 'm.room.encryption') { - const members = await this.client.getRoomMembers(roomId, null, ['join', 'invite']); + const members = await this.client.getRoomMembers(roomId, null, null, 'leave'); await this.engine.addTrackedUsers(members.map(e => e.membershipFor)); } } diff --git a/test/MatrixClientTest.ts b/test/MatrixClientTest.ts index c3e7a003..133b4195 100644 --- a/test/MatrixClientTest.ts +++ b/test/MatrixClientTest.ts @@ -3080,18 +3080,18 @@ describe('MatrixClient', () => { }, }, ]; - const forMemberships: Membership[] = ['join', 'leave']; - const forNotMemberships: Membership[] = ['ban']; + const forMembership: Membership = 'join'; + const forNotMembership: Membership = 'ban'; // noinspection TypeScriptValidateJSTypes http.when("GET", "/_matrix/client/v3/rooms").respond(200, (path, content, req) => { expect(path).toEqual(`${hsUrl}/_matrix/client/v3/rooms/${encodeURIComponent(roomId)}/members`); - expectArrayEquals(forMemberships, (req.queryParams as any).membership); - expectArrayEquals(forNotMemberships, (req.queryParams as any).not_membership); + expect(forMembership).toEqual((req.queryParams as any).membership); + expect(forNotMembership).toEqual((req.queryParams as any).not_membership); return { chunk: memberEvents }; }); - const [result] = await Promise.all([client.getRoomMembers(roomId, null, forMemberships, forNotMemberships), http.flushAllExpected()]); + const [result] = await Promise.all([client.getRoomMembers(roomId, null, forMembership, forNotMembership), http.flushAllExpected()]); expect(result).toBeDefined(); expect(result.length).toBe(2); expect(result[0].membership).toBe(memberEvents[0]['content']['membership']); diff --git a/test/encryption/CryptoClientTest.ts b/test/encryption/CryptoClientTest.ts index 02ed769e..9bfea65e 100644 --- a/test/encryption/CryptoClientTest.ts +++ b/test/encryption/CryptoClientTest.ts @@ -529,10 +529,10 @@ describe('CryptoClient', () => { const roomId = "!room:example.org"; const prom2 = new Promise(extResolve => { - client.getRoomMembers = simple.mock().callFn((rid, token, memberships) => { + client.getRoomMembers = simple.mock().callFn((rid, token, _membership, notMembership) => { expect(rid).toEqual(roomId); expect(token).toBeFalsy(); - expect(memberships).toEqual(["join", "invite"]); + expect(notMembership).toEqual("leave"); extResolve(); return Promise.resolve(targetUserIds.map(u => new MembershipEvent({ type: "m.room.member",