From f9cd40cd2c83cfed5340c4f979483e68160a5cdc Mon Sep 17 00:00:00 2001 From: gnuxie Date: Wed, 27 Jul 2022 19:26:04 +0100 Subject: [PATCH 1/6] Replace acceptInvitesFromGroup with acceptInvitesFromSpace. https://github.com/matrix-org/mjolnir/issues/125 https://github.com/matrix-org/mjolnir/issues/99 acceptInvitesFromGroup was implemented with an experimental api that was a precursor to spaces which was refereed to as either communities or groups. Support for communities/groups ended in Synapse 1.61.0 https://github.com/matrix-org/synapse/releases/tag/v1.61.0. --- config/default.yaml | 4 ++-- config/harness.yaml | 4 ++-- src/Mjolnir.ts | 15 ++++++++++++--- src/config.ts | 4 ++-- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/config/default.yaml b/config/default.yaml index 6b94fc1d..3a2e560f 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -34,9 +34,9 @@ dataPath: "/data/storage" # If true (the default), Mjolnir will only accept invites from users present in managementRoom. autojoinOnlyIfManager: true -# If `autojoinOnlyIfManager` is false, only the members in this group can invite +# If `autojoinOnlyIfManager` is false, only the members in this space can invite # the bot to new rooms. -acceptInvitesFromGroup: "+example:example.org" +acceptInvitesFromSpace: "!example:example.org" # Whether Mjolnir should report ignored invites to the management room (if autojoinOnlyIfManager is true). recordIgnoredInvites: false diff --git a/config/harness.yaml b/config/harness.yaml index e3c3a9db..18b992fa 100644 --- a/config/harness.yaml +++ b/config/harness.yaml @@ -32,9 +32,9 @@ dataPath: "./test/harness/mjolnir-data/" # to new rooms. autojoinOnlyIfManager: true -# If `autojoinOnlyIfManager` is false, only the members in this group can invite +# If `autojoinOnlyIfManager` is false, only the members in this space can invite # the bot to new rooms. -acceptInvitesFromGroup: '+example:example.org' +acceptInvitesFromSpace: '!example:example.org' # If the bot is invited to a room and it won't accept the invite (due to the # conditions above), report it to the management room. Defaults to disabled (no diff --git a/src/Mjolnir.ts b/src/Mjolnir.ts index 60260726..6cafff0c 100644 --- a/src/Mjolnir.ts +++ b/src/Mjolnir.ts @@ -138,9 +138,18 @@ export class Mjolnir { const managers = await client.getJoinedRoomMembers(mjolnir.managementRoomId); if (!managers.includes(membershipEvent.sender)) return reportInvite(); // ignore invite } else { - const groupMembers = await client.unstableApis.getGroupUsers(options.acceptInvitesFromGroup); - const userIds = groupMembers.map(m => m.user_id); - if (!userIds.includes(membershipEvent.sender)) return reportInvite(); // ignore invite + const spaceId = await client.resolveRoom(options.acceptInvitesFromSpace); + const spaceUserIds = await client.getJoinedRoomMembers(spaceId) + .catch(async e => { + if (e.body?.errcode === "M_FORBIDDEN") { + await mjolnir.logMessage(LogLevel.ERROR, 'Mjolnir', `Mjolnir is not in the space configured for acceptInvitesFromSpace, did you invite it?`); + await client.joinRoom(spaceId); + return await client.getJoinedRoomMembers(spaceId); + } else { + return Promise.reject(e); + } + }); + if (!spaceUserIds.includes(membershipEvent.sender)) return reportInvite(); // ignore invite } return client.joinRoom(roomId); diff --git a/src/config.ts b/src/config.ts index c286f519..27c50bde 100644 --- a/src/config.ts +++ b/src/config.ts @@ -35,7 +35,7 @@ interface IConfig { password: string; }; dataPath: string; - acceptInvitesFromGroup: string; + acceptInvitesFromSpace: string; autojoinOnlyIfManager: boolean; recordIgnoredInvites: boolean; managementRoom: string; @@ -114,7 +114,7 @@ const defaultConfig: IConfig = { password: "", }, dataPath: "/data/storage", - acceptInvitesFromGroup: '+example:example.org', + acceptInvitesFromSpace: '!noop:example.org', autojoinOnlyIfManager: false, recordIgnoredInvites: false, managementRoom: "!noop:example.org", From 681106cf7c03c5fe41052ac3e9a6347a01d11ef2 Mon Sep 17 00:00:00 2001 From: jesopo Date: Mon, 8 Aug 2022 14:42:11 +0000 Subject: [PATCH 2/6] add integration test --- .../integration/acceptInvitesFromGroupTest.ts | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 test/integration/acceptInvitesFromGroupTest.ts diff --git a/test/integration/acceptInvitesFromGroupTest.ts b/test/integration/acceptInvitesFromGroupTest.ts new file mode 100644 index 00000000..cc8754c1 --- /dev/null +++ b/test/integration/acceptInvitesFromGroupTest.ts @@ -0,0 +1,47 @@ +import { strict as assert } from "assert"; + +import config from "../../src/config"; +import { newTestUser } from "./clientHelper"; + +describe("Test: Accept Invites From Space", function() { + let client; + this.beforeEach(async function () { + client = await newTestUser({ name: { contains: "spacee" }}); + await client.start(); + }) + this.afterEach(async function () { + await client.stop(); + }) + it("Mjolnir should accept an invite from a user in a nominated Space", async function() { + this.timeout(20000); + + const mjolnirUserId = await this.mjolnir.client.getUserId(); + + const space = await client.createSpace({ + name: "mjolnir space invite test", + invites: [mjolnirUserId], + }); + + await this.mjolnir.client.joinRoom(space.roomId); + + // we're mutating a static object, which may affect other tests :( + config.autojoinOnlyIfManager = false; + config.acceptInvitesFromSpace = space.roomId; + + const promise = new Promise(async (resolve, reject) => { + const newRoomId = await client.createRoom({ invite: [mjolnirUserId] }); + client.on("room.event", (roomId, event) => { + if ( + roomId === newRoomId + && event.type === "m.room.member" + && event.sender === mjolnirUserId + && event.content?.membership === "join" + ) { + resolve(null); + } + }); + }); + await promise; + }); +}); + From cc3139e2633e3cc913326b7df853f8f28353db2a Mon Sep 17 00:00:00 2001 From: gnuxie Date: Mon, 15 Aug 2022 13:52:33 +0100 Subject: [PATCH 3/6] tidy up a little bit --- test/integration/acceptInvitesFromGroupTest.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/integration/acceptInvitesFromGroupTest.ts b/test/integration/acceptInvitesFromGroupTest.ts index cc8754c1..ebbd8983 100644 --- a/test/integration/acceptInvitesFromGroupTest.ts +++ b/test/integration/acceptInvitesFromGroupTest.ts @@ -1,10 +1,10 @@ -import { strict as assert } from "assert"; - +import { MatrixClient } from "matrix-bot-sdk"; +import { Mjolnir } from "../../src/Mjolnir" import config from "../../src/config"; import { newTestUser } from "./clientHelper"; describe("Test: Accept Invites From Space", function() { - let client; + let client: MatrixClient|undefined; this.beforeEach(async function () { client = await newTestUser({ name: { contains: "spacee" }}); await client.start(); @@ -15,11 +15,13 @@ describe("Test: Accept Invites From Space", function() { it("Mjolnir should accept an invite from a user in a nominated Space", async function() { this.timeout(20000); - const mjolnirUserId = await this.mjolnir.client.getUserId(); + const mjolnir: Mjolnir = this.mjolnir!; + const mjolnirUserId = await mjolnir.client.getUserId(); const space = await client.createSpace({ name: "mjolnir space invite test", invites: [mjolnirUserId], + isPublic: false }); await this.mjolnir.client.joinRoom(space.roomId); From f2ecc2ec336ab52d35da33c570e5ef41b11293a8 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 16 Aug 2022 16:07:05 +0100 Subject: [PATCH 4/6] Edit the test now we can dynamically change config though idk, shouldn't we have just made a new mjolnir instance for this test, or changed the config before the test started somehow? it doesn't seem right. --- test/integration/acceptInvitesFromGroupTest.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/integration/acceptInvitesFromGroupTest.ts b/test/integration/acceptInvitesFromGroupTest.ts index ebbd8983..4ad293fc 100644 --- a/test/integration/acceptInvitesFromGroupTest.ts +++ b/test/integration/acceptInvitesFromGroupTest.ts @@ -1,6 +1,5 @@ import { MatrixClient } from "matrix-bot-sdk"; import { Mjolnir } from "../../src/Mjolnir" -import config from "../../src/config"; import { newTestUser } from "./clientHelper"; describe("Test: Accept Invites From Space", function() { @@ -27,8 +26,8 @@ describe("Test: Accept Invites From Space", function() { await this.mjolnir.client.joinRoom(space.roomId); // we're mutating a static object, which may affect other tests :( - config.autojoinOnlyIfManager = false; - config.acceptInvitesFromSpace = space.roomId; + mjolnir.config.autojoinOnlyIfManager = false; + mjolnir.config.acceptInvitesFromGroup = space.roomId; const promise = new Promise(async (resolve, reject) => { const newRoomId = await client.createRoom({ invite: [mjolnirUserId] }); From bd62c7cc60985775ccd8917fdec08f98103810fc Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 16 Aug 2022 16:10:52 +0100 Subject: [PATCH 5/6] Groups -> Space consistency --- src/Mjolnir.ts | 2 +- ...tInvitesFromGroupTest.ts => acceptInvitesFromSpaceTest.ts} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename test/integration/{acceptInvitesFromGroupTest.ts => acceptInvitesFromSpaceTest.ts} (92%) diff --git a/src/Mjolnir.ts b/src/Mjolnir.ts index 7c859357..ce6637c3 100644 --- a/src/Mjolnir.ts +++ b/src/Mjolnir.ts @@ -123,7 +123,7 @@ export class Mjolnir { * @param {string} options.managementRoom The room to report ignored invitations to if `recordIgnoredInvites` is true. * @param {boolean} options.recordIgnoredInvites Whether to report invites that will be ignored to the `managementRoom`. * @param {boolean} options.autojoinOnlyIfManager Whether to only accept an invitation by a user present in the `managementRoom`. - * @param {string} options.acceptInvitesFromGroup A group of users to accept invites from, ignores invites form users not in this group. + * @param {string} options.acceptInvitesFromSpace A space of users to accept invites from, ignores invites form users not in this space. */ private static addJoinOnInviteListener(mjolnir: Mjolnir, client: MatrixClient, options: { [key: string]: any }) { client.on("room.invite", async (roomId: string, inviteEvent: any) => { diff --git a/test/integration/acceptInvitesFromGroupTest.ts b/test/integration/acceptInvitesFromSpaceTest.ts similarity index 92% rename from test/integration/acceptInvitesFromGroupTest.ts rename to test/integration/acceptInvitesFromSpaceTest.ts index 4ad293fc..8ee45874 100644 --- a/test/integration/acceptInvitesFromGroupTest.ts +++ b/test/integration/acceptInvitesFromSpaceTest.ts @@ -27,9 +27,9 @@ describe("Test: Accept Invites From Space", function() { // we're mutating a static object, which may affect other tests :( mjolnir.config.autojoinOnlyIfManager = false; - mjolnir.config.acceptInvitesFromGroup = space.roomId; + mjolnir.config.acceptInvitesFromSpace = space.roomId; - const promise = new Promise(async (resolve, reject) => { + const promise = new Promise(async resolve => { const newRoomId = await client.createRoom({ invite: [mjolnirUserId] }); client.on("room.event", (roomId, event) => { if ( From a08b98d44ee8b886b2de480c140758fc05cf5719 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 16 Aug 2022 16:13:38 +0100 Subject: [PATCH 6/6] oopsie --- test/integration/acceptInvitesFromSpaceTest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/acceptInvitesFromSpaceTest.ts b/test/integration/acceptInvitesFromSpaceTest.ts index 8ee45874..3f581a58 100644 --- a/test/integration/acceptInvitesFromSpaceTest.ts +++ b/test/integration/acceptInvitesFromSpaceTest.ts @@ -5,7 +5,7 @@ import { newTestUser } from "./clientHelper"; describe("Test: Accept Invites From Space", function() { let client: MatrixClient|undefined; this.beforeEach(async function () { - client = await newTestUser({ name: { contains: "spacee" }}); + client = await newTestUser(this.config.homeserverUrl, { name: { contains: "spacee" }}); await client.start(); }) this.afterEach(async function () {