mirror of
https://github.com/matrix-org/mjolnir.git
synced 2024-10-01 01:36:06 -04:00
Setting up Decentralized Abuse Reports automatically by default
This commit is contained in:
parent
7b2f60985a
commit
e2725b1bb2
@ -243,8 +243,13 @@ export class Mjolnir {
|
||||
this.protectionManager = new ProtectionManager(this);
|
||||
|
||||
this.managementRoomOutput = new ManagementRoomOutput(managementRoomId, client, config);
|
||||
const protections = new ProtectionManager(this);
|
||||
this.protectedRoomsTracker = new ProtectedRoomsSet(client, clientUserId, managementRoomId, this.managementRoomOutput, protections, config);
|
||||
this.protectedRoomsTracker = new ProtectedRoomsSet(
|
||||
client,
|
||||
clientUserId,
|
||||
managementRoomId,
|
||||
this.managementRoomOutput,
|
||||
this.protectionManager,
|
||||
config);
|
||||
}
|
||||
|
||||
public get state(): string {
|
||||
|
@ -104,12 +104,6 @@ export class ProtectedRoomsSet {
|
||||
private readonly clientUserId: string,
|
||||
private readonly managementRoomId: string,
|
||||
private readonly managementRoomOutput: ManagementRoomOutput,
|
||||
/**
|
||||
* The protection manager is only used to verify the permissions
|
||||
* that the protection manager requires are correct for this set of rooms.
|
||||
* The protection manager is not really compatible with this abstraction yet
|
||||
* because of a direct dependency on the protection manager in Mjolnir commands.
|
||||
*/
|
||||
private readonly protectionManager: ProtectionManager,
|
||||
private readonly config: IConfig,
|
||||
) {
|
||||
@ -264,11 +258,13 @@ export class ProtectedRoomsSet {
|
||||
}
|
||||
this.protectedRooms.add(roomId);
|
||||
this.protectedRoomActivityTracker.addProtectedRoom(roomId);
|
||||
this.protectionManager.addProtectedRoom(roomId);
|
||||
}
|
||||
|
||||
public removeProtectedRoom(roomId: string): void {
|
||||
this.protectedRoomActivityTracker.removeProtectedRoom(roomId);
|
||||
this.protectedRooms.delete(roomId);
|
||||
this.protectionManager.removeProtectedRoom(roomId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -31,11 +31,26 @@ export abstract class Protection {
|
||||
readonly requiredStatePermissions: string[] = [];
|
||||
abstract settings: { [setting: string]: AbstractProtectionSetting<any, any> };
|
||||
|
||||
/**
|
||||
* A new room has been added to the list of rooms to protect with this protection.
|
||||
*/
|
||||
async startProtectingRoom(mjolnir: Mjolnir, roomId: string) {
|
||||
// By default, do nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* A room has been removed from the list of rooms to protect with this protection.
|
||||
*/
|
||||
async stopProtectingRoom(mjolnir: Mjolnir, roomId: string) {
|
||||
// By default, do nothing.
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a single event from a protected room, to decide if we need to
|
||||
* respond to it
|
||||
*/
|
||||
async handleEvent(mjolnir: Mjolnir, roomId: string, event: any): Promise<Consequence[] | any> {
|
||||
// By default, do nothing.
|
||||
}
|
||||
|
||||
/*
|
||||
@ -43,6 +58,7 @@ export abstract class Protection {
|
||||
* need to respond to it
|
||||
*/
|
||||
async handleReport(mjolnir: Mjolnir, roomId: string, reporterId: string, event: any, reason?: string): Promise<any> {
|
||||
// By default, do nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
|
98
src/protections/LocalAbuseReports.ts
Normal file
98
src/protections/LocalAbuseReports.ts
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
Copyright 2023 Element.
|
||||
|
||||
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 } from "matrix-bot-sdk";
|
||||
import { Mjolnir } from "../Mjolnir";
|
||||
import { Protection } from "./IProtection";
|
||||
|
||||
/*
|
||||
An implementation of per decentralized abuse reports, as per
|
||||
https://github.com/Yoric/matrix-doc/blob/aristotle/proposals/3215-towards-decentralized-moderation.md
|
||||
*/
|
||||
|
||||
const EVENT_MODERATED_BY = "org.matrix.msc3215.room.moderation.moderated_by";
|
||||
const EVENT_MODERATOR_OF = "org.matrix.msc3215.room.moderation.moderator_of";
|
||||
|
||||
/**
|
||||
* Setup decentralized abuse reports in protected rooms.
|
||||
*/
|
||||
export class LocalAbuseReports extends Protection {
|
||||
settings: { };
|
||||
public readonly name = "LocalAbuseReports";
|
||||
public readonly description = "Enables MSC3215-compliant web clients to send abuse reports to the moderator instead of the homeserver admin";
|
||||
readonly requiredStatePermissions = [EVENT_MODERATED_BY];
|
||||
|
||||
/**
|
||||
* A new room has been added to the list of rooms to protect with this protection.
|
||||
*/
|
||||
async startProtectingRoom(mjolnir: Mjolnir, protectedRoomId: string) {
|
||||
try {
|
||||
const userId = await mjolnir.client.getUserId();
|
||||
|
||||
// Fetch the previous state of the room, to avoid overwriting any existing setup.
|
||||
let previousState: /* previous content */ any | /* there was no previous content */ null;
|
||||
try {
|
||||
previousState = await mjolnir.client.getRoomStateEvent(protectedRoomId, EVENT_MODERATED_BY, EVENT_MODERATED_BY);
|
||||
} catch (ex) {
|
||||
previousState = null;
|
||||
}
|
||||
if (previousState && previousState["room_id"] && previousState["user_id"]) {
|
||||
if (previousState["room_id"] === mjolnir.managementRoomId && previousState["user_id"] === userId) {
|
||||
// The room is already setup, do nothing.
|
||||
return;
|
||||
} else {
|
||||
// There is a setup already, but it's not for us. Don't overwrite it.
|
||||
let protectedRoomAliasOrId = await mjolnir.client.getPublishedAlias(protectedRoomId) || protectedRoomId;
|
||||
mjolnir.managementRoomOutput.logMessage(LogLevel.INFO, "LocalAbuseReports", `Room ${protectedRoomAliasOrId} is already setup for decentralized abuse reports with bot ${previousState["user_id"]} and room ${previousState["room_id"]}, not overwriting automatically. To overwrite, use command \`!mjolnir rooms setup ${protectedRoomId} reporting\``);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup protected room -> moderation room link.
|
||||
// We do this before the other one to be able to fail early if we do not have a sufficient
|
||||
// powerlevel.
|
||||
let eventId;
|
||||
try {
|
||||
eventId = await mjolnir.client.sendStateEvent(protectedRoomId, EVENT_MODERATED_BY, EVENT_MODERATED_BY, {
|
||||
room_id: mjolnir.managementRoomId,
|
||||
user_id: userId,
|
||||
});
|
||||
} catch (ex) {
|
||||
mjolnir.managementRoomOutput.logMessage(LogLevel.ERROR, "LocalAbuseReports", `Could not autoset protected room -> moderation room link: ${ex.message}. To set it manually, use command \`!mjolnir rooms setup ${protectedRoomId} reporting\``);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Setup moderation room -> protected room.
|
||||
await mjolnir.client.sendStateEvent(mjolnir.managementRoomId, EVENT_MODERATOR_OF, protectedRoomId, {
|
||||
user_id: userId,
|
||||
});
|
||||
} catch (ex) {
|
||||
// If the second `sendStateEvent` fails, we could end up with a room half setup, which
|
||||
// is bad. Attempt to rollback.
|
||||
mjolnir.managementRoomOutput.logMessage(LogLevel.ERROR, "LocalAbuseReports", `Could not autoset moderation room -> protected room link: ${ex.message}. To set it manually, use command \`!mjolnir rooms setup ${protectedRoomId} reporting\``);
|
||||
try {
|
||||
await mjolnir.client.redactEvent(protectedRoomId, eventId, "Rolling back incomplete MSC3215 setup");
|
||||
} finally {
|
||||
// Ignore second exception, propagate first.
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
mjolnir.managementRoomOutput.logMessage(LogLevel.ERROR, "LocalAbuseReports", ex.message);
|
||||
}
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ import { Consequence } from "./consequence";
|
||||
import { htmlEscape } from "../utils";
|
||||
import { ERROR_KIND_FATAL, ERROR_KIND_PERMISSION } from "../ErrorCache";
|
||||
import { RoomUpdateError } from "../models/RoomUpdateError";
|
||||
import { LocalAbuseReports } from "./LocalAbuseReports";
|
||||
|
||||
const PROTECTIONS: Protection[] = [
|
||||
new FirstMessageIsImage(),
|
||||
@ -40,6 +41,7 @@ const PROTECTIONS: Protection[] = [
|
||||
new TrustedReporters(),
|
||||
new DetectFederationLag(),
|
||||
new JoinWaveShortCircuit(),
|
||||
new LocalAbuseReports(),
|
||||
];
|
||||
|
||||
const ENABLED_PROTECTIONS_EVENT_TYPE = "org.matrix.mjolnir.enabled_protections";
|
||||
@ -97,6 +99,11 @@ export class ProtectionManager {
|
||||
// this.getProtectionSettings() validates this data for us, so we don't need to
|
||||
protection.settings[key].setValue(value);
|
||||
}
|
||||
if (protection.enabled) {
|
||||
for (let roomId of this.mjolnir.protectedRoomsTracker.getProtectedRooms()) {
|
||||
await protection.startProtectingRoom(this.mjolnir, roomId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -104,11 +111,17 @@ export class ProtectionManager {
|
||||
*
|
||||
* @param protection The protection object we want to unregister
|
||||
*/
|
||||
public unregisterProtection(protectionName: string) {
|
||||
if (!(this._protections.has(protectionName))) {
|
||||
public async unregisterProtection(protectionName: string) {
|
||||
let protection = this._protections.get(protectionName);
|
||||
if (!protection) {
|
||||
throw new Error("Failed to find protection by name: " + protectionName);
|
||||
}
|
||||
this._protections.delete(protectionName);
|
||||
if (protection.enabled) {
|
||||
for (let roomId of this.mjolnir.protectedRoomsTracker.getProtectedRooms()) {
|
||||
await protection.stopProtectingRoom(this.mjolnir, roomId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -159,9 +172,13 @@ export class ProtectionManager {
|
||||
*/
|
||||
public async enableProtection(name: string) {
|
||||
const protection = this._protections.get(name);
|
||||
if (protection !== undefined) {
|
||||
if (protection === undefined) {
|
||||
return;
|
||||
}
|
||||
protection.enabled = true;
|
||||
await this.saveEnabledProtections();
|
||||
for (let roomId of this.mjolnir.protectedRoomsTracker.getProtectedRooms()) {
|
||||
await protection.startProtectingRoom(this.mjolnir, roomId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,9 +204,13 @@ export class ProtectionManager {
|
||||
*/
|
||||
public async disableProtection(name: string) {
|
||||
const protection = this._protections.get(name);
|
||||
if (protection !== undefined) {
|
||||
if (protection === undefined) {
|
||||
return;
|
||||
}
|
||||
protection.enabled = false;
|
||||
await this.saveEnabledProtections();
|
||||
for (let roomId of this.mjolnir.protectedRoomsTracker.getProtectedRooms()) {
|
||||
await protection.stopProtectingRoom(this.mjolnir, roomId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,4 +415,24 @@ export class ProtectionManager {
|
||||
await protection.handleReport(this.mjolnir, roomId, reporterId, event, reason);
|
||||
}
|
||||
}
|
||||
|
||||
public async addProtectedRoom(roomId: string) {
|
||||
for (const protection of this.enabledProtections) {
|
||||
try {
|
||||
await protection.startProtectingRoom(this.mjolnir, roomId);
|
||||
} catch (ex) {
|
||||
this.mjolnir.managementRoomOutput.logMessage(LogLevel.ERROR, protection.name, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async removeProtectedRoom(roomId: string) {
|
||||
for (const protection of this.enabledProtections) {
|
||||
try {
|
||||
await protection.stopProtectingRoom(this.mjolnir, roomId);
|
||||
} catch (ex) {
|
||||
this.mjolnir.managementRoomOutput.logMessage(LogLevel.ERROR, protection.name, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,89 @@ const EVENT_MODERATED_BY = "org.matrix.msc3215.room.moderation.moderated_by";
|
||||
const EVENT_MODERATOR_OF = "org.matrix.msc3215.room.moderation.moderator_of";
|
||||
const EVENT_MODERATION_REQUEST = "org.matrix.msc3215.abuse.report";
|
||||
|
||||
enum SetupMechanism {
|
||||
ManualCommand,
|
||||
Protection
|
||||
}
|
||||
|
||||
describe("Test: Requesting moderation", async () => {
|
||||
it(`Mjölnir can setup a room for moderation requests using !mjolnir command`, async function() {
|
||||
// Create a few users and a room, make sure that Mjölnir is moderator in the room.
|
||||
let goodUser = await newTestUser(this.config.homeserverUrl, { name: { contains: "reporting-abuse-good-user" }});
|
||||
let badUser = await newTestUser(this.config.homeserverUrl, { name: { contains: "reporting-abuse-bad-user" }});
|
||||
|
||||
let roomId = await goodUser.createRoom({ invite: [await badUser.getUserId(), await this.mjolnir.client.getUserId()] });
|
||||
await goodUser.inviteUser(await badUser.getUserId(), roomId);
|
||||
await badUser.joinRoom(roomId);
|
||||
await goodUser.setUserPowerLevel(await this.mjolnir.client.getUserId(), roomId, 100);
|
||||
|
||||
// Setup moderated_by/moderator_of.
|
||||
await this.mjolnir.client.sendText(this.mjolnir.managementRoomId, `!mjolnir rooms setup ${roomId} reporting`);
|
||||
|
||||
// Wait until moderated_by/moderator_of are setup
|
||||
while (true) {
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
try {
|
||||
await goodUser.getRoomStateEvent(roomId, EVENT_MODERATED_BY, EVENT_MODERATED_BY);
|
||||
} catch (ex) {
|
||||
console.log("moderated_by not setup yet, waiting");
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
await this.mjolnir.client.getRoomStateEvent(this.mjolnir.managementRoomId, EVENT_MODERATOR_OF, roomId);
|
||||
} catch (ex) {
|
||||
console.log("moderator_of not setup yet, waiting");
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
it(`Mjölnir can setup a room for moderation requests using room protections`, async function() {
|
||||
await this.mjolnir.protectionManager.enableProtection("LocalAbuseReports");
|
||||
|
||||
// Create a few users and a room, make sure that Mjölnir is moderator in the room.
|
||||
let goodUser = await newTestUser(this.config.homeserverUrl, { name: { contains: "reporting-abuse-good-user" }});
|
||||
let badUser = await newTestUser(this.config.homeserverUrl, { name: { contains: "reporting-abuse-bad-user" }});
|
||||
|
||||
let roomId = await goodUser.createRoom({ invite: [await badUser.getUserId(), await this.mjolnir.client.getUserId()] });
|
||||
await goodUser.inviteUser(await badUser.getUserId(), roomId);
|
||||
await badUser.joinRoom(roomId);
|
||||
await this.mjolnir.client.joinRoom(roomId);
|
||||
await goodUser.setUserPowerLevel(await this.mjolnir.client.getUserId(), roomId, 100);
|
||||
|
||||
// Wait until Mjölnir has joined the room.
|
||||
while (true) {
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
const joinedRooms = await this.mjolnir.client.getJoinedRooms();
|
||||
console.debug("Looking for room", roomId, "in", joinedRooms);
|
||||
if (joinedRooms.some(joinedRoomId => joinedRoomId == roomId)) {
|
||||
break;
|
||||
} else {
|
||||
console.log("Mjölnir hasn't joined the room yet, waiting");
|
||||
}
|
||||
}
|
||||
|
||||
// Setup moderated_by/moderator_of.
|
||||
this.mjolnir.addProtectedRoom(roomId);
|
||||
|
||||
// Wait until moderated_by/moderator_of are setup
|
||||
while (true) {
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
try {
|
||||
await goodUser.getRoomStateEvent(roomId, EVENT_MODERATED_BY, EVENT_MODERATED_BY);
|
||||
} catch (ex) {
|
||||
console.log("moderated_by not setup yet, waiting");
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
await this.mjolnir.client.getRoomStateEvent(this.mjolnir.managementRoomId, EVENT_MODERATOR_OF, roomId);
|
||||
} catch (ex) {
|
||||
console.log("moderator_of not setup yet, waiting");
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
it(`Mjölnir propagates moderation requests`, async function() {
|
||||
this.timeout(90000);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { strict as assert } from "assert";
|
||||
|
||||
import { Mjolnir } from "../../src/Mjolnir";
|
||||
import { IProtection } from "../../src/protections/IProtection";
|
||||
import { Protection } from "../../src/protections/IProtection";
|
||||
import { ProtectionSettingValidationError } from "../../src/protections/ProtectionSettings";
|
||||
import { NumberProtectionSetting, StringProtectionSetting, StringListProtectionSetting } from "../../src/protections/ProtectionSettings";
|
||||
import { newTestUser, noticeListener } from "./clientHelper";
|
||||
@ -26,7 +26,7 @@ describe("Test: Protection settings", function() {
|
||||
it("Mjolnir successfully saves valid protection setting values", async function() {
|
||||
this.timeout(20000);
|
||||
|
||||
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
||||
await this.mjolnir.protectionManager.registerProtection(new class extends Protection {
|
||||
name = "05OVMS";
|
||||
description = "A test protection";
|
||||
settings = { test: new NumberProtectionSetting(3) };
|
||||
@ -41,8 +41,9 @@ describe("Test: Protection settings", function() {
|
||||
it("Mjolnir should accumulate changed settings", async function() {
|
||||
this.timeout(20000);
|
||||
|
||||
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
||||
await this.mjolnir.protectionManager.registerProtection(new class extends Protection {
|
||||
name = "HPUjKN";
|
||||
description = "A test protection";
|
||||
settings = {
|
||||
test1: new NumberProtectionSetting(3),
|
||||
test2: new NumberProtectionSetting(4)
|
||||
@ -59,7 +60,7 @@ describe("Test: Protection settings", function() {
|
||||
this.timeout(20000);
|
||||
await client.joinRoom(this.config.managementRoom);
|
||||
|
||||
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
||||
await this.mjolnir.protectionManager.registerProtection(new class extends Protection {
|
||||
name = "JY2TPN";
|
||||
description = "A test protection";
|
||||
settings = { test: new StringProtectionSetting() };
|
||||
@ -84,7 +85,7 @@ describe("Test: Protection settings", function() {
|
||||
this.timeout(20000);
|
||||
await client.joinRoom(this.config.managementRoom);
|
||||
|
||||
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
||||
await this.mjolnir.protectionManager.registerProtection(new class extends Protection {
|
||||
name = "r33XyT";
|
||||
description = "A test protection";
|
||||
settings = { test: new StringListProtectionSetting() };
|
||||
@ -108,7 +109,7 @@ describe("Test: Protection settings", function() {
|
||||
this.timeout(20000);
|
||||
await client.joinRoom(this.config.managementRoom);
|
||||
|
||||
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
||||
await this.mjolnir.protectionManager.registerProtection(new class extends Protection {
|
||||
name = "oXzT0E";
|
||||
description = "A test protection";
|
||||
settings = { test: new StringListProtectionSetting() };
|
||||
@ -133,13 +134,13 @@ describe("Test: Protection settings", function() {
|
||||
this.timeout(20000);
|
||||
await client.joinRoom(this.config.managementRoom);
|
||||
|
||||
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
||||
await this.mjolnir.protectionManager.registerProtection(new class extends Protection {
|
||||
name = "d0sNrt";
|
||||
description = "A test protection";
|
||||
settings = { test: new StringProtectionSetting() };
|
||||
});
|
||||
|
||||
let replyPromise = new Promise((resolve, reject) => {
|
||||
let replyPromise: Promise<any> = new Promise((resolve, reject) => {
|
||||
let i = 0;
|
||||
client.on('room.message', noticeListener(this.mjolnir.managementRoomId, (event) => {
|
||||
if (event.content.body.includes("Changed d0sNrt.test ")) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Mjolnir } from "../../src/Mjolnir";
|
||||
import { IProtection } from "../../src/protections/IProtection";
|
||||
import { Protection } from "../../src/protections/IProtection";
|
||||
import { newTestUser } from "./clientHelper";
|
||||
|
||||
describe("Test: Report polling", function() {
|
||||
@ -15,18 +15,21 @@ describe("Test: Report polling", function() {
|
||||
await this.mjolnir.addProtectedRoom(protectedRoomId);
|
||||
|
||||
const eventId = await client.sendMessage(protectedRoomId, {msgtype: "m.text", body: "uwNd3q"});
|
||||
await new Promise(async resolve => {
|
||||
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
||||
class CustomProtection extends Protection {
|
||||
name = "jYvufI";
|
||||
description = "A test protection";
|
||||
settings = { };
|
||||
handleEvent = async (mjolnir: Mjolnir, roomId: string, event: any) => { };
|
||||
handleReport = (mjolnir: Mjolnir, roomId: string, reporterId: string, event: any, reason?: string) => {
|
||||
if (reason === "x5h1Je") {
|
||||
resolve(null);
|
||||
constructor(private resolve) {
|
||||
super();
|
||||
}
|
||||
};
|
||||
});
|
||||
async handleReport (mjolnir: Mjolnir, roomId: string, reporterId: string, event: any, reason?: string) {
|
||||
if (reason === "x5h1Je") {
|
||||
this.resolve(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
await new Promise(async resolve => {
|
||||
await this.mjolnir.protectionManager.registerProtection(new CustomProtection(resolve));
|
||||
await this.mjolnir.protectionManager.enableProtection("jYvufI");
|
||||
await client.doRequest(
|
||||
"POST",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { strict as assert } from "assert";
|
||||
|
||||
import { Mjolnir } from "../../src/Mjolnir";
|
||||
import { IProtection } from "../../src/protections/IProtection";
|
||||
import { Protection } from "../../src/protections/IProtection";
|
||||
import { newTestUser, noticeListener } from "./clientHelper";
|
||||
import { matrixClient, mjolnir } from "./mjolnirSetupUtils";
|
||||
import { ConsequenceBan, ConsequenceRedact } from "../../src/protections/consequence";
|
||||
@ -27,7 +27,7 @@ describe("Test: standard consequences", function() {
|
||||
await badUser.joinRoom(protectedRoomId);
|
||||
await this.mjolnir.addProtectedRoom(protectedRoomId);
|
||||
|
||||
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
||||
await this.mjolnir.protectionManager.registerProtection(new class extends Protection {
|
||||
name = "JY2TPN";
|
||||
description = "A test protection";
|
||||
settings = { };
|
||||
@ -39,7 +39,7 @@ describe("Test: standard consequences", function() {
|
||||
});
|
||||
await this.mjolnir.protectionManager.enableProtection("JY2TPN");
|
||||
|
||||
let reply = new Promise(async (resolve, reject) => {
|
||||
let reply: Promise<any> = new Promise(async (resolve, reject) => {
|
||||
const messageId = await badUser.sendMessage(protectedRoomId, {msgtype: "m.text", body: "ngmWkF"});
|
||||
let redaction;
|
||||
badUser.on('room.event', (roomId, event) => {
|
||||
@ -71,7 +71,7 @@ describe("Test: standard consequences", function() {
|
||||
await badUser.joinRoom(protectedRoomId);
|
||||
await this.mjolnir.addProtectedRoom(protectedRoomId);
|
||||
|
||||
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
||||
await this.mjolnir.protectionManager.registerProtection(new class extends Protection {
|
||||
name = "0LxMTy";
|
||||
description = "A test protection";
|
||||
settings = { };
|
||||
@ -83,7 +83,7 @@ describe("Test: standard consequences", function() {
|
||||
});
|
||||
await this.mjolnir.protectionManager.enableProtection("0LxMTy");
|
||||
|
||||
let reply = new Promise(async (resolve, reject) => {
|
||||
let reply: Promise<any> = new Promise(async (resolve, reject) => {
|
||||
const messageId = await badUser.sendMessage(protectedRoomId, {msgtype: "m.text", body: "7Uga3d"});
|
||||
let ban;
|
||||
badUser.on('room.leave', (roomId, event) => {
|
||||
@ -118,7 +118,7 @@ describe("Test: standard consequences", function() {
|
||||
await goodUser.joinRoom(protectedRoomId);
|
||||
await this.mjolnir.addProtectedRoom(protectedRoomId);
|
||||
|
||||
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
||||
await this.mjolnir.protectionManager.registerProtection(new class extends Protection {
|
||||
name = "95B1Cr";
|
||||
description = "A test protection";
|
||||
settings = { };
|
||||
|
Loading…
Reference in New Issue
Block a user