diff --git a/config/default.yaml b/config/default.yaml index c451cea..3caeb00 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -74,3 +74,11 @@ automaticallyRedactForReasons: # A list of rooms to protect (matrix.to URLs) protectedRooms: - "https://matrix.to/#/#yourroom:example.org" + +# Set this option to true to protect every room the bot is joined to. Note that +# this effectively makes the protectedRooms and associated commands useless because +# the bot by nature must be joined to the room to protect it. +# +# Note: the management room is *excluded* from this condition. Add it to the +# protected rooms to protect it. +protectAllJoinedRooms: false diff --git a/package.json b/package.json index 1a25ce8..68c6c65 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,6 @@ "config": "^3.2.2", "escape-html": "^1.0.3", "js-yaml": "^3.13.1", - "matrix-bot-sdk": "^0.4.0" + "matrix-bot-sdk": "^0.4.1" } } diff --git a/src/Mjolnir.ts b/src/Mjolnir.ts index 5cccc48..0273b39 100644 --- a/src/Mjolnir.ts +++ b/src/Mjolnir.ts @@ -44,6 +44,7 @@ export class Mjolnir { private protections: IProtection[] = []; private redactionQueue = new AutomaticRedactionQueue(); private automaticRedactionReasons: MatrixGlob[] = []; + private protectedJoinedRoomIds: string[] = []; constructor( public readonly client: MatrixClient, @@ -75,6 +76,15 @@ export class Mjolnir { } }); + client.on("room.join", (roomId: string, event: any) => { + LogService.info("Mjolnir", `Joined ${roomId}`); + return this.resyncJoinedRooms(); + }); + client.on("room.leave", (roomId: string, event: any) => { + LogService.info("Mjolnir", `Left ${roomId}`); + return this.resyncJoinedRooms(); + }); + client.getUserId().then(userId => { this.localpart = userId.split(':')[0].substring(1); return client.getUserProfile(userId); @@ -115,6 +125,7 @@ export class Mjolnir { }).then(async () => { this.currentState = STATE_SYNCING; await logMessage(LogLevel.DEBUG, "Mjolnir@startup", "Loading protected rooms..."); + await this.resyncJoinedRooms(false); try { const data = await this.client.getAccountData(PROTECTED_ROOMS_EVENT_TYPE); if (data && data['rooms']) { @@ -138,8 +149,7 @@ export class Mjolnir { } public async addProtectedRoom(roomId: string) { - const permalink = Permalinks.forRoom(roomId); - this.protectedRooms[roomId] = permalink; + this.protectedRooms[roomId] = Permalinks.forRoom(roomId); let additionalProtectedRooms; try { @@ -167,6 +177,23 @@ export class Mjolnir { await this.client.setAccountData(PROTECTED_ROOMS_EVENT_TYPE, additionalProtectedRooms); } + private async resyncJoinedRooms(withSync = true) { + if (!config.protectAllJoinedRooms) return; + + const joinedRoomIds = (await this.client.getJoinedRooms()).filter(r => r !== config.managementRoom); + for (const roomId of this.protectedJoinedRoomIds) { + delete this.protectedRooms[roomId]; + } + this.protectedJoinedRoomIds = joinedRoomIds; + for (const roomId of joinedRoomIds) { + this.protectedRooms[roomId] = Permalinks.forRoom(roomId); + } + + if (withSync) { + await this.syncLists(config.verboseLogging); + } + } + private async getEnabledProtections() { let enabled: string[] = []; try { diff --git a/src/commands/ListProtectedRoomsCommand.ts b/src/commands/ListProtectedRoomsCommand.ts index 007683a..c0f29fc 100644 --- a/src/commands/ListProtectedRoomsCommand.ts +++ b/src/commands/ListProtectedRoomsCommand.ts @@ -19,8 +19,8 @@ import { RichReply } from "matrix-bot-sdk"; // !mjolnir rooms export async function execListProtectedRooms(roomId: string, event: any, mjolnir: Mjolnir) { - let html = "Protected rooms: