Update log handling for debugging

This commit is contained in:
Travis Ralston 2019-11-06 18:46:49 -07:00
parent 05aedcafb7
commit 84135c5ff5
10 changed files with 103 additions and 58 deletions

36
src/LogProxy.ts Normal file
View File

@ -0,0 +1,36 @@
/*
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 { LogLevel, LogService } from "matrix-bot-sdk";
import config from "./config";
const levelToFn = {
[LogLevel.DEBUG.toString()]: LogService.debug,
[LogLevel.INFO.toString()]: LogService.info,
[LogLevel.WARN.toString()]: LogService.warn,
[LogLevel.ERROR.toString()]: LogService.error,
};
export async function logMessage(level: LogLevel, module: string, message: string | any) {
if (config.RUNTIME.client && (config.verboseLogging || LogLevel.INFO.includes(level))) {
let clientMessage = message;
if (level === LogLevel.WARN) clientMessage = `⚠ | ${message}`;
if (level === LogLevel.ERROR) clientMessage = `‼ | ${message}`;
await config.RUNTIME.client.sendNotice(config.managementRoom, clientMessage);
}
levelToFn[level.toString()](module, message);
}

View File

@ -14,13 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { LogService, MatrixClient, Permalinks } from "matrix-bot-sdk"; import { LogLevel, LogService, MatrixClient, Permalinks } from "matrix-bot-sdk";
import BanList, { ALL_RULE_TYPES } from "./models/BanList"; import BanList, { ALL_RULE_TYPES } from "./models/BanList";
import { applyServerAcls } from "./actions/ApplyAcl"; import { applyServerAcls } from "./actions/ApplyAcl";
import { RoomUpdateError } from "./models/RoomUpdateError"; import { RoomUpdateError } from "./models/RoomUpdateError";
import { COMMAND_PREFIX, handleCommand } from "./commands/CommandHandler"; import { COMMAND_PREFIX, handleCommand } from "./commands/CommandHandler";
import { applyUserBans } from "./actions/ApplyBan"; import { applyUserBans } from "./actions/ApplyBan";
import config from "./config"; import config from "./config";
import { logMessage } from "./LogProxy";
export const STATE_NOT_STARTED = "not_started"; export const STATE_NOT_STARTED = "not_started";
export const STATE_CHECKING_PERMISSIONS = "checking_permissions"; export const STATE_CHECKING_PERMISSIONS = "checking_permissions";
@ -37,14 +38,13 @@ export class Mjolnir {
constructor( constructor(
public readonly client: MatrixClient, public readonly client: MatrixClient,
public readonly managementRoomId: string,
public readonly protectedRooms: { [roomId: string]: string }, public readonly protectedRooms: { [roomId: string]: string },
private banLists: BanList[], private banLists: BanList[],
) { ) {
client.on("room.event", this.handleEvent.bind(this)); client.on("room.event", this.handleEvent.bind(this));
client.on("room.message", async (roomId, event) => { client.on("room.message", async (roomId, event) => {
if (roomId !== managementRoomId) return; if (roomId !== config.managementRoom) return;
if (!event['content']) return; if (!event['content']) return;
const content = event['content']; const content = event['content'];
@ -55,6 +55,7 @@ export class Mjolnir {
// rewrite the event body to make the prefix uniform (in case the bot has spaces in its display name) // rewrite the event body to make the prefix uniform (in case the bot has spaces in its display name)
event['content']['body'] = COMMAND_PREFIX + content['body'].substring(prefixUsed.length); event['content']['body'] = COMMAND_PREFIX + content['body'].substring(prefixUsed.length);
LogService.info("Mjolnir", `Command being run by ${event['sender']}: ${event['content']['body']}`);
await client.sendReadReceipt(roomId, event['event_id']); await client.sendReadReceipt(roomId, event['event_id']);
return handleCommand(roomId, event, this); return handleCommand(roomId, event, this);
@ -83,25 +84,19 @@ export class Mjolnir {
return this.client.start().then(async () => { return this.client.start().then(async () => {
this.currentState = STATE_CHECKING_PERMISSIONS; this.currentState = STATE_CHECKING_PERMISSIONS;
if (config.verifyPermissionsOnStartup) { if (config.verifyPermissionsOnStartup) {
if (config.verboseLogging) { await logMessage(LogLevel.INFO, "Mjolnir@startup", "Checking permissions...");
await this.client.sendNotice(this.managementRoomId, "Checking permissions...");
}
await this.verifyPermissions(config.verboseLogging); await this.verifyPermissions(config.verboseLogging);
} }
}).then(async () => { }).then(async () => {
this.currentState = STATE_SYNCING; this.currentState = STATE_SYNCING;
if (config.syncOnStartup) { if (config.syncOnStartup) {
if (config.verboseLogging) { await logMessage(LogLevel.INFO, "Mjolnir@startup", "Syncing lists...");
await this.client.sendNotice(this.managementRoomId, "Syncing lists...");
}
await this.buildWatchedBanLists(); await this.buildWatchedBanLists();
await this.syncLists(config.verboseLogging); await this.syncLists(config.verboseLogging);
} }
}).then(async () => { }).then(async () => {
this.currentState = STATE_RUNNING; this.currentState = STATE_RUNNING;
if (config.verboseLogging) { await logMessage(LogLevel.INFO, "Mjolnir@startup", "Startup complete. Now monitoring rooms.");
await this.client.sendNotice(this.managementRoomId, "Startup complete.");
}
}); });
} }
@ -181,7 +176,7 @@ export class Mjolnir {
if (!hadErrors && verbose) { if (!hadErrors && verbose) {
const html = `<font color="#00cc00">All permissions look OK.</font>`; const html = `<font color="#00cc00">All permissions look OK.</font>`;
const text = "All permissions look OK."; const text = "All permissions look OK.";
await this.client.sendMessage(this.managementRoomId, { await this.client.sendMessage(config.managementRoom, {
msgtype: "m.notice", msgtype: "m.notice",
body: text, body: text,
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
@ -257,7 +252,7 @@ export class Mjolnir {
if (!hadErrors && verbose) { if (!hadErrors && verbose) {
const html = `<font color="#00cc00">Done updating rooms - no errors</font>`; const html = `<font color="#00cc00">Done updating rooms - no errors</font>`;
const text = "Done updating rooms - no errors"; const text = "Done updating rooms - no errors";
await this.client.sendMessage(this.managementRoomId, { await this.client.sendMessage(config.managementRoom, {
msgtype: "m.notice", msgtype: "m.notice",
body: text, body: text,
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
@ -285,7 +280,7 @@ export class Mjolnir {
if (!hadErrors) { if (!hadErrors) {
const html = `<font color="#00cc00"><b>Done updating rooms - no errors</b></font>`; const html = `<font color="#00cc00"><b>Done updating rooms - no errors</b></font>`;
const text = "Done updating rooms - no errors"; const text = "Done updating rooms - no errors";
await this.client.sendMessage(this.managementRoomId, { await this.client.sendMessage(config.managementRoom, {
msgtype: "m.notice", msgtype: "m.notice",
body: text, body: text,
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
@ -302,7 +297,7 @@ export class Mjolnir {
const url = this.protectedRooms[roomId]; const url = this.protectedRooms[roomId];
let html = `Power levels changed in <a href="${url}">${roomId}</a> - checking permissions...`; let html = `Power levels changed in <a href="${url}">${roomId}</a> - checking permissions...`;
let text = `Power levels changed in ${url} - checking permissions...`; let text = `Power levels changed in ${url} - checking permissions...`;
await this.client.sendMessage(this.managementRoomId, { await this.client.sendMessage(config.managementRoom, {
msgtype: "m.notice", msgtype: "m.notice",
body: text, body: text,
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
@ -313,7 +308,7 @@ export class Mjolnir {
if (!hadErrors) { if (!hadErrors) {
html = `<font color="#00cc00">All permissions look OK.</font>`; html = `<font color="#00cc00">All permissions look OK.</font>`;
text = "All permissions look OK."; text = "All permissions look OK.";
await this.client.sendMessage(this.managementRoomId, { await this.client.sendMessage(config.managementRoom, {
msgtype: "m.notice", msgtype: "m.notice",
body: text, body: text,
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
@ -358,7 +353,7 @@ export class Mjolnir {
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
formatted_body: html, formatted_body: html,
}; };
await this.client.sendMessage(this.managementRoomId, message); await this.client.sendMessage(config.managementRoom, message);
return true; return true;
} }
} }

View File

@ -19,6 +19,8 @@ import { ServerAcl } from "../models/ServerAcl";
import { RoomUpdateError } from "../models/RoomUpdateError"; import { RoomUpdateError } from "../models/RoomUpdateError";
import { Mjolnir } from "../Mjolnir"; import { Mjolnir } from "../Mjolnir";
import config from "../config"; import config from "../config";
import { LogLevel } from "matrix-bot-sdk";
import { logMessage } from "../LogProxy";
/** /**
* Applies the server ACLs represented by the ban lists to the provided rooms, returning the * Applies the server ACLs represented by the ban lists to the provided rooms, returning the
@ -40,35 +42,31 @@ export async function applyServerAcls(lists: BanList[], roomIds: string[], mjoln
if (config.verboseLogging) { if (config.verboseLogging) {
// We specifically use sendNotice to avoid having to escape HTML // We specifically use sendNotice to avoid having to escape HTML
await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Constructed server ACL:\n${JSON.stringify(finalAcl, null, 2)}`); await mjolnir.client.sendNotice(config.managementRoom, `Constructed server ACL:\n${JSON.stringify(finalAcl, null, 2)}`);
} }
const errors: RoomUpdateError[] = []; const errors: RoomUpdateError[] = [];
for (const roomId of roomIds) { for (const roomId of roomIds) {
try { try {
if (config.verboseLogging) { await logMessage(LogLevel.DEBUG, "ApplyAcl", `Checking ACLs for ${roomId}`);
await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Checking ACLs for ${roomId}`);
}
try { try {
const currentAcl = await mjolnir.client.getRoomStateEvent(roomId, "m.room.server_acl", ""); const currentAcl = await mjolnir.client.getRoomStateEvent(roomId, "m.room.server_acl", "");
if (acl.matches(currentAcl)) { if (acl.matches(currentAcl)) {
if (config.verboseLogging) { await logMessage(LogLevel.DEBUG, "ApplyAcl", `Skipping ACLs for ${roomId} because they are already the right ones`);
await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Skipping ACLs for ${roomId} because they are already the right ones`);
}
continue; continue;
} }
} catch (e) { } catch (e) {
// ignore - assume no ACL // ignore - assume no ACL
} }
if (config.verboseLogging) { // We specifically use sendNotice to avoid having to escape HTML
// We specifically use sendNotice to avoid having to escape HTML await logMessage(LogLevel.DEBUG, "ApplyAcl", `Applying ACL in ${roomId}`);
await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Applying ACL in ${roomId}`);
}
if (!config.noop) { if (!config.noop) {
await mjolnir.client.sendStateEvent(roomId, "m.room.server_acl", "", finalAcl); await mjolnir.client.sendStateEvent(roomId, "m.room.server_acl", "", finalAcl);
} else {
await logMessage(LogLevel.WARN, "ApplyAcl", `Tried to apply ACL in ${roomId} but Mjolnir is running in no-op mode`);
} }
} catch (e) { } catch (e) {
errors.push({roomId, errorMessage: e.message || (e.body ? e.body.error : '<no message>')}); errors.push({roomId, errorMessage: e.message || (e.body ? e.body.error : '<no message>')});

View File

@ -18,6 +18,8 @@ import BanList from "../models/BanList";
import { RoomUpdateError } from "../models/RoomUpdateError"; import { RoomUpdateError } from "../models/RoomUpdateError";
import { Mjolnir } from "../Mjolnir"; import { Mjolnir } from "../Mjolnir";
import config from "../config"; import config from "../config";
import { logMessage } from "../LogProxy";
import { LogLevel } from "matrix-bot-sdk";
/** /**
* Applies the member bans represented by the ban lists to the provided rooms, returning the * Applies the member bans represented by the ban lists to the provided rooms, returning the
@ -32,10 +34,8 @@ export async function applyUserBans(lists: BanList[], roomIds: string[], mjolnir
let bansApplied = 0; let bansApplied = 0;
for (const roomId of roomIds) { for (const roomId of roomIds) {
try { try {
if (config.verboseLogging) { // We specifically use sendNotice to avoid having to escape HTML
// We specifically use sendNotice to avoid having to escape HTML await logMessage(LogLevel.DEBUG, "ApplyBan", `Updating member bans in ${roomId}`);
await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Updating member bans in ${roomId}`);
}
const state = await mjolnir.client.getRoomState(roomId); const state = await mjolnir.client.getRoomState(roomId);
const members = state.filter(s => s['type'] === 'm.room.member' && !!s['state_key']); const members = state.filter(s => s['type'] === 'm.room.member' && !!s['state_key']);
@ -54,13 +54,13 @@ export async function applyUserBans(lists: BanList[], roomIds: string[], mjolnir
if (userRule.isMatch(member['state_key'])) { if (userRule.isMatch(member['state_key'])) {
// User needs to be banned // User needs to be banned
if (config.verboseLogging) { // We specifically use sendNotice to avoid having to escape HTML
// We specifically use sendNotice to avoid having to escape HTML await logMessage(LogLevel.DEBUG, "ApplyBan", `Banning ${member['state_key']} in ${roomId} for: ${userRule.reason}`);
await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Banning ${member['state_key']} in ${roomId} for: ${userRule.reason}`);
}
if (!config.noop) { if (!config.noop) {
await mjolnir.client.banUser(member['state_key'], roomId, userRule.reason); await mjolnir.client.banUser(member['state_key'], roomId, userRule.reason);
} else {
await logMessage(LogLevel.WARN, "ApplyBan", `Tried to ban ${member['state_key']} in ${roomId} but Mjolnir is running in no-op mode`);
} }
bansApplied++; bansApplied++;
@ -79,7 +79,7 @@ export async function applyUserBans(lists: BanList[], roomIds: string[], mjolnir
if (bansApplied > 0) { if (bansApplied > 0) {
const html = `<font color="#00cc00"><b>Banned ${bansApplied} people</b></font>`; const html = `<font color="#00cc00"><b>Banned ${bansApplied} people</b></font>`;
const text = `Banned ${bansApplied} people`; const text = `Banned ${bansApplied} people`;
await this.client.sendMessage(mjolnir.managementRoomId, { await this.client.sendMessage(config.managementRoom, {
msgtype: "m.notice", msgtype: "m.notice",
body: text, body: text,
format: "org.matrix.custom.html", format: "org.matrix.custom.html",

View File

@ -83,6 +83,6 @@ export async function handleCommand(roomId: string, event: any, mjolnir: Mjolnir
const text = "There was an error processing your command - see console/log for details"; const text = "There was an error processing your command - see console/log for details";
const reply = RichReply.createFor(roomId, event, text, text); const reply = RichReply.createFor(roomId, event, text, text);
reply["msgtype"] = "m.notice"; reply["msgtype"] = "m.notice";
return mjolnir.client.sendMessage(roomId, reply); return await mjolnir.client.sendMessage(roomId, reply);
} }
} }

View File

@ -18,6 +18,7 @@ import { Mjolnir } from "../Mjolnir";
import { RichReply } from "matrix-bot-sdk"; import { RichReply } from "matrix-bot-sdk";
import { RECOMMENDATION_BAN, recommendationToStable } from "../models/ListRule"; import { RECOMMENDATION_BAN, recommendationToStable } from "../models/ListRule";
import { RULE_SERVER, RULE_USER, ruleTypeToStable } from "../models/BanList"; import { RULE_SERVER, RULE_USER, ruleTypeToStable } from "../models/BanList";
import config from "../config";
// !mjolnir import <room ID> <shortcode> // !mjolnir import <room ID> <shortcode>
export async function execImportCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) { export async function execImportCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) {
@ -42,7 +43,7 @@ export async function execImportCommand(roomId: string, event: any, mjolnir: Mjo
if (content['membership'] === 'ban') { if (content['membership'] === 'ban') {
const reason = content['reason'] || '<no reason>'; const reason = content['reason'] || '<no reason>';
await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Adding user ${stateEvent['state_key']} to ban list`); await mjolnir.client.sendNotice(config.managementRoom, `Adding user ${stateEvent['state_key']} to ban list`);
const recommendation = recommendationToStable(RECOMMENDATION_BAN); const recommendation = recommendationToStable(RECOMMENDATION_BAN);
const ruleContent = { const ruleContent = {
@ -60,7 +61,7 @@ export async function execImportCommand(roomId: string, event: any, mjolnir: Mjo
for (const server of content['deny']) { for (const server of content['deny']) {
const reason = "<no reason>"; const reason = "<no reason>";
await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Adding server ${server} to ban list`); await mjolnir.client.sendNotice(config.managementRoom, `Adding server ${server} to ban list`);
const recommendation = recommendationToStable(RECOMMENDATION_BAN); const recommendation = recommendationToStable(RECOMMENDATION_BAN);
const ruleContent = { const ruleContent = {

View File

@ -17,6 +17,8 @@ limitations under the License.
import { Mjolnir } from "../Mjolnir"; import { Mjolnir } from "../Mjolnir";
import { getMessagesByUserSinceLastJoin } from "../utils"; import { getMessagesByUserSinceLastJoin } from "../utils";
import config from "../config"; import config from "../config";
import { logMessage } from "../LogProxy";
import { LogLevel } from "matrix-bot-sdk";
// !mjolnir redact <user ID> [room alias] // !mjolnir redact <user ID> [room alias]
export async function execRedactCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) { export async function execRedactCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) {
@ -28,17 +30,15 @@ export async function execRedactCommand(roomId: string, event: any, mjolnir: Mjo
const targetRoomIds = roomAlias ? [roomAlias] : Object.keys(mjolnir.protectedRooms); const targetRoomIds = roomAlias ? [roomAlias] : Object.keys(mjolnir.protectedRooms);
for (const targetRoomId of targetRoomIds) { for (const targetRoomId of targetRoomIds) {
if (config.verboseLogging) { await logMessage(LogLevel.DEBUG, "RedactCommand", `Fetching sent messages for ${userId} in ${targetRoomId} to redact...`);
await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Fetching sent messages for ${userId} in ${targetRoomId} to redact...`);
}
const eventsToRedact = await getMessagesByUserSinceLastJoin(mjolnir.client, userId, targetRoomId); const eventsToRedact = await getMessagesByUserSinceLastJoin(mjolnir.client, userId, targetRoomId);
for (const victimEvent of eventsToRedact) { for (const victimEvent of eventsToRedact) {
if (config.verboseLogging) { await logMessage(LogLevel.DEBUG, "RedactCommand", `Redacting ${victimEvent['event_id']} in ${targetRoomId}`);
await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Redacting ${victimEvent['event_id']} in ${targetRoomId}`);
}
if (!config.noop) { if (!config.noop) {
await mjolnir.client.redactEvent(targetRoomId, victimEvent['event_id']); await mjolnir.client.redactEvent(targetRoomId, victimEvent['event_id']);
} else {
await logMessage(LogLevel.WARN, "RedactCommand", `Tried to redact ${victimEvent['event_id']} in ${targetRoomId} but Mjolnir is running in no-op mode`);
} }
} }
} }

View File

@ -16,10 +16,11 @@ limitations under the License.
import { Mjolnir } from "../Mjolnir"; import { Mjolnir } from "../Mjolnir";
import { RULE_ROOM, RULE_SERVER, RULE_USER, ruleTypeToStable, USER_RULE_TYPES } from "../models/BanList"; import { RULE_ROOM, RULE_SERVER, RULE_USER, ruleTypeToStable, USER_RULE_TYPES } from "../models/BanList";
import { RichReply } from "matrix-bot-sdk"; import { LogLevel, RichReply } from "matrix-bot-sdk";
import { RECOMMENDATION_BAN, recommendationToStable } from "../models/ListRule"; import { RECOMMENDATION_BAN, recommendationToStable } from "../models/ListRule";
import { MatrixGlob } from "matrix-bot-sdk/lib/MatrixGlob"; import { MatrixGlob } from "matrix-bot-sdk/lib/MatrixGlob";
import config from "../config"; import config from "../config";
import { logMessage } from "../LogProxy";
function parseBits(parts: string[]): { listShortcode: string, entityType: string, ruleType: string, glob: string, reason: string } { function parseBits(parts: string[]): { listShortcode: string, entityType: string, ruleType: string, glob: string, reason: string } {
const shortcode = parts[2].toLowerCase(); const shortcode = parts[2].toLowerCase();
@ -98,7 +99,7 @@ export async function execUnbanCommand(roomId: string, event: any, mjolnir: Mjol
if (USER_RULE_TYPES.includes(bits.ruleType) && parts.length > 5 && parts[5] === 'true') { if (USER_RULE_TYPES.includes(bits.ruleType) && parts.length > 5 && parts[5] === 'true') {
const rule = new MatrixGlob(bits.glob); const rule = new MatrixGlob(bits.glob);
await mjolnir.client.sendNotice(mjolnir.managementRoomId, "Unbanning users that match glob: " + bits.glob); await logMessage(LogLevel.INFO, "UnbanBanCommand", "Unbanning users that match glob: " + bits.glob);
let unbannedSomeone = false; let unbannedSomeone = false;
for (const protectedRoomId of Object.keys(mjolnir.protectedRooms)) { for (const protectedRoomId of Object.keys(mjolnir.protectedRooms)) {
const members = await mjolnir.client.getMembers(protectedRoomId, null, ['ban'], null); const members = await mjolnir.client.getMembers(protectedRoomId, null, ['ban'], null);
@ -106,21 +107,21 @@ export async function execUnbanCommand(roomId: string, event: any, mjolnir: Mjol
const victim = member['state_key']; const victim = member['state_key'];
if (!member['content'] || member['content']['membership'] !== 'ban') continue; if (!member['content'] || member['content']['membership'] !== 'ban') continue;
if (rule.test(victim)) { if (rule.test(victim)) {
if (config.verboseLogging) { await logMessage(LogLevel.DEBUG, "UnbanBanCommand", `Unbanning ${victim} in ${protectedRoomId}`);
await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Unbanning ${victim} in ${protectedRoomId}`);
}
if (!config.noop) { if (!config.noop) {
await mjolnir.client.unbanUser(victim, protectedRoomId); await mjolnir.client.unbanUser(victim, protectedRoomId);
} else {
await logMessage(LogLevel.WARN, "UnbanBanCommand", `Attempted to unban ${victim} in ${protectedRoomId} but Mjolnir is running in no-op mode`);
} }
unbannedSomeone = true; unbannedSomeone = true;
} }
} }
} }
if (unbannedSomeone) { if (unbannedSomeone) {
if (config.verboseLogging) { await logMessage(LogLevel.DEBUG, "UnbanBanCommand", `Syncing lists to ensure no users were accidentally unbanned`);
await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Syncing lists to ensure no users were accidentally unbanned`);
}
await mjolnir.syncLists(config.verboseLogging); await mjolnir.syncLists(config.verboseLogging);
} }
} }

View File

@ -15,6 +15,7 @@ limitations under the License.
*/ */
import * as config from "config"; import * as config from "config";
import { MatrixClient } from "matrix-bot-sdk";
interface IConfig { interface IConfig {
homeserverUrl: string; homeserverUrl: string;
@ -33,6 +34,14 @@ interface IConfig {
verifyPermissionsOnStartup: boolean; verifyPermissionsOnStartup: boolean;
noop: boolean; noop: boolean;
protectedRooms: string[]; // matrix.to urls protectedRooms: string[]; // matrix.to urls
/**
* Config options only set at runtime. Try to avoid using the objects
* here as much as possible.
*/
RUNTIME: {
client: MatrixClient;
};
} }
export default <IConfig>config; export default <IConfig>config;

View File

@ -28,6 +28,9 @@ import {
import config from "./config"; import config from "./config";
import BanList from "./models/BanList"; import BanList from "./models/BanList";
import { Mjolnir } from "./Mjolnir"; import { Mjolnir } from "./Mjolnir";
import { logMessage } from "./LogProxy";
config.RUNTIME = {client: null};
LogService.setLogger(new RichConsoleLogger()); LogService.setLogger(new RichConsoleLogger());
LogService.setLevel(LogLevel.fromString(config.logLevel, LogLevel.DEBUG)); LogService.setLevel(LogLevel.fromString(config.logLevel, LogLevel.DEBUG));
@ -45,6 +48,8 @@ LogService.info("index", "Starting bot...");
client = new MatrixClient(config.homeserverUrl, config.accessToken, storage); client = new MatrixClient(config.homeserverUrl, config.accessToken, storage);
} }
config.RUNTIME.client = client;
if (config.autojoin) { if (config.autojoin) {
AutojoinRoomsMixin.setupOnClient(client); AutojoinRoomsMixin.setupOnClient(client);
} }
@ -68,9 +73,9 @@ LogService.info("index", "Starting bot...");
} }
// Ensure we're also in the management room // Ensure we're also in the management room
const managementRoomId = await client.joinRoom(config.managementRoom); config.managementRoom = await client.joinRoom(config.managementRoom);
await client.sendNotice(managementRoomId, "Mjolnir is starting up. Use !mjolnir to query status."); await logMessage(LogLevel.INFO, "index", "Mjolnir is starting up. Use !mjolnir to query status.");
const bot = new Mjolnir(client, managementRoomId, protectedRooms, banLists); const bot = new Mjolnir(client, protectedRooms, banLists);
await bot.start(); await bot.start();
})(); })();