diff --git a/config/default.yaml b/config/default.yaml index 0e3b43d..e32968b 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -45,7 +45,3 @@ verifyPermissionsOnStartup: true # A list of rooms to protect (matrix.to URLs) protectedRooms: - "https://matrix.to/#/#yourroom:example.org" - -# A list of ban lists to follow (matrix.to URLs) -banLists: - - "https://matrix.to/#/#sample-ban-list:t2bot.io" # S.A.M.P.L.E. diff --git a/src/Mjolnir.ts b/src/Mjolnir.ts index daaff6f..5913e87 100644 --- a/src/Mjolnir.ts +++ b/src/Mjolnir.ts @@ -27,6 +27,8 @@ export const STATE_CHECKING_PERMISSIONS = "checking_permissions"; export const STATE_SYNCING = "syncing"; export const STATE_RUNNING = "running"; +const WATCHED_LISTS_EVENT_TYPE = "org.matrix.mjolnir.watched_lists"; + export class Mjolnir { private displayName: string; @@ -103,36 +105,56 @@ export class Mjolnir { }); } - public async watchList(roomRef: string) { + public async watchList(roomRef: string): Promise { const joinedRooms = await this.client.getJoinedRooms(); const permalink = Permalinks.parseUrl(roomRef); - if (!permalink.roomIdOrAlias) return; + if (!permalink.roomIdOrAlias) return null; const roomId = await this.client.resolveRoom(permalink.roomIdOrAlias); if (!joinedRooms.includes(roomId)) { await this.client.joinRoom(permalink.roomIdOrAlias, permalink.viaServers); } - if (this.banLists.find(b => b.roomId === roomId)) return; + if (this.banLists.find(b => b.roomId === roomId)) return null; const list = new BanList(roomId, roomRef, this.client); await list.updateList(); this.banLists.push(list); + + await this.client.setAccountData(WATCHED_LISTS_EVENT_TYPE, { + references: this.banLists.map(b => b.roomRef), + }); + + return list; } - public async unwatchList(roomRef: string) { + public async unwatchList(roomRef: string): Promise { const permalink = Permalinks.parseUrl(roomRef); - if (!permalink.roomIdOrAlias) return; + if (!permalink.roomIdOrAlias) return null; const roomId = await this.client.resolveRoom(permalink.roomIdOrAlias); const list = this.banLists.find(b => b.roomId === roomId); if (list) this.banLists.splice(this.banLists.indexOf(list), 1); + + await this.client.setAccountData(WATCHED_LISTS_EVENT_TYPE, { + references: this.banLists.map(b => b.roomRef), + }); + + return list; } public async buildWatchedBanLists() { const banLists: BanList[] = []; const joinedRooms = await this.client.getJoinedRooms(); - for (const roomRef of config.banLists) { + + let watchedListsEvent = {}; + try { + watchedListsEvent = await this.client.getAccountData(WATCHED_LISTS_EVENT_TYPE); + } catch (e) { + // ignore - not important + } + + for (const roomRef of (watchedListsEvent['references'] || [])) { const permalink = Permalinks.parseUrl(roomRef); if (!permalink.roomIdOrAlias) continue; diff --git a/src/commands/CommandHandler.ts b/src/commands/CommandHandler.ts index d9ea80a..4899217 100644 --- a/src/commands/CommandHandler.ts +++ b/src/commands/CommandHandler.ts @@ -23,6 +23,7 @@ import * as htmlEscape from "escape-html"; import { execSyncCommand } from "./SyncCommand"; import { execPermissionCheckCommand } from "./PermissionCheckCommand"; import { execCreateListCommand } from "./CreateBanListCommand"; +import { execUnwatchCommand, execWatchCommand } from "./WatchUnwatchCommand"; export const COMMAND_PREFIX = "!mjolnir"; @@ -45,6 +46,10 @@ export function handleCommand(roomId: string, event: any, mjolnir: Mjolnir) { return execPermissionCheckCommand(roomId, event, mjolnir); } else if (parts.length >= 5 && parts[1] === 'list' && parts[2] === 'create') { return execCreateListCommand(roomId, event, mjolnir, parts); + } else if (parts[1] === 'watch' && parts.length > 1) { + return execWatchCommand(roomId, event, mjolnir, parts); + } else if (parts[1] === 'unwatch' && parts.length > 1) { + return execUnwatchCommand(roomId, event, mjolnir, parts); } else { // Help menu const menu = "" + diff --git a/src/commands/WatchUnwatchCommand.ts b/src/commands/WatchUnwatchCommand.ts new file mode 100644 index 0000000..b63ea80 --- /dev/null +++ b/src/commands/WatchUnwatchCommand.ts @@ -0,0 +1,42 @@ +/* +Copyright 2019 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { Mjolnir } from "../Mjolnir"; +import { Permalinks, RichReply } from "matrix-bot-sdk"; + +// !mjolnir watch +export async function execWatchCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) { + const list = await mjolnir.watchList(Permalinks.forRoom(parts[2])); + if (!list) { + const replyText = "Cannot watch list due to error - is that a valid room alias?"; + const reply = RichReply.createFor(roomId, event, replyText, replyText); + reply["msgtype"] = "m.notice"; + return mjolnir.client.sendMessage(roomId, reply); + } + await mjolnir.client.unstableApis.addReactionToEvent(roomId, event['event_id'], '✅'); +} + +// !mjolnir unwatch +export async function execUnwatchCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) { + const list = await mjolnir.unwatchList(Permalinks.forRoom(parts[2])); + if (!list) { + const replyText = "Cannot unwatch list due to error - is that a valid room alias?"; + const reply = RichReply.createFor(roomId, event, replyText, replyText); + reply["msgtype"] = "m.notice"; + return mjolnir.client.sendMessage(roomId, reply); + } + await mjolnir.client.unstableApis.addReactionToEvent(roomId, event['event_id'], '✅'); +} diff --git a/src/config.ts b/src/config.ts index c38b19f..d819b62 100644 --- a/src/config.ts +++ b/src/config.ts @@ -31,7 +31,6 @@ interface IConfig { syncOnStartup: boolean; verifyPermissionsOnStartup: boolean; protectedRooms: string[]; // matrix.to urls - banLists: string[]; // matrix.to urls } export default config;