diff --git a/src/ManagementRoomOutput.ts b/src/ManagementRoomOutput.ts
index edb25029..87d7b1cd 100644
--- a/src/ManagementRoomOutput.ts
+++ b/src/ManagementRoomOutput.ts
@@ -40,7 +40,7 @@ const levelToFn = {
*/
export default class ManagementRoomOutput {
constructor(
- private readonly managementRoomId: string,
+ public readonly managementRoomId: string,
private readonly client: MatrixSendClient,
private readonly config: IConfig,
) {}
diff --git a/src/ProtectedRoomsSet.ts b/src/ProtectedRoomsSet.ts
index a88b414a..9b8b345b 100644
--- a/src/ProtectedRoomsSet.ts
+++ b/src/ProtectedRoomsSet.ts
@@ -362,13 +362,12 @@ export class ProtectedRoomsSet {
// ignore - assume no ACL
}
- // We specifically use sendNotice to avoid having to escape HTML
- await this.managementRoomOutput.logMessage(
- LogLevel.DEBUG,
- "ApplyAcl",
- `Applying ACL in ${roomId}`,
- roomId,
- );
+ await this.client.sendMessage(this.managementRoomId, {
+ msgtype: "m.text",
+ body: `Applying ACL in ${roomId}.`,
+ format: "org.matrix.custom.html",
+ formatted_body: `Applying ACL in ${htmlEscape(roomId)}.`,
+ });
if (!this.config.noop) {
await this.client.sendStateEvent(roomId, "m.room.server_acl", "", finalAcl);
@@ -439,13 +438,13 @@ export class ProtectedRoomsSet {
const memberAccess = this.accessControlUnit.getAccessForUser(member.userId, "IGNORE_SERVER");
if (memberAccess.outcome === Access.Banned) {
const reason = memberAccess.rule ? memberAccess.rule.reason : "";
- // We specifically use sendNotice to avoid having to escape HTML
- await this.managementRoomOutput.logMessage(
- LogLevel.INFO,
- "ApplyBan",
- `Banning ${member.userId} in ${roomId} for: ${reason}`,
- roomId,
- );
+
+ await this.client.sendMessage(this.managementRoomId, {
+ msgtype: "m.text",
+ body: `Banning ${member.userId} in ${roomId} for: ${reason}.`,
+ format: "org.matrix.custom.html",
+ formatted_body: `Banning ${htmlEscape(member.userId)} in ${roomId} for: ${reason}.`,
+ });
if (!this.config.noop) {
if (this.moderators.checkMembership(member.userId)) {
diff --git a/src/commands/KickCommand.ts b/src/commands/KickCommand.ts
index 19857e6d..c49b4281 100644
--- a/src/commands/KickCommand.ts
+++ b/src/commands/KickCommand.ts
@@ -16,6 +16,7 @@ limitations under the License.
import { Mjolnir } from "../Mjolnir";
import { LogLevel, MatrixGlob, RichReply } from "@vector-im/matrix-bot-sdk";
+import { htmlEscape } from "../utils";
// !mjolnir kick [room] [reason]
export async function execKickCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) {
@@ -57,12 +58,12 @@ export async function execKickCommand(roomId: string, event: any, mjolnir: Mjoln
const target = member.membershipFor;
if (kickRule.test(target)) {
- await mjolnir.managementRoomOutput.logMessage(
- LogLevel.DEBUG,
- "KickCommand",
- `Removing ${target} in ${protectedRoomId}`,
- protectedRoomId,
- );
+ await mjolnir.client.sendMessage(mjolnir.managementRoomId, {
+ msgtype: "m.text",
+ body: `Removing ${target} in ${protectedRoomId}.`,
+ format: "org.matrix.custom.html",
+ formatted_body: `Removing ${htmlEscape(target)} in ${protectedRoomId}.`,
+ });
if (!mjolnir.config.noop) {
try {
@@ -70,11 +71,12 @@ export async function execKickCommand(roomId: string, event: any, mjolnir: Mjoln
return mjolnir.client.kickUser(target, protectedRoomId, reason);
});
} catch (e) {
- await mjolnir.managementRoomOutput.logMessage(
- LogLevel.WARN,
- "KickCommand",
- `An error happened while trying to kick ${target}: ${e}`,
- );
+ await mjolnir.client.sendMessage(mjolnir.managementRoomId, {
+ msgtype: "m.text",
+ body: `An error happened while trying to kick ${target}: ${e}`,
+ format: "org.matrix.custom.html",
+ formatted_body: `An error happened while trying to kick ${htmlEscape(target)}: ${e}.`,
+ });
}
} else {
await mjolnir.managementRoomOutput.logMessage(
diff --git a/src/commands/SuspendCommand.ts b/src/commands/SuspendCommand.ts
index 33bef2d7..5ab6dc3a 100644
--- a/src/commands/SuspendCommand.ts
+++ b/src/commands/SuspendCommand.ts
@@ -16,6 +16,7 @@ limitations under the License.
import { Mjolnir } from "../Mjolnir";
import { RichReply } from "@vector-im/matrix-bot-sdk";
+import { htmlEscape } from "../utils";
export async function execSuspendCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) {
const target = parts[2];
@@ -31,7 +32,8 @@ export async function execSuspendCommand(roomId: string, event: any, mjolnir: Mj
await mjolnir.suspendSynapseUser(target);
const msg = `User ${target} has been suspended.`;
- const confirmation = RichReply.createFor(roomId, event, msg, msg);
+ const htmlMsg = `User ${htmlEscape(target)} has been suspended.`;
+ const confirmation = RichReply.createFor(roomId, event, msg, htmlMsg);
confirmation["msgtype"] = "m.notice";
await mjolnir.client.sendMessage(roomId, confirmation);
await mjolnir.client.unstableApis.addReactionToEvent(roomId, event["event_id"], "✅");
diff --git a/src/protections/BasicFlooding.ts b/src/protections/BasicFlooding.ts
index d6ddc451..0c52d2a8 100644
--- a/src/protections/BasicFlooding.ts
+++ b/src/protections/BasicFlooding.ts
@@ -18,6 +18,7 @@ import { Protection } from "./IProtection";
import { NumberProtectionSetting } from "./ProtectionSettings";
import { Mjolnir } from "../Mjolnir";
import { LogLevel, LogService } from "@vector-im/matrix-bot-sdk";
+import { htmlEscape } from "../utils";
// if this is exceeded, we'll ban the user for spam and redact their messages
export const DEFAULT_MAX_PER_MINUTE = 10;
@@ -68,12 +69,12 @@ export class BasicFlooding extends Protection {
}
if (messageCount >= this.settings.maxPerMinute.value) {
- await mjolnir.managementRoomOutput.logMessage(
- LogLevel.WARN,
- "BasicFlooding",
- `Banning ${event["sender"]} in ${roomId} for flooding (${messageCount} messages in the last minute)`,
- roomId,
- );
+ await mjolnir.client.sendMessage(mjolnir.managementRoomId, {
+ msgtype: "m.text",
+ body: `Banning ${event["sender"]} in ${roomId} for flooding (${messageCount} messages in the last minute)`,
+ format: "org.matrix.custom.html",
+ formatted_body: `Banning ${htmlEscape(event["sender"])} in ${roomId} for flooding (${messageCount} messages in the last minute).`,
+ });
if (!mjolnir.config.noop) {
if (mjolnir.moderators.checkMembership(event["sender"])) {
mjolnir.managementRoomOutput.logMessage(
diff --git a/src/protections/FirstMessageIsImage.ts b/src/protections/FirstMessageIsImage.ts
index 51574f96..fe3d129a 100644
--- a/src/protections/FirstMessageIsImage.ts
+++ b/src/protections/FirstMessageIsImage.ts
@@ -17,7 +17,7 @@ limitations under the License.
import { Protection } from "./IProtection";
import { Mjolnir } from "../Mjolnir";
import { LogLevel, LogService } from "@vector-im/matrix-bot-sdk";
-import { isTrueJoinEvent } from "../utils";
+import { htmlEscape, isTrueJoinEvent } from "../utils";
export class FirstMessageIsImage extends Protection {
private justJoined: { [roomId: string]: string[] } = {};
@@ -58,11 +58,12 @@ export class FirstMessageIsImage extends Protection {
const isMedia =
msgtype === "m.image" || msgtype === "m.video" || formattedBody.toLowerCase().includes("${htmlEscape(event["sender"])} for posting an image as the first thing after joining in ${roomId}.`,
+ });
if (!mjolnir.config.noop) {
if (mjolnir.moderators.checkMembership(event["sender"])) {
await mjolnir.managementRoomOutput.logMessage(
diff --git a/src/utils.ts b/src/utils.ts
index 05893a34..eca9a2a7 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -130,12 +130,12 @@ async function botRedactUserMessagesIn(
}
});
} catch (error) {
- await managementRoom.logMessage(
- LogLevel.ERROR,
- "utils#redactUserMessagesIn",
- `Caught an error while trying to redact messages for ${userIdOrGlob} in ${targetRoomId}: ${error}`,
- targetRoomId,
- );
+ await client.sendMessage(managementRoom.managementRoomId, {
+ msgtype: "m.text",
+ body: `Caught an error while trying to redact messages for ${userIdOrGlob} in ${targetRoomId}: ${error}`,
+ format: "org.matrix.custom.html",
+ formatted_body: `Caught an error while trying to redact messages for ${htmlEscape(userIdOrGlob)} in ${targetRoomId}: ${error}`,
+ });
}
}
}
@@ -215,12 +215,13 @@ export async function redactUserMessagesIn(
"utils#redactUserMessagesIn",
`Error using admin API to redact messages: ${extractRequestError(e)}`,
);
- await managementRoom.logMessage(
- LogLevel.ERROR,
- "utils#redactUserMessagesIn",
- `Error using admin API to redact messages for user ${userIdOrGlob}, please check logs for more info - falling
- back to non-admin redaction process.`,
- );
+ await client.sendMessage(managementRoom.managementRoomId, {
+ msgtype: "m.text",
+ body: `Error using admin API to redact messages for user ${userIdOrGlob}, please check logs for more info - falling back to non-admin redaction process.`,
+ format: "org.matrix.custom.html",
+ formatted_body: `Error using admin API to redact messages for user ${htmlEscape(userIdOrGlob)}, please check logs for more info - falling
+ back to non-admin redaction process.`,
+ });
await botRedactUserMessagesIn(client, managementRoom, userIdOrGlob, filteredRooms, limit, noop);
}
} else {