From f529a6c7a285e4cf587d0cfb90fa0bb6776e7c3f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 9 Dec 2019 20:36:00 -0700 Subject: [PATCH 1/2] Render policy room event updates in the timeline Fixes https://github.com/matrix-org/mjolnir/issues/15 This should be completely safe to deploy, even without a labs flag, because policy rooms (ban lists) are usually only joined by the people who know what they are. This also has no relation to the Mjolnir functionality currently in Riot, though it does make seeing your ban list a bit less awkward. Ban list rules only show up in ban list rooms and rarely show up in public rooms, hence the somewhat vague messaging. It should be obvious that it's a ban list room due to the surrounding room decoration/purpose. --- src/TextForEvent.js | 87 +++++++++++++++++++++++++ src/components/views/rooms/EventTile.js | 6 ++ src/i18n/strings/en_EN.json | 17 +++++ 3 files changed, 110 insertions(+) diff --git a/src/TextForEvent.js b/src/TextForEvent.js index cd0c5cfc5f..abd2e0432e 100644 --- a/src/TextForEvent.js +++ b/src/TextForEvent.js @@ -19,6 +19,7 @@ import { _t } from './languageHandler'; import * as Roles from './Roles'; import {isValid3pidInvite} from "./RoomInvite"; import SettingsStore from "./settings/SettingsStore"; +import {ALL_RULE_TYPES, ROOM_RULE_TYPES, SERVER_RULE_TYPES, USER_RULE_TYPES} from "./mjolnir/BanList"; function textForMemberEvent(ev) { // XXX: SYJS-16 "sender is sometimes null for join messages" @@ -506,6 +507,87 @@ function textForWidgetEvent(event) { } } +function textForMjolnirEvent(event) { + const senderName = event.getSender(); + const {entity: prevEntity, recommendation: prevRecommendation, reason: prevReason} = event.getPrevContent(); + const {entity, recommendation, reason} = event.getContent(); + + // Rule removed + if (!entity) { + if (USER_RULE_TYPES.includes(event.getType())) { + return _t("%(senderName)s removed the rule banning users matching %(glob)s", + {senderName, glob: prevEntity}); + } else if (ROOM_RULE_TYPES.includes(event.getType())) { + return _t("%(senderName)s removed the rule banning rooms matching %(glob)s", + {senderName, glob: prevEntity}); + } else if (SERVER_RULE_TYPES.includes(event.getType())) { + return _t("%(senderName)s removed the rule banning servers matching %(glob)s", + {senderName, glob: prevEntity}); + } + + // Unknown type. We'll say something, but we shouldn't end up here. + return _t("%(senderName)s removed a ban rule matching %(glob)s", {senderName, glob: prevEntity}); + } + + // Invalid rule + if (!recommendation || !reason) return _t(`%(senderName)s updated an invalid ban rule`, {senderName}); + + // Rule updated + if (entity === prevEntity) { + if (USER_RULE_TYPES.includes(event.getType())) { + return _t("%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s", + {senderName, glob: entity, reason}); + } else if (ROOM_RULE_TYPES.includes(event.getType())) { + return _t("%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s", + {senderName, glob: entity, reason}); + } else if (SERVER_RULE_TYPES.includes(event.getType())) { + return _t("%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s", + {senderName, glob: entity, reason}); + } + + // Unknown type. We'll say something but we shouldn't end up here. + return _t("%(senderName)s updated a ban rule matching %(glob)s for %(reason)s", + {senderName, glob: entity, reason}); + } + + // New rule + if (!prevEntity) { + if (USER_RULE_TYPES.includes(event.getType())) { + return _t("%(senderName)s created a rule banning users matching %(glob)s for %(reason)s", + {senderName, glob: entity, reason}); + } else if (ROOM_RULE_TYPES.includes(event.getType())) { + return _t("%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s", + {senderName, glob: entity, reason}); + } else if (SERVER_RULE_TYPES.includes(event.getType())) { + return _t("%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s", + {senderName, glob: entity, reason}); + } + + // Unknown type. We'll say something but we shouldn't end up here. + return _t("%(senderName)s created a ban rule matching %(glob)s for %(reason)s", + {senderName, glob: entity, reason}); + } + + // else the entity !== prevEntity - count as a removal & add + if (USER_RULE_TYPES.includes(event.getType())) { + return _t("%(senderName)s changed a rule that was banning users matching %(oldGlob)s to matching " + + "%(newGlob)s for %(reason)s", + {senderName, oldGlob: prevEntity, newGlob: entity, reason}); + } else if (ROOM_RULE_TYPES.includes(event.getType())) { + return _t("%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching " + + "%(newGlob)s for %(reason)s", + {senderName, oldGlob: prevEntity, newGlob: entity, reason}); + } else if (SERVER_RULE_TYPES.includes(event.getType())) { + return _t("%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching " + + "%(newGlob)s for %(reason)s", + {senderName, oldGlob: prevEntity, newGlob: entity, reason}); + } + + // Unknown type. We'll say something but we shouldn't end up here. + return _t("%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s " + + "for %(reason)s", {senderName, oldGlob: prevEntity, newGlob: entity, reason}); +} + const handlers = { 'm.room.message': textForMessageEvent, 'm.call.invite': textForCallInviteEvent, @@ -533,6 +615,11 @@ const stateHandlers = { 'im.vector.modular.widgets': textForWidgetEvent, }; +// Add all the Mjolnir stuff to the renderer +for (const evType of ALL_RULE_TYPES) { + stateHandlers[evType] = textForMjolnirEvent; +} + module.exports = { textForEvent: function(ev) { const handler = (ev.isState() ? stateHandlers : handlers)[ev.getType()]; diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index fb0878b880..edffead03e 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -34,6 +34,7 @@ import SettingsStore from "../../../settings/SettingsStore"; import {EventStatus, MatrixClient} from 'matrix-js-sdk'; import {formatTime} from "../../../DateUtils"; import MatrixClientPeg from '../../../MatrixClientPeg'; +import {ALL_RULE_TYPES} from "../../../mjolnir/BanList"; const ObjectUtils = require('../../../ObjectUtils'); @@ -69,6 +70,11 @@ const stateEventTileTypes = { 'm.room.related_groups': 'messages.TextualEvent', }; +// Add all the Mjolnir stuff to the renderer +for (const evType of ALL_RULE_TYPES) { + stateEventTileTypes[evType] = 'messages.TextualEvent'; +} + function getHandlerTile(ev) { const type = ev.getType(); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 182c761c5f..5685c31a60 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -266,6 +266,23 @@ "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s", "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s", + "%(senderName)s removed the rule banning users matching %(glob)s": "%(senderName)s removed the rule banning users matching %(glob)s", + "%(senderName)s removed the rule banning rooms matching %(glob)s": "%(senderName)s removed the rule banning rooms matching %(glob)s", + "%(senderName)s removed the rule banning servers matching %(glob)s": "%(senderName)s removed the rule banning servers matching %(glob)s", + "%(senderName)s removed a ban rule matching %(glob)s": "%(senderName)s removed a ban rule matching %(glob)s", + "%(senderName)s updated an invalid ban rule": "%(senderName)s updated an invalid ban rule", + "%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s": "%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s", + "%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s", + "%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s", + "%(senderName)s updated a ban rule matching %(glob)s for %(reason)s": "%(senderName)s updated a ban rule matching %(glob)s for %(reason)s", + "%(senderName)s created a rule banning users matching %(glob)s for %(reason)s": "%(senderName)s created a rule banning users matching %(glob)s for %(reason)s", + "%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s", + "%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s", + "%(senderName)s created a ban rule matching %(glob)s for %(reason)s": "%(senderName)s created a ban rule matching %(glob)s for %(reason)s", + "%(senderName)s changed a rule that was banning users matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s changed a rule that was banning users matching %(oldGlob)s to matching %(newGlob)s for %(reason)s", + "%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s", + "%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s", + "%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s", "Light theme": "Light theme", "Dark theme": "Dark theme", "%(displayName)s is typing …": "%(displayName)s is typing …", From 4548713c19a9af90dac7f6bb068d2932b0c913e7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 9 Dec 2019 20:38:56 -0700 Subject: [PATCH 2/2] Appease the linter --- src/TextForEvent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TextForEvent.js b/src/TextForEvent.js index abd2e0432e..c3c8396e26 100644 --- a/src/TextForEvent.js +++ b/src/TextForEvent.js @@ -509,7 +509,7 @@ function textForWidgetEvent(event) { function textForMjolnirEvent(event) { const senderName = event.getSender(); - const {entity: prevEntity, recommendation: prevRecommendation, reason: prevReason} = event.getPrevContent(); + const {entity: prevEntity} = event.getPrevContent(); const {entity, recommendation, reason} = event.getContent(); // Rule removed